Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
99befc3927
commit
c241fef181
44 changed files with 344 additions and 228 deletions
|
@ -36,9 +36,13 @@ workflow:
|
|||
# they serve no purpose and will run anyway when the changes are merged.
|
||||
- if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^release-tools\/\d+\.\d+\.\d+-rc\d+$/ && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ /^[\d-]+-stable(-ee)?$/ && $CI_PROJECT_PATH == "gitlab-org/gitlab"'
|
||||
when: never
|
||||
# For merge requests, create a pipeline.
|
||||
# For merged result pipelines, set $QA_IMAGE, since $CI_MERGE_REQUEST_SOURCE_BRANCH_SHA is only available for merged result pipelines.
|
||||
- if: '$CI_MERGE_REQUEST_EVENT_TYPE == "merged_result" || $CI_MERGE_REQUEST_EVENT_TYPE == "merge_train"'
|
||||
variables:
|
||||
QA_IMAGE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_MERGE_REQUEST_SOURCE_BRANCH_SHA}"
|
||||
# Also run (detached) merge request pipelines.
|
||||
- if: '$CI_MERGE_REQUEST_IID'
|
||||
# For the 2-hourly scheduled pipelines, we set specific variables
|
||||
# For the 2-hourly scheduled pipelines, we set specific variables.
|
||||
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE == "schedule" && $FREQUENCY == "2-hourly"'
|
||||
variables:
|
||||
CRYSTALBALL: "true"
|
||||
|
@ -88,6 +92,9 @@ variables:
|
|||
RSPEC_FAIL_FAST_ENABLED: "true" # Set it to "false" to disable RSpec fail-fast
|
||||
SIMPLECOV: "true"
|
||||
|
||||
# For the default QA image, we use $CI_COMMIT_SHA as tag since it's always available and we override it for specific workflow.rules (see above)
|
||||
QA_IMAGE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_COMMIT_SHA}"
|
||||
|
||||
# Preparing custom clone path to reduce space used by all random forks
|
||||
# on GitLab.com's Shared Runners. Our main forks - especially the security
|
||||
# ones - will have this variable overwritten in the project settings, so that
|
||||
|
|
|
@ -370,19 +370,11 @@
|
|||
when: never
|
||||
- <<: *if-dot-com-gitlab-org-and-security-merge-request
|
||||
changes: *ci-build-images-patterns
|
||||
variables:
|
||||
QA_IMAGE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_MERGE_REQUEST_SOURCE_BRANCH_SHA}"
|
||||
- <<: *if-dot-com-gitlab-org-and-security-merge-request
|
||||
changes: *code-qa-patterns
|
||||
variables:
|
||||
QA_IMAGE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_MERGE_REQUEST_SOURCE_BRANCH_SHA}"
|
||||
- <<: *if-dot-com-gitlab-org-default-branch
|
||||
changes: *code-qa-patterns
|
||||
variables:
|
||||
QA_IMAGE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_COMMIT_SHA}"
|
||||
- <<: *if-dot-com-gitlab-org-schedule
|
||||
variables:
|
||||
QA_IMAGE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_COMMIT_SHA}"
|
||||
|
||||
.build-images:rules:build-assets-image:
|
||||
rules:
|
||||
|
@ -594,24 +586,16 @@
|
|||
when: never
|
||||
- <<: *if-dot-com-gitlab-org-and-security-merge-request
|
||||
changes: *ci-qa-patterns
|
||||
variables:
|
||||
QA_IMAGE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_MERGE_REQUEST_SOURCE_BRANCH_SHA}"
|
||||
allow_failure: true
|
||||
- <<: *if-dot-com-gitlab-org-and-security-merge-request
|
||||
changes: *qa-patterns
|
||||
variables:
|
||||
QA_IMAGE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_MERGE_REQUEST_SOURCE_BRANCH_SHA}"
|
||||
allow_failure: true
|
||||
- <<: *if-dot-com-gitlab-org-and-security-merge-request
|
||||
changes: *code-patterns
|
||||
when: manual
|
||||
variables:
|
||||
QA_IMAGE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_MERGE_REQUEST_SOURCE_BRANCH_SHA}"
|
||||
allow_failure: true
|
||||
- <<: *if-dot-com-gitlab-org-schedule
|
||||
allow_failure: true
|
||||
variables:
|
||||
QA_IMAGE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_COMMIT_SHA}"
|
||||
|
||||
###############
|
||||
# Rails rules #
|
||||
|
@ -1298,17 +1282,11 @@
|
|||
when: never
|
||||
- <<: *if-dot-com-gitlab-org-merge-request
|
||||
changes: *ci-review-patterns
|
||||
variables:
|
||||
QA_IMAGE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_MERGE_REQUEST_SOURCE_BRANCH_SHA}"
|
||||
- <<: *if-dot-com-gitlab-org-merge-request
|
||||
changes: *frontend-patterns
|
||||
variables:
|
||||
QA_IMAGE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_MERGE_REQUEST_SOURCE_BRANCH_SHA}"
|
||||
allow_failure: true
|
||||
- <<: *if-dot-com-gitlab-org-merge-request
|
||||
changes: *code-qa-patterns
|
||||
variables:
|
||||
QA_IMAGE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_MERGE_REQUEST_SOURCE_BRANCH_SHA}"
|
||||
allow_failure: true
|
||||
|
||||
# The rule needs to be duplicated between `on_success` and `on_failure`
|
||||
|
@ -1344,13 +1322,9 @@
|
|||
- <<: *if-dot-com-gitlab-org-merge-request
|
||||
changes: *code-patterns
|
||||
when: manual
|
||||
variables:
|
||||
QA_IMAGE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_MERGE_REQUEST_SOURCE_BRANCH_SHA}"
|
||||
allow_failure: true
|
||||
- <<: *if-dot-com-gitlab-org-merge-request
|
||||
changes: *qa-patterns
|
||||
variables:
|
||||
QA_IMAGE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_MERGE_REQUEST_SOURCE_BRANCH_SHA}"
|
||||
allow_failure: true
|
||||
|
||||
# The rule needs to be duplicated between `on_success` and `on_failure`
|
||||
|
|
|
@ -46,7 +46,7 @@ export default {
|
|||
return timeIntervalInWords(this.job.queued);
|
||||
},
|
||||
runnerHelpUrl() {
|
||||
return helpPagePath('ci/runners/index.html', {
|
||||
return helpPagePath('ci/runners/configure_runners.html', {
|
||||
anchor: 'set-maximum-job-timeout-for-a-runner',
|
||||
});
|
||||
},
|
||||
|
|
|
@ -304,7 +304,7 @@ class Admin::UsersController < Admin::ApplicationController
|
|||
end
|
||||
|
||||
def user
|
||||
@user ||= find_routable!(User, params[:id])
|
||||
@user ||= find_routable!(User, params[:id], request.path_info)
|
||||
end
|
||||
|
||||
def build_canonical_path(user)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
module ProjectUnauthorized
|
||||
module ControllerActions
|
||||
def self.on_routable_not_found
|
||||
lambda do |routable|
|
||||
lambda do |routable, path_info|
|
||||
return unless routable.is_a?(Project)
|
||||
|
||||
label = routable.external_authorization_classification_label
|
||||
|
|
|
@ -3,13 +3,13 @@
|
|||
module RoutableActions
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def find_routable!(routable_klass, requested_full_path, extra_authorization_proc: nil)
|
||||
routable = routable_klass.find_by_full_path(requested_full_path, follow_redirects: request.get?)
|
||||
def find_routable!(routable_klass, routable_full_path, path_info, extra_authorization_proc: nil)
|
||||
routable = routable_klass.find_by_full_path(routable_full_path, follow_redirects: request.get?)
|
||||
if routable_authorized?(routable, extra_authorization_proc)
|
||||
ensure_canonical_path(routable, requested_full_path)
|
||||
ensure_canonical_path(routable, routable_full_path)
|
||||
routable
|
||||
else
|
||||
perform_not_found_actions(routable, not_found_actions)
|
||||
perform_not_found_actions(routable, not_found_actions, path_info)
|
||||
|
||||
route_not_found unless performed?
|
||||
|
||||
|
@ -21,11 +21,11 @@ module RoutableActions
|
|||
[ProjectUnauthorized::ControllerActions.on_routable_not_found]
|
||||
end
|
||||
|
||||
def perform_not_found_actions(routable, actions)
|
||||
def perform_not_found_actions(routable, actions, path_info)
|
||||
actions.each do |action|
|
||||
break if performed?
|
||||
|
||||
instance_exec(routable, &action)
|
||||
instance_exec(routable, path_info, &action)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -42,13 +42,13 @@ module RoutableActions
|
|||
end
|
||||
end
|
||||
|
||||
def ensure_canonical_path(routable, requested_full_path)
|
||||
def ensure_canonical_path(routable, routable_full_path)
|
||||
return unless request.get?
|
||||
|
||||
canonical_path = routable.full_path
|
||||
if canonical_path != requested_full_path
|
||||
if !request.xhr? && request.format.html? && canonical_path.casecmp(requested_full_path) != 0
|
||||
flash[:notice] = "#{routable.class.to_s.titleize} '#{requested_full_path}' was moved to '#{canonical_path}'. Please update any links and bookmarks that may still have the old path."
|
||||
if canonical_path != routable_full_path
|
||||
if !request.xhr? && request.format.html? && canonical_path.casecmp(routable_full_path) != 0
|
||||
flash[:notice] = "#{routable.class.to_s.titleize} '#{routable_full_path}' was moved to '#{canonical_path}'. Please update any links and bookmarks that may still have the old path."
|
||||
end
|
||||
|
||||
redirect_to build_canonical_path(routable), status: :moved_permanently
|
||||
|
|
|
@ -24,7 +24,7 @@ class Groups::ApplicationController < ApplicationController
|
|||
end
|
||||
|
||||
def group
|
||||
@group ||= find_routable!(Group, params[:group_id] || params[:id])
|
||||
@group ||= find_routable!(Group, params[:group_id] || params[:id], request.path_info)
|
||||
end
|
||||
|
||||
def group_projects
|
||||
|
|
|
@ -13,6 +13,6 @@ class Groups::Clusters::ApplicationsController < Clusters::ApplicationsControlle
|
|||
end
|
||||
|
||||
def group
|
||||
@group ||= find_routable!(Group, params[:group_id] || params[:id])
|
||||
@group ||= find_routable!(Group, params[:group_id] || params[:id], request.path_info)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -13,6 +13,6 @@ class Groups::Clusters::IntegrationsController < Clusters::IntegrationsControlle
|
|||
end
|
||||
|
||||
def group
|
||||
@group ||= find_routable!(Group, params[:group_id] || params[:id])
|
||||
@group ||= find_routable!(Group, params[:group_id] || params[:id], request.path_info)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,7 +15,7 @@ class Groups::ClustersController < Clusters::ClustersController
|
|||
end
|
||||
|
||||
def group
|
||||
@group ||= find_routable!(Group, params[:group_id] || params[:id])
|
||||
@group ||= find_routable!(Group, params[:group_id] || params[:id], request.path_info)
|
||||
end
|
||||
|
||||
def metrics_dashboard_params
|
||||
|
|
|
@ -6,7 +6,7 @@ class Profiles::GroupsController < Profiles::ApplicationController
|
|||
feature_category :users
|
||||
|
||||
def update
|
||||
group = find_routable!(Group, params[:id])
|
||||
group = find_routable!(Group, params[:id], request.path_info)
|
||||
notification_setting = current_user.notification_settings_for(group)
|
||||
|
||||
if notification_setting.update(update_params)
|
||||
|
|
|
@ -26,7 +26,7 @@ class Projects::ApplicationController < ApplicationController
|
|||
path = File.join(params[:namespace_id], params[:project_id] || params[:id])
|
||||
auth_proc = ->(project) { !project.pending_delete? }
|
||||
|
||||
@project = find_routable!(Project, path, extra_authorization_proc: auth_proc)
|
||||
@project = find_routable!(Project, path, request.path_info, extra_authorization_proc: auth_proc)
|
||||
end
|
||||
|
||||
def build_canonical_path(project)
|
||||
|
|
|
@ -10,6 +10,6 @@ class Projects::Clusters::ApplicationsController < Clusters::ApplicationsControl
|
|||
end
|
||||
|
||||
def project
|
||||
@project ||= find_routable!(Project, File.join(params[:namespace_id], params[:project_id]))
|
||||
@project ||= find_routable!(Project, File.join(params[:namespace_id], params[:project_id]), request.path_info)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,6 +10,6 @@ class Projects::Clusters::IntegrationsController < ::Clusters::IntegrationsContr
|
|||
end
|
||||
|
||||
def project
|
||||
@project ||= find_routable!(Project, File.join(params[:namespace_id], params[:project_id]))
|
||||
@project ||= find_routable!(Project, File.join(params[:namespace_id], params[:project_id]), request.path_info)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -17,7 +17,7 @@ class Projects::ClustersController < Clusters::ClustersController
|
|||
end
|
||||
|
||||
def project
|
||||
@project ||= find_routable!(Project, File.join(params[:namespace_id], params[:project_id]))
|
||||
@project ||= find_routable!(Project, File.join(params[:namespace_id], params[:project_id]), request.path_info)
|
||||
end
|
||||
|
||||
def repository
|
||||
|
|
|
@ -172,7 +172,7 @@ class UsersController < ApplicationController
|
|||
private
|
||||
|
||||
def user
|
||||
@user ||= find_routable!(User, params[:username])
|
||||
@user ||= find_routable!(User, params[:username], request.path_info)
|
||||
end
|
||||
|
||||
def personal_projects
|
||||
|
|
|
@ -119,14 +119,6 @@ module BoardsHelper
|
|||
}
|
||||
end
|
||||
|
||||
def boards_link_text
|
||||
if current_board_parent.multiple_issue_boards_available?
|
||||
s_("IssueBoards|Boards")
|
||||
else
|
||||
s_("IssueBoards|Board")
|
||||
end
|
||||
end
|
||||
|
||||
def recent_boards_path
|
||||
recent_project_boards_path(@project) if current_board_parent.is_a?(Project)
|
||||
end
|
||||
|
|
|
@ -67,15 +67,6 @@ module NavHelper
|
|||
%w(dev_ops_report usage_trends)
|
||||
end
|
||||
|
||||
def group_issues_sub_menu_items
|
||||
%w[
|
||||
groups#issues
|
||||
milestones#index
|
||||
boards#index
|
||||
boards#show
|
||||
]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_header_links
|
||||
|
|
|
@ -2,26 +2,23 @@
|
|||
= form_errors(@application_setting)
|
||||
|
||||
%fieldset
|
||||
%p
|
||||
- link_to_restart = link_to(_('restart'), help_page_path('administration/restart_gitlab'))
|
||||
= _('Enable a Prometheus metrics endpoint at %{metrics_path} to expose a variety of statistics on the health and performance of GitLab. Additional information on authenticating and connecting to the metrics endpoint is available %{link}.').html_safe % { metrics_path: "<code>#{metrics_path}</code>".html_safe, link: link_to(_('here'), admin_health_check_path) }
|
||||
= _('This setting requires a %{link_to_restart} to take effect.').html_safe % { link_to_restart: link_to_restart }
|
||||
= link_to sprite_icon('question-o'), help_page_path('administration/monitoring/prometheus/index')
|
||||
.form-group
|
||||
.form-check
|
||||
= f.check_box :prometheus_metrics_enabled, class: 'form-check-input'
|
||||
= f.label :prometheus_metrics_enabled, class: 'form-check-label' do
|
||||
= _("Enable Prometheus Metrics")
|
||||
= _("Enable health and performance metrics endpoint")
|
||||
.form-text.text-muted
|
||||
= _('Enable a Prometheus endpoint that exposes health and performance statistics. The Health Check menu item appears in the Monitoring section of the Admin Area. Restart required.')
|
||||
= link_to _('Learn More.'), help_page_path('administration/monitoring/prometheus/gitlab_metrics.md'), target: '_blank'
|
||||
- unless Gitlab::Metrics.metrics_folder_present?
|
||||
.form-text.text-muted
|
||||
%strong.cred= _("WARNING:")
|
||||
= _("Environment variable %{code_start}%{environment_variable}%{code_end} does not exist or is not pointing to a valid directory.").html_safe % { environment_variable: prometheus_multiproc_dir, code_start: '<code>'.html_safe, code_end: '</code>'.html_safe }
|
||||
= link_to sprite_icon('question-o'), help_page_path('administration/monitoring/prometheus/gitlab_metrics', anchor: 'metrics-shared-directory')
|
||||
.form-group
|
||||
= f.label :metrics_method_call_threshold, _('Method Call Threshold (ms)'), class: 'label-bold'
|
||||
= f.label :metrics_method_call_threshold, _('Method call threshold (ms)'), class: 'label-bold'
|
||||
= f.number_field :metrics_method_call_threshold, class: 'form-control gl-form-input'
|
||||
.form-text.text-muted
|
||||
A method call is only tracked when it takes longer to complete than
|
||||
the given amount of milliseconds.
|
||||
Only track method calls that take longer to complete than the given duration.
|
||||
|
||||
= f.submit _('Save changes'), class: "gl-button btn btn-confirm"
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
|
||||
= expanded_by_default? ? _('Collapse') : _('Expand')
|
||||
%p
|
||||
= _('Enable and configure Prometheus metrics.')
|
||||
= _('Monitor the health and performance of GitLab with Prometheus.')
|
||||
.settings-content
|
||||
= render 'prometheus'
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
= form_for [:admin, @group] do |f|
|
||||
= gitlab_ui_form_for [:admin, @group] do |f|
|
||||
= form_errors(@group)
|
||||
= render 'shared/group_form', f: f
|
||||
= render 'shared/group_form_description', f: f
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
- return unless render_setting_to_allow_project_access_token_creation?(group)
|
||||
|
||||
.form-group.gl-mb-3
|
||||
.gl-form-checkbox.custom-control.custom-checkbox
|
||||
= f.check_box :resource_access_token_creation_allowed, checked: group.namespace_settings.resource_access_token_creation_allowed?, class: 'custom-control-input', data: { qa_selector: 'resource_access_token_creation_allowed_checkbox' }
|
||||
= f.label :resource_access_token_creation_allowed, class: 'custom-control-label' do
|
||||
%span= s_('GroupSettings|Allow project access token creation')
|
||||
- project_access_tokens_link = help_page_path('user/project/settings/project_access_tokens')
|
||||
- link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: project_access_tokens_link }
|
||||
%p.help-text= s_('GroupSettings|Users can create %{link_start}project access tokens%{link_end} for projects in this group.').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
|
||||
- project_access_tokens_link = help_page_path('user/project/settings/project_access_tokens')
|
||||
- link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: project_access_tokens_link }
|
||||
= f.gitlab_ui_checkbox_component :resource_access_token_creation_allowed,
|
||||
s_('GroupSettings|Allow project access token creation'),
|
||||
checkbox_options: { checked: group.namespace_settings.resource_access_token_creation_allowed?, data: { qa_selector: 'resource_access_token_creation_allowed_checkbox' } },
|
||||
help_text: s_('GroupSettings|Users can create %{link_start}project access tokens%{link_end} for projects in this group.').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
|
||||
|
|
|
@ -1,42 +1,5 @@
|
|||
- issues_count = cached_issuables_count(@group, type: :issues)
|
||||
- merge_requests_count = cached_issuables_count(@group, type: :merge_requests)
|
||||
|
||||
- if group_sidebar_link?(:issues)
|
||||
= nav_link(path: group_issues_sub_menu_items, unless: -> { current_path?('issues_analytics#show') }) do
|
||||
= link_to issues_group_path(@group), data: { qa_selector: 'group_issues_item' }, class: 'has-sub-items' do
|
||||
.nav-icon-container
|
||||
= sprite_icon('issues')
|
||||
%span.nav-item-name
|
||||
= _('Issues')
|
||||
%span.badge.badge-pill.count= issues_count
|
||||
|
||||
%ul.sidebar-sub-level-items{ data: { qa_selector: 'group_issues_sidebar_submenu'} }
|
||||
= nav_link(path: group_issues_sub_menu_items, html_options: { class: "fly-out-top-item" } ) do
|
||||
= link_to issues_group_path(@group) do
|
||||
%strong.fly-out-top-item-name
|
||||
= _('Issues')
|
||||
%span.badge.badge-pill.count.issue_counter.fly-out-badge= issues_count
|
||||
|
||||
%li.divider.fly-out-top-item
|
||||
= nav_link(path: 'groups#issues', html_options: { class: 'home' }) do
|
||||
= link_to issues_group_path(@group), title: _('List') do
|
||||
%span
|
||||
= _('List')
|
||||
|
||||
- if group_sidebar_link?(:boards)
|
||||
= nav_link(path: ['boards#index', 'boards#show']) do
|
||||
= link_to group_boards_path(@group), title: boards_link_text, data: { qa_selector: 'group_issue_boards_link' } do
|
||||
%span
|
||||
= boards_link_text
|
||||
|
||||
- if group_sidebar_link?(:milestones)
|
||||
= nav_link(path: 'milestones#index') do
|
||||
= link_to group_milestones_path(@group), title: _('Milestones'), data: { qa_selector: 'group_milestones_link' } do
|
||||
%span
|
||||
= _('Milestones')
|
||||
|
||||
= render_if_exists 'layouts/nav/sidebar/group_iterations_link'
|
||||
|
||||
- if group_sidebar_link?(:merge_requests)
|
||||
= nav_link(path: 'groups#merge_requests') do
|
||||
= link_to merge_requests_group_path(@group) do
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
- label_class = local_assigns.fetch(:bold_label, false) ? 'font-weight-bold' : ''
|
||||
|
||||
.gl-form-checkbox.custom-control.custom-checkbox
|
||||
= form.check_box :request_access_enabled, class: 'custom-control-input', data: { qa_selector: 'request_access_checkbox' }
|
||||
= form.label :request_access_enabled, class: 'custom-control-label' do
|
||||
%span{ class: label_class }= _('Allow users to request access (if visibility is public or internal)')
|
||||
= form.gitlab_ui_checkbox_component :request_access_enabled,
|
||||
_('Allow users to request access (if visibility is public or internal)'),
|
||||
label_options: { class: label_class },
|
||||
checkbox_options: { data: { qa_selector: 'request_access_checkbox' } }
|
||||
|
|
|
@ -12,4 +12,5 @@ const ROOT_PATH = path.resolve(__dirname, '../..');
|
|||
// lib/gitlab.rb: Gitlab.jh?
|
||||
// Since IS_EE already satisifies the conditions of not being a FOSS_ONLY.
|
||||
// const isFossOnly = JSON.parse(process.env.FOSS_ONLY || 'false');
|
||||
module.exports = IS_EE && fs.existsSync(path.join(ROOT_PATH, 'jh'));
|
||||
const isEEOnly = JSON.parse(process.env.EE_ONLY || 'false');
|
||||
module.exports = IS_EE && !isEEOnly && fs.existsSync(path.join(ROOT_PATH, 'jh'));
|
||||
|
|
17
db/migrate/20210721145029_add_state_to_members.rb
Normal file
17
db/migrate/20210721145029_add_state_to_members.rb
Normal file
|
@ -0,0 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddStateToMembers < ActiveRecord::Migration[6.1]
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
|
||||
def up
|
||||
with_lock_retries do
|
||||
add_column :members, :state, :integer, limit: 2, default: 0
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
with_lock_retries do
|
||||
remove_column :members, :state
|
||||
end
|
||||
end
|
||||
end
|
1
db/schema_migrations/20210721145029
Normal file
1
db/schema_migrations/20210721145029
Normal file
|
@ -0,0 +1 @@
|
|||
1585d2912058ce3a9225233c23707a3679a3f8df2078c71b5cc48f28b7bb9392
|
|
@ -14707,7 +14707,8 @@ CREATE TABLE members (
|
|||
requested_at timestamp without time zone,
|
||||
expires_at date,
|
||||
ldap boolean DEFAULT false NOT NULL,
|
||||
override boolean DEFAULT false NOT NULL
|
||||
override boolean DEFAULT false NOT NULL,
|
||||
state smallint DEFAULT 0
|
||||
);
|
||||
|
||||
CREATE SEQUENCE members_id_seq
|
||||
|
|
|
@ -8,10 +8,10 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
To enable the GitLab Prometheus metrics:
|
||||
|
||||
1. Log into GitLab as a user with [administrator permissions](../../../user/permissions.md).
|
||||
1. Log in to GitLab as a user with [administrator permissions](../../../user/permissions.md).
|
||||
1. On the top bar, select **Menu >** **{admin}** **Admin**.
|
||||
1. On the left sidebar, select **Settings > Metrics and profiling**.
|
||||
1. Find the **Metrics - Prometheus** section, and click **Enable Prometheus Metrics**.
|
||||
1. Find the **Metrics - Prometheus** section, and select **Add link to Prometheus**.
|
||||
1. [Restart GitLab](../../restart_gitlab.md#omnibus-gitlab-restart) for the changes to take effect.
|
||||
|
||||
For installations from source you must configure it yourself.
|
||||
|
|
|
@ -932,63 +932,6 @@ variables:
|
|||
The DAST job does not require the project's repository to be present when running, so by default
|
||||
[`GIT_STRATEGY`](../../../ci/runners/configure_runners.md#git-strategy) is set to `none`.
|
||||
|
||||
## Running DAST in an offline environment
|
||||
|
||||
For self-managed GitLab instances in an environment with limited, restricted, or intermittent access
|
||||
to external resources through the internet, some adjustments are required for the DAST job to
|
||||
successfully run. For more information, see [Offline environments](../offline_deployments/index.md).
|
||||
|
||||
### Requirements for offline DAST support
|
||||
|
||||
To use DAST in an offline environment, you need:
|
||||
|
||||
- GitLab Runner with the [`docker` or `kubernetes` executor](#prerequisites).
|
||||
- Docker Container Registry with a locally available copy of the DAST
|
||||
[container image](https://gitlab.com/security-products/dast), found in the
|
||||
[DAST container registry](https://gitlab.com/security-products/dast/container_registry).
|
||||
|
||||
Note that GitLab Runner has a [default `pull policy` of `always`](https://docs.gitlab.com/runner/executors/docker.html#using-the-always-pull-policy),
|
||||
meaning the runner tries to pull Docker images from the GitLab container registry even if a local
|
||||
copy is available. The GitLab Runner [`pull_policy` can be set to `if-not-present`](https://docs.gitlab.com/runner/executors/docker.html#using-the-if-not-present-pull-policy)
|
||||
in an offline environment if you prefer using only locally available Docker images. However, we
|
||||
recommend keeping the pull policy setting to `always` if not in an offline environment, as this
|
||||
enables the use of updated scanners in your CI/CD pipelines.
|
||||
|
||||
### Make GitLab DAST analyzer images available inside your Docker registry
|
||||
|
||||
For DAST, import the following default DAST analyzer image from `registry.gitlab.com` to your [local Docker container registry](../../packages/container_registry/index.md):
|
||||
|
||||
- `registry.gitlab.com/security-products/dast:latest`
|
||||
|
||||
The process for importing Docker images into a local offline Docker registry depends on
|
||||
**your network security policy**. Please consult your IT staff to find an accepted and approved
|
||||
process by which external resources can be imported or temporarily accessed.
|
||||
These scanners are [periodically updated](../vulnerabilities/index.md#vulnerability-scanner-maintenance)
|
||||
with new definitions, and you may be able to make occasional updates on your own.
|
||||
|
||||
For details on saving and transporting Docker images as a file, see Docker's documentation on
|
||||
[`docker save`](https://docs.docker.com/engine/reference/commandline/save/),
|
||||
[`docker load`](https://docs.docker.com/engine/reference/commandline/load/),
|
||||
[`docker export`](https://docs.docker.com/engine/reference/commandline/export/), and
|
||||
[`docker import`](https://docs.docker.com/engine/reference/commandline/import/).
|
||||
|
||||
### Set DAST CI/CD job variables to use local DAST analyzers
|
||||
|
||||
Add the following configuration to your `.gitlab-ci.yml` file. You must replace `image` to refer to
|
||||
the DAST Docker image hosted on your local Docker container registry:
|
||||
|
||||
```yaml
|
||||
include:
|
||||
- template: DAST.gitlab-ci.yml
|
||||
dast:
|
||||
image: registry.example.com/namespace/dast:latest
|
||||
```
|
||||
|
||||
The DAST job should now use local copies of the DAST analyzers to scan your code and generate
|
||||
security reports without requiring internet access.
|
||||
|
||||
Alternatively, you can use the CI/CD variable `SECURE_ANALYZERS_PREFIX` to override the base registry address of the `dast` image.
|
||||
|
||||
## On-demand scans
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/218465) in GitLab 13.2.
|
||||
|
|
63
doc/user/application_security/dast/run_dast_offline.md
Normal file
63
doc/user/application_security/dast/run_dast_offline.md
Normal file
|
@ -0,0 +1,63 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
|
||||
type: reference, howto
|
||||
---
|
||||
|
||||
# Run DAST in an offline environment
|
||||
|
||||
For self-managed GitLab instances in an environment with limited, restricted, or intermittent access
|
||||
to external resources through the internet, some adjustments are required for the DAST job to
|
||||
successfully run. For more information, see [Offline environments](../offline_deployments/index.md).
|
||||
|
||||
## Requirements for offline DAST support
|
||||
|
||||
To use DAST in an offline environment, you need:
|
||||
|
||||
- GitLab Runner with the [`docker` or `kubernetes` executor](index.md#prerequisites).
|
||||
- Docker Container Registry with a locally available copy of the DAST
|
||||
[container image](https://gitlab.com/security-products/dast), found in the
|
||||
[DAST container registry](https://gitlab.com/security-products/dast/container_registry).
|
||||
|
||||
Note that GitLab Runner has a [default `pull policy` of `always`](https://docs.gitlab.com/runner/executors/docker.html#using-the-always-pull-policy),
|
||||
meaning the runner tries to pull Docker images from the GitLab container registry even if a local
|
||||
copy is available. The GitLab Runner [`pull_policy` can be set to `if-not-present`](https://docs.gitlab.com/runner/executors/docker.html#using-the-if-not-present-pull-policy)
|
||||
in an offline environment if you prefer using only locally available Docker images. However, we
|
||||
recommend keeping the pull policy setting to `always` if not in an offline environment, as this
|
||||
enables the use of updated scanners in your CI/CD pipelines.
|
||||
|
||||
## Make GitLab DAST analyzer images available inside your Docker registry
|
||||
|
||||
For DAST, import the following default DAST analyzer image from `registry.gitlab.com` to your [local Docker container registry](../../packages/container_registry/index.md):
|
||||
|
||||
- `registry.gitlab.com/security-products/dast:latest`
|
||||
|
||||
The process for importing Docker images into a local offline Docker registry depends on
|
||||
**your network security policy**. Please consult your IT staff to find an accepted and approved
|
||||
process by which external resources can be imported or temporarily accessed.
|
||||
These scanners are [periodically updated](../vulnerabilities/index.md#vulnerability-scanner-maintenance)
|
||||
with new definitions, and you may be able to make occasional updates on your own.
|
||||
|
||||
For details on saving and transporting Docker images as a file, see Docker's documentation on
|
||||
[`docker save`](https://docs.docker.com/engine/reference/commandline/save/),
|
||||
[`docker load`](https://docs.docker.com/engine/reference/commandline/load/),
|
||||
[`docker export`](https://docs.docker.com/engine/reference/commandline/export/), and
|
||||
[`docker import`](https://docs.docker.com/engine/reference/commandline/import/).
|
||||
|
||||
## Set DAST CI/CD job variables to use local DAST analyzers
|
||||
|
||||
Add the following configuration to your `.gitlab-ci.yml` file. You must replace `image` to refer to
|
||||
the DAST Docker image hosted on your local Docker container registry:
|
||||
|
||||
```yaml
|
||||
include:
|
||||
- template: DAST.gitlab-ci.yml
|
||||
dast:
|
||||
image: registry.example.com/namespace/dast:latest
|
||||
```
|
||||
|
||||
The DAST job should now use local copies of the DAST analyzers to scan your code and generate
|
||||
security reports without requiring internet access.
|
||||
|
||||
Alternatively, you can use the CI/CD variable `SECURE_ANALYZERS_PREFIX` to override the base registry address of the `dast` image.
|
|
@ -87,7 +87,7 @@ above. You can find more information at each of the pages below:
|
|||
|
||||
- [Container scanning offline directions](../container_scanning/index.md#running-container-scanning-in-an-offline-environment)
|
||||
- [SAST offline directions](../sast/index.md#running-sast-in-an-offline-environment)
|
||||
- [DAST offline directions](../dast/index.md#running-dast-in-an-offline-environment)
|
||||
- [DAST offline directions](../dast/run_dast_offline.md#run-dast-in-an-offline-environment)
|
||||
- [License Compliance offline directions](../../compliance/license_compliance/index.md#running-license-compliance-in-an-offline-environment)
|
||||
- [Dependency Scanning offline directions](../dependency_scanning/index.md#running-dependency-scanning-in-an-offline-environment)
|
||||
|
||||
|
|
|
@ -52,9 +52,6 @@ module Gitlab
|
|||
tracking_category: 'Growth::Conversion::Experiment::ShowTrialStatusInSidebar',
|
||||
rollout_strategy: :group
|
||||
},
|
||||
trial_onboarding_issues: {
|
||||
tracking_category: 'Growth::Conversion::Experiment::TrialOnboardingIssues'
|
||||
},
|
||||
learn_gitlab_a: {
|
||||
tracking_category: 'Growth::Conversion::Experiment::LearnGitLabA',
|
||||
rollout_strategy: :user
|
||||
|
|
|
@ -328,6 +328,9 @@ excluded_attributes:
|
|||
- :release_id
|
||||
project_members:
|
||||
- :source_id
|
||||
- :state
|
||||
group_members:
|
||||
- :state
|
||||
metrics:
|
||||
- :merge_request_id
|
||||
- :pipeline_id
|
||||
|
|
101
lib/sidebars/groups/menus/issues_menu.rb
Normal file
101
lib/sidebars/groups/menus/issues_menu.rb
Normal file
|
@ -0,0 +1,101 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Sidebars
|
||||
module Groups
|
||||
module Menus
|
||||
class IssuesMenu < ::Sidebars::Menu
|
||||
include Gitlab::Utils::StrongMemoize
|
||||
|
||||
override :configure_menu_items
|
||||
def configure_menu_items
|
||||
return unless can?(context.current_user, :read_group_issues, context.group)
|
||||
|
||||
add_item(list_menu_item)
|
||||
add_item(boards_menu_item)
|
||||
add_item(milestones_menu_item)
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
override :link
|
||||
def link
|
||||
issues_group_path(context.group)
|
||||
end
|
||||
|
||||
override :title
|
||||
def title
|
||||
_('Issues')
|
||||
end
|
||||
|
||||
override :sprite_icon
|
||||
def sprite_icon
|
||||
'issues'
|
||||
end
|
||||
|
||||
override :has_pill?
|
||||
def has_pill?
|
||||
true
|
||||
end
|
||||
|
||||
override :pill_count
|
||||
def pill_count
|
||||
strong_memoize(:pill_count) do
|
||||
count_service = ::Groups::OpenIssuesCountService
|
||||
count = count_service.new(context.group, context.current_user).count
|
||||
|
||||
format_cached_count(count_service, count)
|
||||
end
|
||||
end
|
||||
|
||||
override :pill_html_options
|
||||
def pill_html_options
|
||||
{
|
||||
class: 'issue_counter'
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def list_menu_item
|
||||
::Sidebars::MenuItem.new(
|
||||
title: _('List'),
|
||||
link: issues_group_path(context.group),
|
||||
active_routes: { path: 'groups#issues' },
|
||||
container_html_options: { aria: { label: _('Issues') } },
|
||||
item_id: :issue_list
|
||||
)
|
||||
end
|
||||
|
||||
def boards_menu_item
|
||||
unless can?(context.current_user, :read_group_boards, context.group)
|
||||
return ::Sidebars::NilMenuItem.new(item_id: :boards)
|
||||
end
|
||||
|
||||
title = context.group.multiple_issue_boards_available? ? s_('IssueBoards|Boards') : s_('IssueBoards|Board')
|
||||
|
||||
::Sidebars::MenuItem.new(
|
||||
title: title,
|
||||
link: group_boards_path(context.group),
|
||||
active_routes: { path: %w[boards#index boards#show] },
|
||||
item_id: :boards
|
||||
)
|
||||
end
|
||||
|
||||
def milestones_menu_item
|
||||
unless can?(context.current_user, :read_group_milestones, context.group)
|
||||
return ::Sidebars::NilMenuItem.new(item_id: :milestones)
|
||||
end
|
||||
|
||||
::Sidebars::MenuItem.new(
|
||||
title: _('Milestones'),
|
||||
link: group_milestones_path(context.group),
|
||||
active_routes: { path: 'milestones#index' },
|
||||
item_id: :milestones
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Sidebars::Groups::Menus::IssuesMenu.prepend_mod_with('Sidebars::Groups::Menus::IssuesMenu')
|
|
@ -8,6 +8,7 @@ module Sidebars
|
|||
set_scope_menu(Sidebars::Groups::Menus::ScopeMenu.new(context))
|
||||
|
||||
add_menu(Sidebars::Groups::Menus::GroupInformationMenu.new(context))
|
||||
add_menu(Sidebars::Groups::Menus::IssuesMenu.new(context))
|
||||
end
|
||||
|
||||
override :render_raw_menus_partial
|
||||
|
|
|
@ -12118,9 +12118,6 @@ msgstr ""
|
|||
msgid "Enable PlantUML"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable Prometheus Metrics"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable Pseudonymizer data collection"
|
||||
msgstr ""
|
||||
|
||||
|
@ -12142,15 +12139,12 @@ msgstr ""
|
|||
msgid "Enable What's new: Current tier only"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable a Prometheus metrics endpoint at %{metrics_path} to expose a variety of statistics on the health and performance of GitLab. Additional information on authenticating and connecting to the metrics endpoint is available %{link}."
|
||||
msgid "Enable a Prometheus endpoint that exposes health and performance statistics. The Health Check menu item appears in the Monitoring section of the Admin Area. Restart required."
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable access to the performance bar for non-administrators in a given group."
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable and configure Prometheus metrics."
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable and disable Service Desk. Some additional configuration might be required. %{link_start}Learn more%{link_end}."
|
||||
msgstr ""
|
||||
|
||||
|
@ -12184,6 +12178,9 @@ msgstr ""
|
|||
msgid "Enable header and footer in emails"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable health and performance metrics endpoint"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable in-product marketing emails"
|
||||
msgstr ""
|
||||
|
||||
|
@ -19260,6 +19257,9 @@ msgstr ""
|
|||
msgid "Learn More"
|
||||
msgstr ""
|
||||
|
||||
msgid "Learn More."
|
||||
msgstr ""
|
||||
|
||||
msgid "Learn how to %{link_start}contribute to the built-in templates%{link_end}"
|
||||
msgstr ""
|
||||
|
||||
|
@ -20723,7 +20723,7 @@ msgstr ""
|
|||
msgid "Method"
|
||||
msgstr ""
|
||||
|
||||
msgid "Method Call Threshold (ms)"
|
||||
msgid "Method call threshold (ms)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Metric was successfully added."
|
||||
|
@ -21354,6 +21354,9 @@ msgstr ""
|
|||
msgid "Monitor Settings"
|
||||
msgstr ""
|
||||
|
||||
msgid "Monitor the health and performance of GitLab with Prometheus."
|
||||
msgstr ""
|
||||
|
||||
msgid "Monitor your errors by integrating with Sentry."
|
||||
msgstr ""
|
||||
|
||||
|
@ -31806,6 +31809,9 @@ msgstr ""
|
|||
msgid "SuperSonics|Expires on"
|
||||
msgstr ""
|
||||
|
||||
msgid "SuperSonics|Export license usage file"
|
||||
msgstr ""
|
||||
|
||||
msgid "SuperSonics|Free trial"
|
||||
msgstr ""
|
||||
|
||||
|
@ -33816,9 +33822,6 @@ msgstr ""
|
|||
msgid "This setting can be overridden in each project."
|
||||
msgstr ""
|
||||
|
||||
msgid "This setting requires a %{link_to_restart} to take effect."
|
||||
msgstr ""
|
||||
|
||||
msgid "This subscription is for"
|
||||
msgstr ""
|
||||
|
||||
|
@ -38867,9 +38870,6 @@ msgstr ""
|
|||
msgid "help"
|
||||
msgstr ""
|
||||
|
||||
msgid "here"
|
||||
msgstr ""
|
||||
|
||||
msgid "http:"
|
||||
msgstr ""
|
||||
|
||||
|
@ -39610,9 +39610,6 @@ msgstr ""
|
|||
msgid "reset it."
|
||||
msgstr ""
|
||||
|
||||
msgid "restart"
|
||||
msgstr ""
|
||||
|
||||
msgid "revised"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -8,8 +8,6 @@ module QA
|
|||
|
||||
view 'app/views/layouts/nav/sidebar/_group_menus.html.haml' do
|
||||
element :general_settings_link
|
||||
element :group_issues_item
|
||||
element :group_milestones_link
|
||||
element :group_settings
|
||||
end
|
||||
|
||||
|
@ -63,7 +61,7 @@ module QA
|
|||
def go_to_milestones
|
||||
hover_issues do
|
||||
within_submenu do
|
||||
click_element(:group_milestones_link)
|
||||
click_element(:sidebar_menu_item_link, menu_item: 'Milestones')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -81,8 +79,8 @@ module QA
|
|||
|
||||
def hover_issues
|
||||
within_sidebar do
|
||||
scroll_to_element(:group_issues_item)
|
||||
find_element(:group_issues_item).hover
|
||||
scroll_to_element(:sidebar_menu_link, menu_item: 'Issues')
|
||||
find_element(:sidebar_menu_link, menu_item: 'Issues').hover
|
||||
|
||||
yield
|
||||
end
|
||||
|
|
|
@ -10,7 +10,7 @@ RSpec.describe RoutableActions do
|
|||
|
||||
def routable
|
||||
@klass = params[:type].constantize
|
||||
@routable = find_routable!(params[:type].constantize, params[:id])
|
||||
@routable = find_routable!(params[:type].constantize, params[:id], '/')
|
||||
end
|
||||
|
||||
def show
|
||||
|
@ -135,7 +135,7 @@ RSpec.describe RoutableActions do
|
|||
end
|
||||
|
||||
it 'performs checks in the context of the controller' do
|
||||
check = lambda { |routable| redirect_to routable }
|
||||
check = lambda { |routable, path_info| redirect_to routable }
|
||||
allow(subject).to receive(:not_found_actions).and_return([check])
|
||||
|
||||
get_routable(routable)
|
||||
|
|
|
@ -490,7 +490,7 @@ RSpec.describe 'Admin updates settings' do
|
|||
|
||||
it 'change Prometheus settings' do
|
||||
page.within('.as-prometheus') do
|
||||
check 'Enable Prometheus Metrics'
|
||||
check 'Enable health and performance metrics endpoint'
|
||||
click_button 'Save changes'
|
||||
end
|
||||
|
||||
|
|
|
@ -112,16 +112,6 @@ RSpec.describe NavHelper do
|
|||
it { is_expected.to all(be_a(String)) }
|
||||
end
|
||||
|
||||
describe '.group_issues_sub_menu_items' do
|
||||
subject { helper.group_issues_sub_menu_items }
|
||||
|
||||
before do
|
||||
allow(helper).to receive(:current_user).and_return(nil)
|
||||
end
|
||||
|
||||
it { is_expected.to all(be_a(String)) }
|
||||
end
|
||||
|
||||
describe '#page_has_markdown?' do
|
||||
using RSpec::Parameterized::TableSyntax
|
||||
|
||||
|
|
54
spec/lib/sidebars/groups/menus/issues_menu_spec.rb
Normal file
54
spec/lib/sidebars/groups/menus/issues_menu_spec.rb
Normal file
|
@ -0,0 +1,54 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Sidebars::Groups::Menus::IssuesMenu do
|
||||
let_it_be(:owner) { create(:user) }
|
||||
let_it_be(:group) do
|
||||
build(:group, :private).tap do |g|
|
||||
g.add_owner(owner)
|
||||
end
|
||||
end
|
||||
|
||||
let(:user) { owner }
|
||||
let(:context) { Sidebars::Groups::Context.new(current_user: user, container: group) }
|
||||
let(:menu) { described_class.new(context) }
|
||||
|
||||
describe 'Menu Items' do
|
||||
subject { menu.renderable_items.index { |e| e.item_id == item_id } }
|
||||
|
||||
shared_examples 'menu access rights' do
|
||||
specify { is_expected.not_to be_nil }
|
||||
|
||||
describe 'when the user does not have access' do
|
||||
let(:user) { nil }
|
||||
|
||||
specify { is_expected.to be_nil }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'List' do
|
||||
let(:item_id) { :issue_list }
|
||||
|
||||
specify { is_expected.not_to be_nil }
|
||||
|
||||
it_behaves_like 'menu access rights'
|
||||
end
|
||||
|
||||
describe 'Boards' do
|
||||
let(:item_id) { :boards }
|
||||
|
||||
it_behaves_like 'menu access rights'
|
||||
end
|
||||
|
||||
describe 'Milestones' do
|
||||
let(:item_id) { :milestones }
|
||||
|
||||
it_behaves_like 'menu access rights'
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'pill_count formatted results' do
|
||||
let(:count_service) { ::Groups::OpenIssuesCountService }
|
||||
end
|
||||
end
|
|
@ -10,7 +10,7 @@ RSpec.describe API::Groups do
|
|||
let_it_be(:user2) { create(:user) }
|
||||
let_it_be(:user3) { create(:user) }
|
||||
let_it_be(:admin) { create(:admin) }
|
||||
let_it_be(:group1) { create(:group, avatar: File.open(uploaded_image_temp_path)) }
|
||||
let_it_be(:group1) { create(:group, path: 'some_path', avatar: File.open(uploaded_image_temp_path)) }
|
||||
let_it_be(:group2) { create(:group, :private) }
|
||||
let_it_be(:project1) { create(:project, namespace: group1) }
|
||||
let_it_be(:project2) { create(:project, namespace: group2) }
|
||||
|
|
|
@ -39,4 +39,30 @@ RSpec.describe 'layouts/nav/sidebar/_group' do
|
|||
expect(rendered).to have_link('Members', href: group_group_members_path(group))
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Issues' do
|
||||
it 'has a default link to the issue list path' do
|
||||
render
|
||||
|
||||
expect(rendered).to have_link('Issues', href: issues_group_path(group))
|
||||
end
|
||||
|
||||
it 'has a link to the issue list page' do
|
||||
render
|
||||
|
||||
expect(rendered).to have_link('List', href: issues_group_path(group))
|
||||
end
|
||||
|
||||
it 'has a link to the boards page' do
|
||||
render
|
||||
|
||||
expect(rendered).to have_link('Board', href: group_boards_path(group))
|
||||
end
|
||||
|
||||
it 'has a link to the milestones page' do
|
||||
render
|
||||
|
||||
expect(rendered).to have_link('Milestones', href: group_milestones_path(group))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue