summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-03-12 18:09:28 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-03-12 18:09:28 +0000
commitce8a0b90849ac5d1895e741c023432930f24d724 (patch)
treedbdc97de542cdbe18a2fc8b1a6b64ac0673ed3d3
parentdc889678d1de8c09310b2f8f9742bb6c78a6f1a4 (diff)
downloadgitlab-ce-ce8a0b90849ac5d1895e741c023432930f24d724.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/assets/javascripts/mr_popover/queries/merge_request.query.graphql2
-rw-r--r--app/assets/javascripts/sidebar/queries/sidebarDetails.query.graphql2
-rw-r--r--app/assets/javascripts/sidebar/queries/sidebarDetailsForHealthStatusFeatureFlag.query.graphql2
-rw-r--r--app/graphql/mutations/issues/base.rb2
-rw-r--r--app/graphql/mutations/merge_requests/base.rb2
-rw-r--r--app/graphql/resolvers/issues_resolver.rb4
-rw-r--r--app/graphql/resolvers/merge_requests_resolver.rb4
-rw-r--r--app/graphql/types/ci/pipeline_type.rb2
-rw-r--r--app/graphql/types/merge_request_type.rb2
-rw-r--r--app/helpers/analytics_navbar_helper.rb3
-rw-r--r--app/models/namespace.rb2
-rw-r--r--app/models/user.rb1
-rw-r--r--app/models/user_highest_role.rb7
-rw-r--r--app/uploaders/avatar_uploader.rb7
-rw-r--r--app/uploaders/content_type_whitelist.rb53
-rw-r--r--app/uploaders/favicon_uploader.rb9
-rw-r--r--app/uploaders/gitlab_uploader.rb2
-rw-r--r--app/views/layouts/nav/sidebar/_group.html.haml18
-rw-r--r--app/views/layouts/nav/sidebar/_project.html.haml37
-rw-r--r--app/workers/all_queues.yml300
-rw-r--r--app/workers/concerns/worker_attributes.rb4
-rw-r--r--app/workers/error_tracking_issue_link_worker.rb4
-rw-r--r--app/workers/update_merge_requests_worker.rb16
-rw-r--r--changelogs/unreleased/200107-avatar-content-type-does-not-match-file-extension.yml5
-rw-r--r--changelogs/unreleased/introduce_highest_role_per_user_database_table.yml5
-rw-r--r--config/locales/carrierwave.en.yml4
-rw-r--r--db/migrate/20200311093210_create_user_highest_roles.rb25
-rw-r--r--db/schema.rb7
-rw-r--r--doc/administration/high_availability/README.md4
-rw-r--r--doc/administration/operations/extra_sidekiq_processes.md2
-rw-r--r--doc/api/graphql/reference/gitlab_schema.graphql40
-rw-r--r--doc/api/graphql/reference/gitlab_schema.json40
-rw-r--r--doc/api/graphql/reference/index.md4
-rw-r--r--doc/development/api_graphql_styleguide.md2
-rw-r--r--doc/development/sidekiq_style_guide.md14
-rw-r--r--lib/gitlab/ci/parsers/test/junit.rb12
-rw-r--r--lib/gitlab/ci/reports/test_case.rb9
-rw-r--r--locale/gitlab.pot9
-rw-r--r--qa/qa/page/group/menu.rb1
-rw-r--r--spec/factories/ci/test_case.rb31
-rw-r--r--spec/factories/user_highest_roles.rb7
-rw-r--r--spec/features/merge_request/user_creates_image_diff_notes_spec.rb2
-rw-r--r--spec/features/projects/active_tabs_spec.rb32
-rw-r--r--spec/features/projects/user_uses_shortcuts_spec.rb20
-rw-r--r--spec/frontend/projects/project_import_gitlab_project_spec.js (renamed from spec/javascripts/projects/project_import_gitlab_project_spec.js)0
-rw-r--r--spec/frontend/projects/project_new_spec.js (renamed from spec/javascripts/projects/project_new_spec.js)0
-rw-r--r--spec/lib/gitlab/ci/parsers/test/junit_spec.rb69
-rw-r--r--spec/lib/gitlab/ci/reports/test_case_spec.rb12
-rw-r--r--spec/lib/gitlab/sidekiq_config/cli_methods_spec.rb10
-rw-r--r--spec/lib/gitlab/sidekiq_config/worker_spec.rb2
-rw-r--r--spec/lib/gitlab/sidekiq_middleware/client_metrics_spec.rb6
-rw-r--r--spec/lib/gitlab/sidekiq_middleware/server_metrics_spec.rb6
-rw-r--r--spec/models/namespace_spec.rb20
-rw-r--r--spec/models/user_highest_role_spec.rb13
-rw-r--r--spec/models/user_spec.rb1
-rw-r--r--spec/requests/api/groups_spec.rb2
-rw-r--r--spec/support/shared_contexts/upload_type_check_shared_context.rb17
-rw-r--r--spec/support/shared_examples/uploaders/upload_type_shared_examples.rb27
-rw-r--r--spec/uploaders/avatar_uploader_spec.rb30
-rw-r--r--spec/uploaders/content_type_whitelist_spec.rb34
-rw-r--r--spec/uploaders/favicon_uploader_spec.rb38
-rw-r--r--spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb1
-rw-r--r--spec/workers/update_merge_requests_worker_spec.rb12
63 files changed, 671 insertions, 389 deletions
diff --git a/app/assets/javascripts/mr_popover/queries/merge_request.query.graphql b/app/assets/javascripts/mr_popover/queries/merge_request.query.graphql
index 37d4bc88a69..0bb9bc03bc7 100644
--- a/app/assets/javascripts/mr_popover/queries/merge_request.query.graphql
+++ b/app/assets/javascripts/mr_popover/queries/merge_request.query.graphql
@@ -1,4 +1,4 @@
-query mergeRequest($projectPath: ID!, $mergeRequestIID: String!) {
+query mergeRequest($projectPath: ID!, $mergeRequestIID: ID!) {
project(fullPath: $projectPath) {
mergeRequest(iid: $mergeRequestIID) {
createdAt
diff --git a/app/assets/javascripts/sidebar/queries/sidebarDetails.query.graphql b/app/assets/javascripts/sidebar/queries/sidebarDetails.query.graphql
index 8cc68f6ea9a..e9fdc05df5a 100644
--- a/app/assets/javascripts/sidebar/queries/sidebarDetails.query.graphql
+++ b/app/assets/javascripts/sidebar/queries/sidebarDetails.query.graphql
@@ -1,4 +1,4 @@
-query ($fullPath: ID!, $iid: String!) {
+query ($fullPath: ID!, $iid: ID!) {
project (fullPath: $fullPath) {
issue (iid: $iid) {
iid
diff --git a/app/assets/javascripts/sidebar/queries/sidebarDetailsForHealthStatusFeatureFlag.query.graphql b/app/assets/javascripts/sidebar/queries/sidebarDetailsForHealthStatusFeatureFlag.query.graphql
index 8cc68f6ea9a..e9fdc05df5a 100644
--- a/app/assets/javascripts/sidebar/queries/sidebarDetailsForHealthStatusFeatureFlag.query.graphql
+++ b/app/assets/javascripts/sidebar/queries/sidebarDetailsForHealthStatusFeatureFlag.query.graphql
@@ -1,4 +1,4 @@
-query ($fullPath: ID!, $iid: String!) {
+query ($fullPath: ID!, $iid: ID!) {
project (fullPath: $fullPath) {
issue (iid: $iid) {
iid
diff --git a/app/graphql/mutations/issues/base.rb b/app/graphql/mutations/issues/base.rb
index 7c545c3eb00..9ec9ff812c2 100644
--- a/app/graphql/mutations/issues/base.rb
+++ b/app/graphql/mutations/issues/base.rb
@@ -9,7 +9,7 @@ module Mutations
required: true,
description: "The project the issue to mutate is in"
- argument :iid, GraphQL::STRING_TYPE,
+ argument :iid, GraphQL::ID_TYPE,
required: true,
description: "The iid of the issue to mutate"
diff --git a/app/graphql/mutations/merge_requests/base.rb b/app/graphql/mutations/merge_requests/base.rb
index 96228855ace..5828146d82a 100644
--- a/app/graphql/mutations/merge_requests/base.rb
+++ b/app/graphql/mutations/merge_requests/base.rb
@@ -9,7 +9,7 @@ module Mutations
required: true,
description: "The project the merge request to mutate is in"
- argument :iid, GraphQL::STRING_TYPE,
+ argument :iid, GraphQL::ID_TYPE,
required: true,
description: "The iid of the merge request to mutate"
diff --git a/app/graphql/resolvers/issues_resolver.rb b/app/graphql/resolvers/issues_resolver.rb
index ae77af32b5b..59d37b0bc6f 100644
--- a/app/graphql/resolvers/issues_resolver.rb
+++ b/app/graphql/resolvers/issues_resolver.rb
@@ -2,11 +2,11 @@
module Resolvers
class IssuesResolver < BaseResolver
- argument :iid, GraphQL::STRING_TYPE,
+ argument :iid, GraphQL::ID_TYPE,
required: false,
description: 'IID of the issue. For example, "1"'
- argument :iids, [GraphQL::STRING_TYPE],
+ argument :iids, [GraphQL::ID_TYPE],
required: false,
description: 'List of IIDs of issues. For example, [1, 2]'
argument :state, Types::IssuableStateEnum,
diff --git a/app/graphql/resolvers/merge_requests_resolver.rb b/app/graphql/resolvers/merge_requests_resolver.rb
index 1740d614b69..96f1a4ffabd 100644
--- a/app/graphql/resolvers/merge_requests_resolver.rb
+++ b/app/graphql/resolvers/merge_requests_resolver.rb
@@ -2,11 +2,11 @@
module Resolvers
class MergeRequestsResolver < BaseResolver
- argument :iid, GraphQL::STRING_TYPE,
+ argument :iid, GraphQL::ID_TYPE,
required: false,
description: 'The IID of the merge request, e.g., "1"'
- argument :iids, [GraphQL::STRING_TYPE],
+ argument :iids, [GraphQL::ID_TYPE],
required: false,
description: 'The list of IIDs of issues, e.g., [1, 2]'
diff --git a/app/graphql/types/ci/pipeline_type.rb b/app/graphql/types/ci/pipeline_type.rb
index d77b2a2ba32..ba0103781ff 100644
--- a/app/graphql/types/ci/pipeline_type.rb
+++ b/app/graphql/types/ci/pipeline_type.rb
@@ -11,7 +11,7 @@ module Types
field :id, GraphQL::ID_TYPE, null: false,
description: 'ID of the pipeline'
- field :iid, GraphQL::STRING_TYPE, null: false,
+ field :iid, GraphQL::ID_TYPE, null: false,
description: 'Internal ID of the pipeline'
field :sha, GraphQL::STRING_TYPE, null: false,
diff --git a/app/graphql/types/merge_request_type.rb b/app/graphql/types/merge_request_type.rb
index 0da95b367d8..ba4bdc6a443 100644
--- a/app/graphql/types/merge_request_type.rb
+++ b/app/graphql/types/merge_request_type.rb
@@ -14,7 +14,7 @@ module Types
field :id, GraphQL::ID_TYPE, null: false,
description: 'ID of the merge request'
- field :iid, GraphQL::STRING_TYPE, null: false,
+ field :iid, GraphQL::ID_TYPE, null: false,
description: 'Internal ID of the merge request'
field :title, GraphQL::STRING_TYPE, null: false,
description: 'Title of the merge request'
diff --git a/app/helpers/analytics_navbar_helper.rb b/app/helpers/analytics_navbar_helper.rb
index eecb4090bcf..f94119c4eef 100644
--- a/app/helpers/analytics_navbar_helper.rb
+++ b/app/helpers/analytics_navbar_helper.rb
@@ -31,7 +31,6 @@ module AnalyticsNavbarHelper
end
def cycle_analytics_navbar_link(project, current_user)
- return unless Feature.enabled?(:analytics_pages_under_project_analytics_sidebar, project, default_enabled: true)
return unless project_nav_tab?(:cycle_analytics)
navbar_sub_item(
@@ -43,7 +42,6 @@ module AnalyticsNavbarHelper
end
def repository_analytics_navbar_link(project, current_user)
- return if Feature.disabled?(:analytics_pages_under_project_analytics_sidebar, project, default_enabled: true)
return if project.empty_repo?
navbar_sub_item(
@@ -55,7 +53,6 @@ module AnalyticsNavbarHelper
end
def ci_cd_analytics_navbar_link(project, current_user)
- return unless Feature.enabled?(:analytics_pages_under_project_analytics_sidebar, project, default_enabled: true)
return unless project_nav_tab?(:pipelines)
return unless project.feature_available?(:builds, current_user) || !project.empty_repo?
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index 631bd930e2f..aae45144f1a 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -130,7 +130,7 @@ class Namespace < ApplicationRecord
return unless host.ends_with?(gitlab_host)
name = host.delete_suffix(gitlab_host)
- Namespace.find_by_path(name)
+ Namespace.where(parent_id: nil).find_by_path(name)
end
# overridden in ee
diff --git a/app/models/user.rb b/app/models/user.rb
index d1a30c6a5c8..17850d13e48 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -164,6 +164,7 @@ class User < ApplicationRecord
has_one :status, class_name: 'UserStatus'
has_one :user_preference
has_one :user_detail
+ has_one :user_highest_role
#
# Validations
diff --git a/app/models/user_highest_role.rb b/app/models/user_highest_role.rb
new file mode 100644
index 00000000000..dc166273787
--- /dev/null
+++ b/app/models/user_highest_role.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class UserHighestRole < ApplicationRecord
+ belongs_to :user, optional: false
+
+ validates :highest_access_level, allow_nil: true, inclusion: { in: Gitlab::Access.all_values }
+end
diff --git a/app/uploaders/avatar_uploader.rb b/app/uploaders/avatar_uploader.rb
index e4046e4b7e6..73dafaefb41 100644
--- a/app/uploaders/avatar_uploader.rb
+++ b/app/uploaders/avatar_uploader.rb
@@ -5,9 +5,8 @@ class AvatarUploader < GitlabUploader
include RecordsUploads::Concern
include ObjectStorage::Concern
prepend ObjectStorage::Extension::RecordsUploads
- include UploadTypeCheck::Concern
- check_upload_type extensions: AvatarUploader::SAFE_IMAGE_EXT
+ MIME_WHITELIST = %w[image/png image/jpeg image/gif image/bmp image/tiff image/vnd.microsoft.icon].freeze
def exists?
model.avatar.file && model.avatar.file.present?
@@ -29,6 +28,10 @@ class AvatarUploader < GitlabUploader
super || 'avatar'
end
+ def content_type_whitelist
+ MIME_WHITELIST
+ end
+
private
def dynamic_segment
diff --git a/app/uploaders/content_type_whitelist.rb b/app/uploaders/content_type_whitelist.rb
new file mode 100644
index 00000000000..b3975d7e2e0
--- /dev/null
+++ b/app/uploaders/content_type_whitelist.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+# Currently we run CarrierWave 1.3.1 which means we can not whitelist files
+# by their content type through magic header parsing.
+#
+# This is a patch to hold us over until we get to CarrierWave 2 :) It's a mashup of
+# CarrierWave's lib/carrierwave/uploader/content_type_whitelist.rb and
+# lib/carrierwave/sanitized_file.rb
+#
+# Include this concern and add a content_type_whitelist method to get the same
+# behavior as you would with CarrierWave 2.
+#
+# This is not an exact replacement as we don't override
+# SanitizedFile#content_type but we do set the content_type attribute when we
+# check the whitelist.
+#
+# Remove this after moving to CarrierWave 2, though on practical terms it shouldn't
+# break anything if left for a while.
+module ContentTypeWhitelist
+ module Concern
+ extend ActiveSupport::Concern
+
+ private
+
+ # CarrierWave calls this method as part of it's before :cache callbacks.
+ # Here we override and extend CarrierWave's method that does not parse the
+ # magic headers.
+ def check_content_type_whitelist!(new_file)
+ new_file.content_type = mime_magic_content_type(new_file.path)
+
+ if content_type_whitelist && !whitelisted_content_type?(new_file.content_type)
+ message = I18n.translate(:"errors.messages.content_type_whitelist_error", allowed_types: Array(content_type_whitelist).join(", "))
+ raise CarrierWave::IntegrityError, message
+ end
+
+ super(new_file)
+ end
+
+ def whitelisted_content_type?(content_type)
+ Array(content_type_whitelist).any? { |item| content_type =~ /#{item}/ }
+ end
+
+ def mime_magic_content_type(path)
+ if path
+ File.open(path) do |file|
+ MimeMagic.by_magic(file).try(:type) || 'invalid/invalid'
+ end
+ end
+ rescue Errno::ENOENT
+ nil
+ end
+ end
+end
diff --git a/app/uploaders/favicon_uploader.rb b/app/uploaders/favicon_uploader.rb
index f393fdf0d84..c9be55e001c 100644
--- a/app/uploaders/favicon_uploader.rb
+++ b/app/uploaders/favicon_uploader.rb
@@ -1,16 +1,17 @@
# frozen_string_literal: true
class FaviconUploader < AttachmentUploader
- include UploadTypeCheck::Concern
-
EXTENSION_WHITELIST = %w[png ico].freeze
-
- check_upload_type extensions: EXTENSION_WHITELIST
+ MIME_WHITELIST = %w[image/png image/vnd.microsoft.icon].freeze
def extension_whitelist
EXTENSION_WHITELIST
end
+ def content_type_whitelist
+ MIME_WHITELIST
+ end
+
private
def filename_for_different_format(filename, format)
diff --git a/app/uploaders/gitlab_uploader.rb b/app/uploaders/gitlab_uploader.rb
index 7dc211b14e4..654bb15378c 100644
--- a/app/uploaders/gitlab_uploader.rb
+++ b/app/uploaders/gitlab_uploader.rb
@@ -1,6 +1,8 @@
# frozen_string_literal: true
class GitlabUploader < CarrierWave::Uploader::Base
+ include ContentTypeWhitelist::Concern
+
class_attribute :options
class << self
diff --git a/app/views/layouts/nav/sidebar/_group.html.haml b/app/views/layouts/nav/sidebar/_group.html.haml
index b2fa647b23e..588ee63c56f 100644
--- a/app/views/layouts/nav/sidebar/_group.html.haml
+++ b/app/views/layouts/nav/sidebar/_group.html.haml
@@ -1,4 +1,3 @@
-- should_display_analytics_pages_in_sidebar = Feature.enabled?(:analytics_pages_under_group_analytics_sidebar, @group, default_enabled: true)
- issues_count = group_issues_count(state: 'opened')
- merge_requests_count = group_merge_requests_count(state: 'opened')
@@ -13,8 +12,7 @@
%ul.sidebar-top-level-items.qa-group-sidebar
- if group_sidebar_link?(:overview)
- paths = group_overview_nav_link_paths
- - paths << 'contribution_analytics#show' unless should_display_analytics_pages_in_sidebar
- = nav_link(path: paths, unless: -> { should_display_analytics_pages_in_sidebar && current_path?('groups/contribution_analytics#show') }, html_options: { class: 'home' }) do
+ = nav_link(path: paths, unless: -> { current_path?('groups/contribution_analytics#show') }, html_options: { class: 'home' }) do
= link_to group_path(@group) do
.nav-icon-container
= sprite_icon('home')
@@ -45,19 +43,10 @@
%span
= _('Activity')
- - unless should_display_analytics_pages_in_sidebar
- - if group_sidebar_link?(:contribution_analytics)
- = nav_link(path: 'contribution_analytics#show') do
- = link_to group_contribution_analytics_path(@group), title: _('Contribution'), data: { placement: 'right', qa_selector: 'contribution_analytics_link' } do
- %span
- = _('Contribution')
-
- = render_if_exists 'layouts/nav/group_insights_link'
-
= render_if_exists "layouts/nav/ee/epic_link", group: @group
- if group_sidebar_link?(:issues)
- = nav_link(path: group_issues_sub_menu_items, unless: -> { should_display_analytics_pages_in_sidebar && current_path?('issues_analytics#show') }) do
+ = 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' } do
.nav-icon-container
= sprite_icon('issues')
@@ -84,9 +73,6 @@
%span
= boards_link_text
- - unless should_display_analytics_pages_in_sidebar
- = render_if_exists 'layouts/nav/issues_analytics_link'
-
- if group_sidebar_link?(:labels)
= nav_link(path: 'labels#index') do
= link_to group_labels_path(@group), title: _('Labels') do
diff --git a/app/views/layouts/nav/sidebar/_project.html.haml b/app/views/layouts/nav/sidebar/_project.html.haml
index aef9532fd46..d7619799f14 100644
--- a/app/views/layouts/nav/sidebar/_project.html.haml
+++ b/app/views/layouts/nav/sidebar/_project.html.haml
@@ -1,5 +1,3 @@
-- should_display_analytics_pages_in_sidebar = Feature.enabled?(:analytics_pages_under_project_analytics_sidebar, @project, default_enabled: true)
-
.nav-sidebar{ class: ("sidebar-collapsed-desktop" if collapsed_sidebar?) }
.nav-sidebar-inner-scroll
- can_edit = can?(current_user, :admin_project, @project)
@@ -10,9 +8,7 @@
.sidebar-context-title
= @project.name
%ul.sidebar-top-level-items.qa-project-sidebar
- - paths = sidebar_projects_paths
- - paths << 'cycle_analytics#show' unless should_display_analytics_pages_in_sidebar
- = nav_link(path: paths, html_options: { class: 'home' }) do
+ = nav_link(path: sidebar_projects_paths, html_options: { class: 'home' }) do
= link_to project_path(@project), class: 'shortcuts-project rspec-project-link', data: { qa_selector: 'project_link' } do
.nav-icon-container
= sprite_icon('home')
@@ -39,17 +35,8 @@
%span= _('Releases')
- - unless should_display_analytics_pages_in_sidebar
- - if can?(current_user, :read_cycle_analytics, @project)
- = nav_link(path: 'cycle_analytics#show') do
- = link_to project_cycle_analytics_path(@project), title: _('Value Stream'), class: 'shortcuts-project-cycle-analytics' do
- %span= _('Value Stream')
-
- = render_if_exists 'layouts/nav/project_insights_link'
-
-
- if project_nav_tab? :files
- = nav_link(controller: sidebar_repository_paths, unless: -> { should_display_analytics_pages_in_sidebar && current_path?('projects/graphs#charts') }) do
+ = nav_link(controller: sidebar_repository_paths, unless: -> { current_path?('projects/graphs#charts') }) do
= link_to project_tree_path(@project), class: 'shortcuts-tree qa-project-menu-repo' do
.nav-icon-container
= sprite_icon('doc-text')
@@ -90,11 +77,6 @@
= link_to project_compare_index_path(@project, from: @repository.root_ref, to: current_ref) do
= _('Compare')
- - unless should_display_analytics_pages_in_sidebar
- = nav_link(path: 'graphs#charts') do
- = link_to charts_project_graph_path(@project, current_ref) do
- = _('Charts')
-
= render_if_exists 'projects/sidebar/repository_locked_files'
- if project_nav_tab? :issues
@@ -178,7 +160,7 @@
= number_with_delimiter(@project.open_merge_requests_count)
- if project_nav_tab? :pipelines
- = nav_link(controller: [:pipelines, :builds, :jobs, :pipeline_schedules, :artifacts], unless: -> { should_display_analytics_pages_in_sidebar && current_path?('projects/pipelines#charts') }) do
+ = nav_link(controller: [:pipelines, :builds, :jobs, :pipeline_schedules, :artifacts], unless: -> { current_path?('projects/pipelines#charts') }) do
= link_to project_pipelines_path(@project), class: 'shortcuts-pipelines qa-link-pipelines rspec-link-pipelines', data: { qa_selector: 'ci_cd_link' } do
.nav-icon-container
= sprite_icon('rocket')
@@ -215,12 +197,6 @@
%span
= _('Schedules')
- - if !should_display_analytics_pages_in_sidebar && @project.feature_available?(:builds, current_user) && !@project.empty_repo?
- = nav_link(path: 'pipelines#charts') do
- = link_to charts_project_pipelines_path(@project), title: _('Charts'), class: 'shortcuts-pipelines-charts' do
- %span
- = _('Charts')
-
= render_if_exists 'layouts/nav/sidebar/project_security_link' # EE-specific
- if project_nav_tab? :operations
@@ -426,13 +402,6 @@
= link_to project_network_path(@project, current_ref), title: _('Network'), class: 'shortcuts-network' do
= _('Graph')
- - unless should_display_analytics_pages_in_sidebar
- -# Shortcut to Repository > Charts (formerly, top-nav item "Graphs")
- - unless @project.empty_repo?
- %li.hidden
- = link_to charts_project_graph_path(@project, current_ref), title: _('Charts'), class: 'shortcuts-repository-charts' do
- = _('Charts')
-
-# Shortcut to Issues > New Issue
- if project_nav_tab?(:issues)
%li.hidden
diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml
index 81c09a77730..d70df18ffaf 100644
--- a/app/workers/all_queues.yml
+++ b/app/workers/all_queues.yml
@@ -6,602 +6,602 @@
- :name: auto_devops:auto_devops_disable
:feature_category: :auto_devops
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 2
:idempotent:
- :name: auto_merge:auto_merge_process
:feature_category: :continuous_delivery
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :cpu
:weight: 3
:idempotent:
- :name: chaos:chaos_cpu_spin
:feature_category: :chaos_engineering
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 2
:idempotent:
- :name: chaos:chaos_db_spin
:feature_category: :chaos_engineering
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 2
:idempotent:
- :name: chaos:chaos_kill
:feature_category: :chaos_engineering
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 2
:idempotent:
- :name: chaos:chaos_leak_mem
:feature_category: :chaos_engineering
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 2
:idempotent:
- :name: chaos:chaos_sleep
:feature_category: :chaos_engineering
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 2
:idempotent:
- :name: container_repository:cleanup_container_repository
:feature_category: :container_registry
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: container_repository:delete_container_repository
:feature_category: :container_registry
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: cronjob:admin_email
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: cronjob:ci_archive_traces_cron
:feature_category: :continuous_integration
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: cronjob:container_expiration_policy
:feature_category: :container_registry
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: cronjob:environments_auto_stop_cron
:feature_category: :continuous_delivery
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: cronjob:expire_build_artifacts
:feature_category: :continuous_integration
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: cronjob:gitlab_usage_ping
:feature_category: :collection
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: cronjob:import_export_project_cleanup
:feature_category: :importers
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: cronjob:issue_due_scheduler
:feature_category: :issue_tracking
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: cronjob:namespaces_prune_aggregation_schedules
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :cpu
:weight: 1
:idempotent:
- :name: cronjob:pages_domain_removal_cron
:feature_category: :pages
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :cpu
:weight: 1
:idempotent:
- :name: cronjob:pages_domain_ssl_renewal_cron
:feature_category: :pages
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: cronjob:pages_domain_verification_cron
:feature_category: :pages
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: cronjob:personal_access_tokens_expiring
:feature_category: :authentication_and_authorization
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: cronjob:pipeline_schedule
:feature_category: :continuous_integration
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :cpu
:weight: 1
:idempotent:
- :name: cronjob:prune_old_events
:feature_category: :users
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: cronjob:prune_web_hook_logs
:feature_category: :integrations
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: cronjob:remove_expired_group_links
:feature_category: :authentication_and_authorization
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: cronjob:remove_expired_members
:feature_category: :authentication_and_authorization
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :cpu
:weight: 1
:idempotent:
- :name: cronjob:remove_unreferenced_lfs_objects
:feature_category: :git_lfs
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: cronjob:repository_archive_cache
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: cronjob:repository_check_dispatch
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: cronjob:requests_profiles
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: cronjob:schedule_migrate_external_diffs
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: cronjob:stuck_ci_jobs
:feature_category: :continuous_integration
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :cpu
:weight: 1
:idempotent:
- :name: cronjob:stuck_export_jobs
:feature_category: :importers
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :cpu
:weight: 1
:idempotent:
- :name: cronjob:stuck_import_jobs
:feature_category: :importers
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :cpu
:weight: 1
:idempotent:
- :name: cronjob:stuck_merge_jobs
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: cronjob:trending_projects
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: deployment:deployments_finished
:feature_category: :continuous_delivery
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :cpu
:weight: 3
:idempotent:
- :name: deployment:deployments_forward_deployment
:feature_category: :continuous_delivery
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 3
:idempotent:
- :name: deployment:deployments_success
:feature_category: :continuous_delivery
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :cpu
:weight: 3
:idempotent:
- :name: gcp_cluster:cluster_configure
:feature_category: :kubernetes_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: gcp_cluster:cluster_configure_istio
:feature_category: :kubernetes_management
:has_external_dependencies: true
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: gcp_cluster:cluster_install_app
:feature_category: :kubernetes_management
:has_external_dependencies: true
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: gcp_cluster:cluster_patch_app
:feature_category: :kubernetes_management
:has_external_dependencies: true
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: gcp_cluster:cluster_project_configure
:feature_category: :kubernetes_management
:has_external_dependencies: true
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: gcp_cluster:cluster_provision
:feature_category: :kubernetes_management
:has_external_dependencies: true
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: gcp_cluster:cluster_upgrade_app
:feature_category: :kubernetes_management
:has_external_dependencies: true
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: gcp_cluster:cluster_wait_for_app_installation
:feature_category: :kubernetes_management
:has_external_dependencies: true
- :urgency: :default
+ :urgency: :low
:resource_boundary: :cpu
:weight: 1
:idempotent:
- :name: gcp_cluster:cluster_wait_for_ingress_ip_address
:feature_category: :kubernetes_management
:has_external_dependencies: true
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: gcp_cluster:clusters_applications_activate_service
:feature_category: :kubernetes_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: gcp_cluster:clusters_applications_deactivate_service
:feature_category: :kubernetes_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: gcp_cluster:clusters_applications_uninstall
:feature_category: :kubernetes_management
:has_external_dependencies: true
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: gcp_cluster:clusters_applications_wait_for_uninstall_app
:feature_category: :kubernetes_management
:has_external_dependencies: true
- :urgency: :default
+ :urgency: :low
:resource_boundary: :cpu
:weight: 1
:idempotent:
- :name: gcp_cluster:clusters_cleanup_app
:feature_category: :kubernetes_management
:has_external_dependencies: true
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: gcp_cluster:clusters_cleanup_project_namespace
:feature_category: :kubernetes_management
:has_external_dependencies: true
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: gcp_cluster:clusters_cleanup_service_account
:feature_category: :kubernetes_management
:has_external_dependencies: true
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: gcp_cluster:wait_for_cluster_creation
:feature_category: :kubernetes_management
:has_external_dependencies: true
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: github_importer:github_import_import_diff_note
:feature_category: :importers
:has_external_dependencies: true
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: github_importer:github_import_import_issue
:feature_category: :importers
:has_external_dependencies: true
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: github_importer:github_import_import_lfs_object
:feature_category: :importers
:has_external_dependencies: true
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: github_importer:github_import_import_note
:feature_category: :importers
:has_external_dependencies: true
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: github_importer:github_import_import_pull_request
:feature_category: :importers
:has_external_dependencies: true
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: github_importer:github_import_refresh_import_jid
:feature_category: :importers
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: github_importer:github_import_stage_finish_import
:feature_category: :importers
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: github_importer:github_import_stage_import_base_data
:feature_category: :importers
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: github_importer:github_import_stage_import_issues_and_diff_notes
:feature_category: :importers
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: github_importer:github_import_stage_import_lfs_objects
:feature_category: :importers
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: github_importer:github_import_stage_import_notes
:feature_category: :importers
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: github_importer:github_import_stage_import_pull_requests
:feature_category: :importers
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: github_importer:github_import_stage_import_repository
:feature_category: :importers
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: hashed_storage:hashed_storage_migrator
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: hashed_storage:hashed_storage_project_migrate
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: hashed_storage:hashed_storage_project_rollback
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: hashed_storage:hashed_storage_rollbacker
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: incident_management:incident_management_process_alert
:feature_category: :incident_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 2
:idempotent:
- :name: mail_scheduler:mail_scheduler_issue_due
:feature_category: :issue_tracking
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 2
:idempotent:
- :name: mail_scheduler:mail_scheduler_notification_service
:feature_category: :issue_tracking
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :cpu
:weight: 2
:idempotent:
- :name: notifications:new_release
:feature_category: :release_orchestration
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 2
:idempotent:
- :name: object_pool:object_pool_create
:feature_category: :gitaly
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: object_pool:object_pool_destroy
:feature_category: :gitaly
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: object_pool:object_pool_join
:feature_category: :gitaly
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :cpu
:weight: 1
:idempotent:
- :name: object_pool:object_pool_schedule_join
:feature_category: :gitaly
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: object_storage:object_storage_background_move
:feature_category: :not_owned
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: object_storage:object_storage_migrate_uploads
:feature_category: :not_owned
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: pipeline_background:archive_trace
:feature_category: :continuous_integration
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: pipeline_background:ci_build_trace_chunk_flush
:feature_category: :continuous_integration
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
@@ -629,28 +629,28 @@
- :name: pipeline_creation:run_pipeline_schedule
:feature_category: :continuous_integration
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 4
:idempotent:
- :name: pipeline_default:build_coverage
:feature_category: :continuous_integration
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 3
:idempotent:
- :name: pipeline_default:build_trace_sections
:feature_category: :continuous_integration
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 3
:idempotent:
- :name: pipeline_default:ci_create_cross_project_pipeline
:feature_category: :continuous_integration
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :cpu
:weight: 3
:idempotent:
@@ -720,21 +720,21 @@
- :name: pipeline_processing:ci_build_prepare
:feature_category: :continuous_integration
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 5
:idempotent:
- :name: pipeline_processing:ci_build_schedule
:feature_category: :continuous_integration
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :cpu
:weight: 5
:idempotent:
- :name: pipeline_processing:ci_resource_groups_assign_resource_from_resource_group
:feature_category: :continuous_delivery
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 5
:idempotent:
@@ -776,70 +776,70 @@
- :name: repository_check:repository_check_batch
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: repository_check:repository_check_clear
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: repository_check:repository_check_single_repository
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: todos_destroyer:todos_destroyer_confidential_issue
:feature_category: :issue_tracking
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: todos_destroyer:todos_destroyer_entity_leave
:feature_category: :issue_tracking
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: todos_destroyer:todos_destroyer_group_private
:feature_category: :issue_tracking
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: todos_destroyer:todos_destroyer_private_features
:feature_category: :issue_tracking
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: todos_destroyer:todos_destroyer_project_private
:feature_category: :issue_tracking
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: update_namespace_statistics:namespaces_root_statistics
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: update_namespace_statistics:namespaces_schedule_aggregation
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
@@ -860,7 +860,7 @@
- :name: background_migration
:feature_category: :not_owned
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
@@ -874,21 +874,21 @@
- :name: create_commit_signature
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 2
:idempotent:
- :name: create_evidence
:feature_category: :release_evidence
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 2
:idempotent:
- :name: create_note_diff_file
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
@@ -902,35 +902,35 @@
- :name: delete_diff_files
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: delete_merged_branches
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: delete_stored_files
:feature_category: :not_owned
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: delete_user
:feature_category: :authentication_and_authorization
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: detect_repository_languages
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
@@ -951,35 +951,35 @@
- :name: error_tracking_issue_link
:feature_category: :error_tracking
:has_external_dependencies: true
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: expire_build_instance_artifacts
:feature_category: :continuous_integration
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: file_hook
:feature_category: :integrations
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: git_garbage_collect
:feature_category: :gitaly
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: github_import_advance_stage
:feature_category: :importers
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
@@ -993,42 +993,42 @@
- :name: group_destroy
:feature_category: :subgroups
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: group_export
:feature_category: :importers
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: group_import
:feature_category: :importers
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: import_issues_csv
:feature_category: :issue_tracking
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :cpu
:weight: 2
:idempotent:
- :name: invalid_gpg_signature_update
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 2
:idempotent:
- :name: irker
:feature_category: :integrations
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
@@ -1049,21 +1049,21 @@
- :name: merge_request_mergeability_check
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: migrate_external_diffs
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: namespaceless_project_destroy
:feature_category: :authentication_and_authorization
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
@@ -1091,28 +1091,28 @@
- :name: pages
:feature_category: :pages
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: pages_domain_ssl_renewal
:feature_category: :pages
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: pages_domain_verification
:feature_category: :pages
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: phabricator_import_import_tasks
:feature_category: :importers
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
@@ -1140,42 +1140,42 @@
- :name: project_daily_statistics
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: project_destroy
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: project_export
:feature_category: :importers
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :memory
:weight: 1
:idempotent:
- :name: project_service
:feature_category: :integrations
:has_external_dependencies: true
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: project_update_repository_storage
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: propagate_service_template
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
@@ -1189,77 +1189,77 @@
- :name: rebase
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 2
:idempotent:
- :name: remote_mirror_notification
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 2
:idempotent:
- :name: repository_cleanup
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: repository_fork
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: repository_import
:feature_category: :importers
:has_external_dependencies: true
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: repository_remove_remote
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: repository_update_remote_mirror
:feature_category: :source_code_management
:has_external_dependencies: true
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: self_monitoring_project_create
:feature_category: :metrics
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 2
:idempotent:
- :name: self_monitoring_project_delete
:feature_category: :metrics
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 2
:idempotent:
- :name: system_hook_push
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: update_external_pull_requests
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 3
:idempotent:
@@ -1273,21 +1273,21 @@
- :name: update_project_statistics
:feature_category: :source_code_management
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: upload_checksum
:feature_category: :geo_replication
:has_external_dependencies:
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
- :name: web_hook
:feature_category: :integrations
:has_external_dependencies: true
- :urgency: :default
+ :urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent:
diff --git a/app/workers/concerns/worker_attributes.rb b/app/workers/concerns/worker_attributes.rb
index 216f73b58e2..b60179531af 100644
--- a/app/workers/concerns/worker_attributes.rb
+++ b/app/workers/concerns/worker_attributes.rb
@@ -8,7 +8,7 @@ module WorkerAttributes
VALID_RESOURCE_BOUNDARIES = [:memory, :cpu, :unknown].freeze
# Urgencies that workers can declare through the `urgencies` attribute
- VALID_URGENCIES = [:high, :default, :none].freeze
+ VALID_URGENCIES = [:high, :low, :throttled].freeze
NAMESPACE_WEIGHTS = {
auto_devops: 2,
@@ -65,7 +65,7 @@ module WorkerAttributes
end
def get_urgency
- worker_attributes[:urgency] || :default
+ worker_attributes[:urgency] || :low
end
# Set this attribute on a job when it will call to services outside of the
diff --git a/app/workers/error_tracking_issue_link_worker.rb b/app/workers/error_tracking_issue_link_worker.rb
index d59abaf8683..9febd5cfecc 100644
--- a/app/workers/error_tracking_issue_link_worker.rb
+++ b/app/workers/error_tracking_issue_link_worker.rb
@@ -26,8 +26,8 @@ class ErrorTrackingIssueLinkWorker # rubocop:disable Scalability/IdempotentWorke
logger.info("Linking Sentry issue #{sentry_issue_id} to GitLab issue #{issue.id}")
sentry_client.create_issue_link(integration_id, sentry_issue_id, issue)
- rescue Sentry::Client::Error
- logger.info("Failed to link Sentry issue #{sentry_issue_id} to GitLab issue #{issue.id}")
+ rescue Sentry::Client::Error => e
+ logger.info("Failed to link Sentry issue #{sentry_issue_id} to GitLab issue #{issue.id} with error: #{e.message}")
end
end
diff --git a/app/workers/update_merge_requests_worker.rb b/app/workers/update_merge_requests_worker.rb
index 4c2a85d6642..63bb6171b9c 100644
--- a/app/workers/update_merge_requests_worker.rb
+++ b/app/workers/update_merge_requests_worker.rb
@@ -18,21 +18,7 @@ class UpdateMergeRequestsWorker # rubocop:disable Scalability/IdempotentWorker
user = User.find_by(id: user_id)
return unless user
- # TODO: remove this benchmarking when we have rich logging
- time = Benchmark.measure do
- MergeRequests::RefreshService.new(project, user).execute(oldrev, newrev, ref)
- end
-
- args_log = [
- "elapsed=#{time.real}",
- "project_id=#{project_id}",
- "user_id=#{user_id}",
- "oldrev=#{oldrev}",
- "newrev=#{newrev}",
- "ref=#{ref}"
- ].join(',')
-
- Rails.logger.info("UpdateMergeRequestsWorker#perform #{args_log}") if time.real > LOG_TIME_THRESHOLD # rubocop:disable Gitlab/RailsLogger
+ MergeRequests::RefreshService.new(project, user).execute(oldrev, newrev, ref)
end
# rubocop: enable CodeReuse/ActiveRecord
end
diff --git a/changelogs/unreleased/200107-avatar-content-type-does-not-match-file-extension.yml b/changelogs/unreleased/200107-avatar-content-type-does-not-match-file-extension.yml
new file mode 100644
index 00000000000..09ab5cd6e3b
--- /dev/null
+++ b/changelogs/unreleased/200107-avatar-content-type-does-not-match-file-extension.yml
@@ -0,0 +1,5 @@
+---
+title: Replace avatar and favicon upload type consistency validation with content whitelist validation
+merge_request: 25401
+author:
+type: changed
diff --git a/changelogs/unreleased/introduce_highest_role_per_user_database_table.yml b/changelogs/unreleased/introduce_highest_role_per_user_database_table.yml
new file mode 100644
index 00000000000..f3f7f5a3179
--- /dev/null
+++ b/changelogs/unreleased/introduce_highest_role_per_user_database_table.yml
@@ -0,0 +1,5 @@
+---
+title: Introduce database table for user highest roles
+merge_request: 26987
+author:
+type: added
diff --git a/config/locales/carrierwave.en.yml b/config/locales/carrierwave.en.yml
index 12619226460..864ec8fd73f 100644
--- a/config/locales/carrierwave.en.yml
+++ b/config/locales/carrierwave.en.yml
@@ -6,8 +6,8 @@ en:
carrierwave_download_error: could not be downloaded
extension_whitelist_error: "You are not allowed to upload %{extension} files, allowed types: %{allowed_types}"
extension_blacklist_error: "You are not allowed to upload %{extension} files, prohibited types: %{prohibited_types}"
- content_type_whitelist_error: "You are not allowed to upload %{content_type} files"
- content_type_blacklist_error: "You are not allowed to upload %{content_type} files"
+ content_type_whitelist_error: "file format is not supported. Please try one of the following supported formats: %{allowed_types}"
+ content_type_blacklist_error: "You are not allowed to upload %{content_type} files, prohibited types: %{allowed_types}"
rmagick_processing_error: "Failed to manipulate with rmagick, maybe it is not an image?"
mini_magick_processing_error: "Failed to manipulate with MiniMagick, maybe it is not an image? Original Error: %{e}"
min_size_error: "File size should be greater than %{min_size}"
diff --git a/db/migrate/20200311093210_create_user_highest_roles.rb b/db/migrate/20200311093210_create_user_highest_roles.rb
new file mode 100644
index 00000000000..36007f196d1
--- /dev/null
+++ b/db/migrate/20200311093210_create_user_highest_roles.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+class CreateUserHighestRoles < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def up
+ with_lock_retries do
+ create_table :user_highest_roles, id: false do |t|
+ t.datetime_with_timezone :updated_at, null: false
+ t.references :user, primary_key: true, default: nil, index: false, foreign_key: { on_delete: :cascade }
+ t.integer :highest_access_level
+
+ t.index [:user_id, :highest_access_level]
+ end
+ end
+ end
+
+ def down
+ with_lock_retries do
+ drop_table :user_highest_roles
+ end
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 4e885ce7dc2..8aad65e9b35 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -4251,6 +4251,12 @@ ActiveRecord::Schema.define(version: 2020_03_11_165635) do
t.index ["user_id"], name: "index_user_details_on_user_id", unique: true
end
+ create_table "user_highest_roles", primary_key: "user_id", id: :bigint, default: nil, force: :cascade do |t|
+ t.datetime_with_timezone "updated_at", null: false
+ t.integer "highest_access_level"
+ t.index ["user_id", "highest_access_level"], name: "index_user_highest_roles_on_user_id_and_highest_access_level"
+ end
+
create_table "user_interacted_projects", id: false, force: :cascade do |t|
t.integer "user_id", null: false
t.integer "project_id", null: false
@@ -5135,6 +5141,7 @@ ActiveRecord::Schema.define(version: 2020_03_11_165635) do
add_foreign_key "user_callouts", "users", on_delete: :cascade
add_foreign_key "user_custom_attributes", "users", on_delete: :cascade
add_foreign_key "user_details", "users", on_delete: :cascade
+ add_foreign_key "user_highest_roles", "users", on_delete: :cascade
add_foreign_key "user_interacted_projects", "projects", name: "fk_722ceba4f7", on_delete: :cascade
add_foreign_key "user_interacted_projects", "users", name: "fk_0894651f08", on_delete: :cascade
add_foreign_key "user_preferences", "users", on_delete: :cascade
diff --git a/doc/administration/high_availability/README.md b/doc/administration/high_availability/README.md
index b7ac9916ea3..af1f91a5bde 100644
--- a/doc/administration/high_availability/README.md
+++ b/doc/administration/high_availability/README.md
@@ -30,7 +30,7 @@ This configuration is supported in [GitLab Starter, Premium and Ultimate](https:
References:
-- [Installation Docs](../../install/README.html)
+- [Installation Docs](../../install/README.md)
- [Backup/Restore Docs](https://docs.gitlab.com/omnibus/settings/backups.html#backup-and-restore-omnibus-gitlab-configuration)
### Level 2: Multiple application servers
@@ -68,7 +68,7 @@ This configuration is supported in [GitLab Premium and Ultimate](https://about.g
References:
- [Geo Documentation](../../gitlab-geo/README.html)
-- [GitLab Geo with a highly available configuration](../geo/replication/high_availability.html)
+- [GitLab Geo with a highly available configuration](../geo/replication/high_availability.md)
## Recommended setups based on number of users
diff --git a/doc/administration/operations/extra_sidekiq_processes.md b/doc/administration/operations/extra_sidekiq_processes.md
index aeb366370f0..df2e4508eb8 100644
--- a/doc/administration/operations/extra_sidekiq_processes.md
+++ b/doc/administration/operations/extra_sidekiq_processes.md
@@ -130,7 +130,7 @@ following attributes:
- `has_external_dependencies` - whether or not the queue connects to external
services. For example, all importers have this set to `true`.
- `urgency` - how important it is that this queue's jobs run
- quickly. Can be `high`, `default`, or `none`. For example, the
+ quickly. Can be `high`, `low`, or `throttled`. For example, the
`authorized_projects` queue is used to refresh user permissions, and
is high urgency.
- `name` - the queue name. The other attributes are typically more useful as
diff --git a/doc/api/graphql/reference/gitlab_schema.graphql b/doc/api/graphql/reference/gitlab_schema.graphql
index b6caff283fc..652d2c7611d 100644
--- a/doc/api/graphql/reference/gitlab_schema.graphql
+++ b/doc/api/graphql/reference/gitlab_schema.graphql
@@ -3757,7 +3757,7 @@ input IssueSetConfidentialInput {
"""
The iid of the issue to mutate
"""
- iid: String!
+ iid: ID!
"""
The project the issue to mutate is in
@@ -3802,7 +3802,7 @@ input IssueSetDueDateInput {
"""
The iid of the issue to mutate
"""
- iid: String!
+ iid: ID!
"""
The project the issue to mutate is in
@@ -3842,7 +3842,7 @@ input IssueSetWeightInput {
"""
The iid of the issue to mutate
"""
- iid: String!
+ iid: ID!
"""
The project the issue to mutate is in
@@ -4150,7 +4150,7 @@ type MergeRequest implements Noteable {
"""
Internal ID of the merge request
"""
- iid: String!
+ iid: ID!
"""
Commit SHA of the merge request if merge is in progress
@@ -4550,7 +4550,7 @@ input MergeRequestSetAssigneesInput {
"""
The iid of the merge request to mutate
"""
- iid: String!
+ iid: ID!
"""
The operation to perform. Defaults to REPLACE.
@@ -4595,7 +4595,7 @@ input MergeRequestSetLabelsInput {
"""
The iid of the merge request to mutate
"""
- iid: String!
+ iid: ID!
"""
The Label IDs to set. Replaces existing labels by default.
@@ -4645,7 +4645,7 @@ input MergeRequestSetLockedInput {
"""
The iid of the merge request to mutate
"""
- iid: String!
+ iid: ID!
"""
Whether or not to lock the merge request.
@@ -4690,7 +4690,7 @@ input MergeRequestSetMilestoneInput {
"""
The iid of the merge request to mutate
"""
- iid: String!
+ iid: ID!
"""
The milestone to assign to the merge request.
@@ -4735,7 +4735,7 @@ input MergeRequestSetSubscriptionInput {
"""
The iid of the merge request to mutate
"""
- iid: String!
+ iid: ID!
"""
The project the merge request to mutate is in
@@ -4780,7 +4780,7 @@ input MergeRequestSetWipInput {
"""
The iid of the merge request to mutate
"""
- iid: String!
+ iid: ID!
"""
The project the merge request to mutate is in
@@ -5351,7 +5351,7 @@ type Pipeline {
"""
Internal ID of the pipeline
"""
- iid: String!
+ iid: ID!
"""
SHA of the pipeline's commit
@@ -5629,12 +5629,12 @@ type Project {
"""
IID of the issue. For example, "1"
"""
- iid: String
+ iid: ID
"""
List of IIDs of issues. For example, [1, 2]
"""
- iids: [String!]
+ iids: [ID!]
"""
Labels applied to this issue
@@ -5724,12 +5724,12 @@ type Project {
"""
IID of the issue. For example, "1"
"""
- iid: String
+ iid: ID
"""
List of IIDs of issues. For example, [1, 2]
"""
- iids: [String!]
+ iids: [ID!]
"""
Labels applied to this issue
@@ -5799,12 +5799,12 @@ type Project {
"""
The IID of the merge request, e.g., "1"
"""
- iid: String
+ iid: ID
"""
The list of IIDs of issues, e.g., [1, 2]
"""
- iids: [String!]
+ iids: [ID!]
): MergeRequest
"""
@@ -5829,12 +5829,12 @@ type Project {
"""
The IID of the merge request, e.g., "1"
"""
- iid: String
+ iid: ID
"""
The list of IIDs of issues, e.g., [1, 2]
"""
- iids: [String!]
+ iids: [ID!]
"""
Returns the last _n_ elements from the list.
@@ -8112,7 +8112,7 @@ input UpdateIssueInput {
"""
The iid of the issue to mutate
"""
- iid: String!
+ iid: ID!
"""
The project the issue to mutate is in
diff --git a/doc/api/graphql/reference/gitlab_schema.json b/doc/api/graphql/reference/gitlab_schema.json
index 3c0835a3605..81452c49398 100644
--- a/doc/api/graphql/reference/gitlab_schema.json
+++ b/doc/api/graphql/reference/gitlab_schema.json
@@ -702,7 +702,7 @@
"description": "IID of the issue. For example, \"1\"",
"type": {
"kind": "SCALAR",
- "name": "String",
+ "name": "ID",
"ofType": null
},
"defaultValue": null
@@ -718,7 +718,7 @@
"name": null,
"ofType": {
"kind": "SCALAR",
- "name": "String",
+ "name": "ID",
"ofType": null
}
}
@@ -881,7 +881,7 @@
"description": "IID of the issue. For example, \"1\"",
"type": {
"kind": "SCALAR",
- "name": "String",
+ "name": "ID",
"ofType": null
},
"defaultValue": null
@@ -897,7 +897,7 @@
"name": null,
"ofType": {
"kind": "SCALAR",
- "name": "String",
+ "name": "ID",
"ofType": null
}
}
@@ -1156,7 +1156,7 @@
"description": "The IID of the merge request, e.g., \"1\"",
"type": {
"kind": "SCALAR",
- "name": "String",
+ "name": "ID",
"ofType": null
},
"defaultValue": null
@@ -1172,7 +1172,7 @@
"name": null,
"ofType": {
"kind": "SCALAR",
- "name": "String",
+ "name": "ID",
"ofType": null
}
}
@@ -1197,7 +1197,7 @@
"description": "The IID of the merge request, e.g., \"1\"",
"type": {
"kind": "SCALAR",
- "name": "String",
+ "name": "ID",
"ofType": null
},
"defaultValue": null
@@ -1213,7 +1213,7 @@
"name": null,
"ofType": {
"kind": "SCALAR",
- "name": "String",
+ "name": "ID",
"ofType": null
}
}
@@ -14425,7 +14425,7 @@
"name": null,
"ofType": {
"kind": "SCALAR",
- "name": "String",
+ "name": "ID",
"ofType": null
}
},
@@ -16204,7 +16204,7 @@
"name": null,
"ofType": {
"kind": "SCALAR",
- "name": "String",
+ "name": "ID",
"ofType": null
}
},
@@ -20999,7 +20999,7 @@
"name": null,
"ofType": {
"kind": "SCALAR",
- "name": "String",
+ "name": "ID",
"ofType": null
}
},
@@ -21129,7 +21129,7 @@
"name": null,
"ofType": {
"kind": "SCALAR",
- "name": "String",
+ "name": "ID",
"ofType": null
}
},
@@ -21259,7 +21259,7 @@
"name": null,
"ofType": {
"kind": "SCALAR",
- "name": "String",
+ "name": "ID",
"ofType": null
}
},
@@ -21425,7 +21425,7 @@
"name": null,
"ofType": {
"kind": "SCALAR",
- "name": "String",
+ "name": "ID",
"ofType": null
}
},
@@ -21602,7 +21602,7 @@
"name": null,
"ofType": {
"kind": "SCALAR",
- "name": "String",
+ "name": "ID",
"ofType": null
}
},
@@ -21732,7 +21732,7 @@
"name": null,
"ofType": {
"kind": "SCALAR",
- "name": "String",
+ "name": "ID",
"ofType": null
}
},
@@ -21858,7 +21858,7 @@
"name": null,
"ofType": {
"kind": "SCALAR",
- "name": "String",
+ "name": "ID",
"ofType": null
}
},
@@ -21988,7 +21988,7 @@
"name": null,
"ofType": {
"kind": "SCALAR",
- "name": "String",
+ "name": "ID",
"ofType": null
}
},
@@ -22118,7 +22118,7 @@
"name": null,
"ofType": {
"kind": "SCALAR",
- "name": "String",
+ "name": "ID",
"ofType": null
}
},
@@ -24554,7 +24554,7 @@
"name": null,
"ofType": {
"kind": "SCALAR",
- "name": "String",
+ "name": "ID",
"ofType": null
}
},
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index a85553ce4aa..57a9c5d952a 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -630,7 +630,7 @@ Autogenerated return type of MarkAsSpamSnippet
| `forceRemoveSourceBranch` | Boolean | Indicates if the project settings will lead to source branch deletion after merge |
| `headPipeline` | Pipeline | The pipeline running on the branch HEAD of the merge request |
| `id` | ID! | ID of the merge request |
-| `iid` | String! | Internal ID of the merge request |
+| `iid` | ID! | Internal ID of the merge request |
| `inProgressMergeCommitSha` | String | Commit SHA of the merge request if merge is in progress |
| `mergeCommitMessage` **{warning-solid}** | String | **Deprecated:** Renamed to defaultMergeCommitMessage |
| `mergeCommitSha` | String | SHA of the merge request commit (set once merged) |
@@ -834,7 +834,7 @@ Information about pagination in a connection.
| `duration` | Int | Duration of the pipeline in seconds |
| `finishedAt` | Time | Timestamp of the pipeline's completion |
| `id` | ID! | ID of the pipeline |
-| `iid` | String! | Internal ID of the pipeline |
+| `iid` | ID! | Internal ID of the pipeline |
| `sha` | String! | SHA of the pipeline's commit |
| `startedAt` | Time | Timestamp when the pipeline was started |
| `status` | PipelineStatusEnum! | Status of the pipeline (CREATED, WAITING_FOR_RESOURCE, PREPARING, PENDING, RUNNING, FAILED, SUCCESS, CANCELED, SKIPPED, MANUAL, SCHEDULED) |
diff --git a/doc/development/api_graphql_styleguide.md b/doc/development/api_graphql_styleguide.md
index c0eb9c83e92..9c59a12bfb3 100644
--- a/doc/development/api_graphql_styleguide.md
+++ b/doc/development/api_graphql_styleguide.md
@@ -541,7 +541,7 @@ argument :project_path, GraphQL::ID_TYPE,
required: true,
description: "The project the merge request to mutate is in"
-argument :iid, GraphQL::STRING_TYPE,
+argument :iid, GraphQL::ID_TYPE,
required: true,
description: "The iid of the merge request to mutate"
diff --git a/doc/development/sidekiq_style_guide.md b/doc/development/sidekiq_style_guide.md
index 89a05f91a9e..1590c7a6d44 100644
--- a/doc/development/sidekiq_style_guide.md
+++ b/doc/development/sidekiq_style_guide.md
@@ -124,13 +124,13 @@ Consider skipping the cop if you're not confident your job can safely run multip
## Job urgency
Jobs can have an `urgency` attribute set, which can be `:high`,
-`:default`, or `:none`. These have the below targets:
+`:low`, or `:throttled`. These have the below targets:
-| **Urgency** | **Queue Scheduling Target** | **Execution Latency Requirement** |
-|-------------|-----------------------------|------------------------------------|
-| `:high` | 100 milliseconds | p50 of 1 second, p99 of 10 seconds |
-| `:default` | 1 minute | Maximum run time of 1 hour |
-| `:none` | None | Maximum run time of 1 hour |
+| **Urgency** | **Queue Scheduling Target** | **Execution Latency Requirement** |
+|--------------|-----------------------------|------------------------------------|
+| `:high` | 100 milliseconds | p50 of 1 second, p99 of 10 seconds |
+| `:low` | 1 minute | Maximum run time of 1 hour |
+| `:throttled` | None | Maximum run time of 1 hour |
To set a job's urgency, use the `urgency` class method:
@@ -175,7 +175,7 @@ these jobs also have very strict execution duration requirements:
If a worker cannot meet these expectations, then it cannot be treated as a
`urgency :high` worker: consider redesigning the worker, or splitting the
work between two different workers, one with `urgency :high` code that
-executes quickly, and the other with `urgency :default`, which has no
+executes quickly, and the other with `urgency :low`, which has no
execution latency requirements (but also has lower scheduling targets).
## Jobs with External Dependencies
diff --git a/lib/gitlab/ci/parsers/test/junit.rb b/lib/gitlab/ci/parsers/test/junit.rb
index 133eb16a83e..0ce901fa5aa 100644
--- a/lib/gitlab/ci/parsers/test/junit.rb
+++ b/lib/gitlab/ci/parsers/test/junit.rb
@@ -6,6 +6,7 @@ module Gitlab
module Test
class Junit
JunitParserError = Class.new(Gitlab::Ci::Parsers::ParserError)
+ ATTACHMENT_TAG_REGEX = /\[\[ATTACHMENT\|(?<path>.+?)\]\]/.freeze
def parse!(xml_data, test_suite)
root = Hash.from_xml(xml_data)
@@ -49,6 +50,7 @@ module Gitlab
if data['failure']
status = ::Gitlab::Ci::Reports::TestCase::STATUS_FAILED
system_output = data['failure']
+ attachment = attachment_path(data['system_out'])
elsif data['error']
status = ::Gitlab::Ci::Reports::TestCase::STATUS_ERROR
system_output = data['error']
@@ -63,9 +65,17 @@ module Gitlab
file: data['file'],
execution_time: data['time'],
status: status,
- system_output: system_output
+ system_output: system_output,
+ attachment: attachment
)
end
+
+ def attachment_path(data)
+ return unless data
+
+ matches = data.match(ATTACHMENT_TAG_REGEX)
+ matches[:path] if matches
+ end
end
end
end
diff --git a/lib/gitlab/ci/reports/test_case.rb b/lib/gitlab/ci/reports/test_case.rb
index fdeaad698b9..55856f64533 100644
--- a/lib/gitlab/ci/reports/test_case.rb
+++ b/lib/gitlab/ci/reports/test_case.rb
@@ -10,9 +10,9 @@ module Gitlab
STATUS_ERROR = 'error'
STATUS_TYPES = [STATUS_SUCCESS, STATUS_FAILED, STATUS_SKIPPED, STATUS_ERROR].freeze
- attr_reader :name, :classname, :execution_time, :status, :file, :system_output, :stack_trace, :key
+ attr_reader :name, :classname, :execution_time, :status, :file, :system_output, :stack_trace, :key, :attachment
- def initialize(name:, classname:, execution_time:, status:, file: nil, system_output: nil, stack_trace: nil)
+ def initialize(name:, classname:, execution_time:, status:, file: nil, system_output: nil, stack_trace: nil, attachment: nil)
@name = name
@classname = classname
@file = file
@@ -21,6 +21,11 @@ module Gitlab
@system_output = system_output
@stack_trace = stack_trace
@key = sanitize_key_name("#{classname}_#{name}")
+ @attachment = attachment
+ end
+
+ def has_attachment?
+ attachment.present?
end
private
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 3f578730eb8..a1fc488fcbd 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -3406,9 +3406,6 @@ msgstr ""
msgid "Changing group path can have unintended side effects."
msgstr ""
-msgid "Charts"
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -19917,10 +19914,10 @@ msgstr ""
msgid "There was an error fetching median data for stages"
msgstr ""
-msgid "There was an error fetching the Designs"
+msgid "There was an error fetching the Node's Groups"
msgstr ""
-msgid "There was an error fetching the Node's Groups"
+msgid "There was an error fetching the designs"
msgstr ""
msgid "There was an error fetching the environments information."
@@ -19965,7 +19962,7 @@ msgstr ""
msgid "There was an error subscribing to this label."
msgstr ""
-msgid "There was an error syncing the Design Repositories."
+msgid "There was an error syncing the designs."
msgstr ""
msgid "There was an error trying to validate your query"
diff --git a/qa/qa/page/group/menu.rb b/qa/qa/page/group/menu.rb
index 02dd72d51fd..380984c283e 100644
--- a/qa/qa/page/group/menu.rb
+++ b/qa/qa/page/group/menu.rb
@@ -10,7 +10,6 @@ module QA
element :group_settings_item
element :group_members_item
element :general_settings_link
- element :contribution_analytics_link
end
view 'app/views/layouts/nav/sidebar/_analytics_links.html.haml' do
diff --git a/spec/factories/ci/test_case.rb b/spec/factories/ci/test_case.rb
new file mode 100644
index 00000000000..8017111bcc7
--- /dev/null
+++ b/spec/factories/ci/test_case.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :test_case, class: 'Gitlab::Ci::Reports::TestCase' do
+ name { "test-1" }
+ classname { "trace" }
+ file { "spec/trace_spec.rb" }
+ execution_time { 1.23 }
+ status { "success" }
+ system_output { nil }
+ attachment { nil }
+
+ trait :with_attachment do
+ attachment { "some/path.png" }
+ end
+
+ skip_create
+
+ initialize_with do
+ new(
+ name: name,
+ classname: classname,
+ file: file,
+ execution_time: execution_time,
+ status: status,
+ system_output: system_output,
+ attachment: attachment
+ )
+ end
+ end
+end
diff --git a/spec/factories/user_highest_roles.rb b/spec/factories/user_highest_roles.rb
new file mode 100644
index 00000000000..2e3447348b7
--- /dev/null
+++ b/spec/factories/user_highest_roles.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :user_highest_role do
+ user
+ end
+end
diff --git a/spec/features/merge_request/user_creates_image_diff_notes_spec.rb b/spec/features/merge_request/user_creates_image_diff_notes_spec.rb
index e1b139c1b3b..cea9056cd93 100644
--- a/spec/features/merge_request/user_creates_image_diff_notes_spec.rb
+++ b/spec/features/merge_request/user_creates_image_diff_notes_spec.rb
@@ -230,7 +230,7 @@ describe 'Merge request > User creates image diff notes', :js do
it_behaves_like 'onion skin'
end
- describe 'swipe view' do
+ describe 'swipe view', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/209999' do
before do
switch_to_swipe_view
end
diff --git a/spec/features/projects/active_tabs_spec.rb b/spec/features/projects/active_tabs_spec.rb
index 69681da6b2a..815cf3b9c58 100644
--- a/spec/features/projects/active_tabs_spec.rb
+++ b/spec/features/projects/active_tabs_spec.rb
@@ -7,8 +7,6 @@ describe 'Project active tab' do
let(:project) { create(:project, :repository) }
before do
- stub_feature_flags(analytics_pages_under_project_analytics_sidebar: { enabled: false, thing: project })
-
project.add_maintainer(user)
sign_in(user)
end
@@ -45,7 +43,7 @@ describe 'Project active tab' do
it_behaves_like 'page has active tab', 'Repository'
- %w(Files Commits Graph Compare Charts Branches Tags).each do |sub_menu|
+ %w(Files Commits Graph Compare Branches Tags).each do |sub_menu|
context "on project Repository/#{sub_menu}" do
before do
click_tab(sub_menu)
@@ -124,29 +122,23 @@ describe 'Project active tab' do
end
end
- context 'when `analytics_pages_under_project_analytics_sidebar` feature flag is enabled' do
+ context 'on project Analytics' do
before do
- stub_feature_flags(analytics_pages_under_project_analytics_sidebar: { enabled: true, thing: project })
+ visit charts_project_graph_path(project, 'master')
end
- context 'on project Analytics' do
- before do
- visit charts_project_graph_path(project, 'master')
- end
+ context 'on project Analytics/Repository Analytics' do
+ it_behaves_like 'page has active tab', _('Analytics')
+ it_behaves_like 'page has active sub tab', _('Repository')
+ end
- context 'on project Analytics/Repository Analytics' do
- it_behaves_like 'page has active tab', _('Analytics')
- it_behaves_like 'page has active sub tab', _('Repository')
+ context 'on project Analytics/Cycle Analytics' do
+ before do
+ click_tab(_('CI / CD'))
end
- context 'on project Analytics/Cycle Analytics' do
- before do
- click_tab(_('CI / CD'))
- end
-
- it_behaves_like 'page has active tab', _('Analytics')
- it_behaves_like 'page has active sub tab', _('CI / CD')
- end
+ it_behaves_like 'page has active tab', _('Analytics')
+ it_behaves_like 'page has active sub tab', _('CI / CD')
end
end
end
diff --git a/spec/features/projects/user_uses_shortcuts_spec.rb b/spec/features/projects/user_uses_shortcuts_spec.rb
index 33c2e65633e..2d629ef538a 100644
--- a/spec/features/projects/user_uses_shortcuts_spec.rb
+++ b/spec/features/projects/user_uses_shortcuts_spec.rb
@@ -7,8 +7,6 @@ describe 'User uses shortcuts', :js do
let(:user) { create(:user) }
before do
- stub_feature_flags(analytics_pages_under_project_analytics_sidebar: { enabled: false, thing: project })
-
project.add_maintainer(user)
sign_in(user)
@@ -119,8 +117,8 @@ describe 'User uses shortcuts', :js do
find('body').native.send_key('g')
find('body').native.send_key('d')
- expect(page).to have_active_navigation('Repository')
- expect(page).to have_active_sub_navigation('Charts')
+ expect(page).to have_active_navigation(_('Analytics'))
+ expect(page).to have_active_sub_navigation(_('Repository'))
end
end
@@ -211,18 +209,4 @@ describe 'User uses shortcuts', :js do
expect(page).to have_active_navigation('Wiki')
end
end
-
- context 'when `analytics_pages_under_project_analytics_sidebar` feature flag is enabled' do
- before do
- stub_feature_flags(analytics_pages_under_project_analytics_sidebar: { enabled: true, thing: project })
- end
-
- it 'redirects to the repository charts page' do
- find('body').native.send_key('g')
- find('body').native.send_key('d')
-
- expect(page).to have_active_navigation(_('Analytics'))
- expect(page).to have_active_sub_navigation(_('Repository'))
- end
- end
end
diff --git a/spec/javascripts/projects/project_import_gitlab_project_spec.js b/spec/frontend/projects/project_import_gitlab_project_spec.js
index 3c94934699d..3c94934699d 100644
--- a/spec/javascripts/projects/project_import_gitlab_project_spec.js
+++ b/spec/frontend/projects/project_import_gitlab_project_spec.js
diff --git a/spec/javascripts/projects/project_new_spec.js b/spec/frontend/projects/project_new_spec.js
index 7c6ff90aff6..7c6ff90aff6 100644
--- a/spec/javascripts/projects/project_new_spec.js
+++ b/spec/frontend/projects/project_new_spec.js
diff --git a/spec/lib/gitlab/ci/parsers/test/junit_spec.rb b/spec/lib/gitlab/ci/parsers/test/junit_spec.rb
index b91cf1dd3ed..9a486c312d4 100644
--- a/spec/lib/gitlab/ci/parsers/test/junit_spec.rb
+++ b/spec/lib/gitlab/ci/parsers/test/junit_spec.rb
@@ -205,6 +205,75 @@ describe Gitlab::Ci::Parsers::Test::Junit do
end
end
+ context 'when data contains an attachment tag' do
+ let(:junit) do
+ <<~EOF
+ <testsuites>
+ <testsuite>
+ <testcase classname='Calculator' name='sumTest1' time='0.01'>
+ <failure>Some failure</failure>
+ <system-out>[[ATTACHMENT|some/path.png]]</system-out>
+ </testcase>
+ </testsuite>
+ </testsuites>
+ EOF
+ end
+
+ it 'add attachment to a test case' do
+ expect { subject }.not_to raise_error
+
+ expect(test_cases[0].has_attachment?).to be_truthy
+ expect(test_cases[0].attachment).to eq("some/path.png")
+ end
+ end
+
+ context 'when data contains multiple attachments tag' do
+ let(:junit) do
+ <<~EOF
+ <testsuites>
+ <testsuite>
+ <testcase classname='Calculator' name='sumTest1' time='0.01'>
+ <failure>Some failure</failure>
+ <system-out>
+ [[ATTACHMENT|some/path.png]]
+ [[ATTACHMENT|some/path.html]]
+ </system-out>
+ </testcase>
+ </testsuite>
+ </testsuites>
+ EOF
+ end
+
+ it 'adds the first match attachment to a test case' do
+ expect { subject }.not_to raise_error
+
+ expect(test_cases[0].has_attachment?).to be_truthy
+ expect(test_cases[0].attachment).to eq("some/path.png")
+ end
+ end
+
+ context 'when data does not match attachment tag regex' do
+ let(:junit) do
+ <<~EOF
+ <testsuites>
+ <testsuite>
+ <testcase classname='Calculator' name='sumTest1' time='0.01'>
+ <failure>Some failure</failure>
+ <system-out>[[attachment]some/path.png]]</system-out>
+ </testcase>
+ </testsuite>
+ </testsuites>
+ EOF
+ end
+
+ it 'does not add attachment to a test case' do
+ expect { subject }.not_to raise_error
+
+ expect(test_cases[0].has_attachment?).to be_falsy
+ expect(test_cases[0].attachment).to be_nil
+ end
+ end
+
private
def flattened_test_cases(test_suite)
diff --git a/spec/lib/gitlab/ci/reports/test_case_spec.rb b/spec/lib/gitlab/ci/reports/test_case_spec.rb
index 20c489ee94c..c13161f3e7c 100644
--- a/spec/lib/gitlab/ci/reports/test_case_spec.rb
+++ b/spec/lib/gitlab/ci/reports/test_case_spec.rb
@@ -88,5 +88,17 @@ describe Gitlab::Ci::Reports::TestCase do
expect { test_case }.to raise_error(ArgumentError)
end
end
+
+ context 'when attachment is present' do
+ let(:attachment_test_case) { build(:test_case, :with_attachment) }
+
+ it "initializes the attachment if present" do
+ expect(attachment_test_case.attachment).to eq("some/path.png")
+ end
+
+ it '#has_attachment?' do
+ expect(attachment_test_case.has_attachment?).to be_truthy
+ end
+ end
end
end
diff --git a/spec/lib/gitlab/sidekiq_config/cli_methods_spec.rb b/spec/lib/gitlab/sidekiq_config/cli_methods_spec.rb
index 8b93ef86eba..0aaff12f278 100644
--- a/spec/lib/gitlab/sidekiq_config/cli_methods_spec.rb
+++ b/spec/lib/gitlab/sidekiq_config/cli_methods_spec.rb
@@ -124,7 +124,7 @@ describe Gitlab::SidekiqConfig::CliMethods do
name: 'a',
feature_category: :category_a,
has_external_dependencies: false,
- urgency: :default,
+ urgency: :low,
resource_boundary: :cpu
},
{
@@ -145,7 +145,7 @@ describe Gitlab::SidekiqConfig::CliMethods do
name: 'c',
feature_category: :category_c,
has_external_dependencies: false,
- urgency: :none,
+ urgency: :throttled,
resource_boundary: :memory
}
]
@@ -168,9 +168,9 @@ describe Gitlab::SidekiqConfig::CliMethods do
# urgency
'urgency=high' | %w(a:2 b)
- 'urgency=default' | %w(a)
- 'urgency=high,default,none' | %w(a a:2 b c)
- 'urgency=default|urgency=none' | %w(a c)
+ 'urgency=low' | %w(a)
+ 'urgency=high,low,throttled' | %w(a a:2 b c)
+ 'urgency=low|urgency=throttled' | %w(a c)
'urgency!=high' | %w(a c)
# name
diff --git a/spec/lib/gitlab/sidekiq_config/worker_spec.rb b/spec/lib/gitlab/sidekiq_config/worker_spec.rb
index 71fafbf0656..817755e3507 100644
--- a/spec/lib/gitlab/sidekiq_config/worker_spec.rb
+++ b/spec/lib/gitlab/sidekiq_config/worker_spec.rb
@@ -88,7 +88,7 @@ describe Gitlab::SidekiqConfig::Worker do
attributes_a = {
feature_category: :source_code_management,
has_external_dependencies: false,
- urgency: :default,
+ urgency: :low,
resource_boundary: :memory,
weight: 2,
idempotent: true
diff --git a/spec/lib/gitlab/sidekiq_middleware/client_metrics_spec.rb b/spec/lib/gitlab/sidekiq_middleware/client_metrics_spec.rb
index 689c7e40727..59639409183 100644
--- a/spec/lib/gitlab/sidekiq_middleware/client_metrics_spec.rb
+++ b/spec/lib/gitlab/sidekiq_middleware/client_metrics_spec.rb
@@ -9,7 +9,7 @@ describe Gitlab::SidekiqMiddleware::ClientMetrics do
let(:queue) { :test }
let(:worker_class) { worker.class }
let(:job) { {} }
- let(:default_labels) { { queue: queue.to_s, boundary: "", external_dependencies: "no", feature_category: "", urgency: "default" } }
+ let(:default_labels) { { queue: queue.to_s, boundary: "", external_dependencies: "no", feature_category: "", urgency: "low" } }
shared_examples "a metrics client middleware" do
context "with mocked prometheus" do
@@ -80,8 +80,8 @@ describe Gitlab::SidekiqMiddleware::ClientMetrics do
context "no urgency" do
it_behaves_like "a metrics client middleware" do
- let(:urgency) { :none }
- let(:labels) { default_labels.merge(urgency: "none") }
+ let(:urgency) { :throttled }
+ let(:labels) { default_labels.merge(urgency: "throttled") }
end
end
diff --git a/spec/lib/gitlab/sidekiq_middleware/server_metrics_spec.rb b/spec/lib/gitlab/sidekiq_middleware/server_metrics_spec.rb
index d815534e873..23c5b59922b 100644
--- a/spec/lib/gitlab/sidekiq_middleware/server_metrics_spec.rb
+++ b/spec/lib/gitlab/sidekiq_middleware/server_metrics_spec.rb
@@ -11,7 +11,7 @@ describe Gitlab::SidekiqMiddleware::ServerMetrics do
let(:job) { {} }
let(:job_status) { :done }
let(:labels_with_job_status) { labels.merge(job_status: job_status.to_s) }
- let(:default_labels) { { queue: queue.to_s, boundary: "", external_dependencies: "no", feature_category: "", urgency: "default" } }
+ let(:default_labels) { { queue: queue.to_s, boundary: "", external_dependencies: "no", feature_category: "", urgency: "low" } }
shared_examples "a metrics middleware" do
context "with mocked prometheus" do
@@ -202,11 +202,11 @@ describe Gitlab::SidekiqMiddleware::ServerMetrics do
end
context "combined" do
- let(:urgency) { :none }
+ let(:urgency) { :throttled }
let(:external_dependencies) { true }
let(:resource_boundary) { :cpu }
let(:feature_category) { :authentication }
- let(:labels) { default_labels.merge(urgency: "none", external_dependencies: "yes", boundary: "cpu", feature_category: "authentication") }
+ let(:labels) { default_labels.merge(urgency: "throttled", external_dependencies: "yes", boundary: "cpu", feature_category: "authentication") }
it_behaves_like "a metrics middleware"
end
diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb
index 276fbc2cb54..78b93b303f7 100644
--- a/spec/models/namespace_spec.rb
+++ b/spec/models/namespace_spec.rb
@@ -201,6 +201,26 @@ describe Namespace do
expect(described_class.find_by_pages_host(host)).to eq(namespace)
end
+ context 'when there is non-top-level group with searched name' do
+ before do
+ create(:group, :nested, path: 'pages')
+ end
+
+ it 'ignores this group' do
+ host = "pages.#{Settings.pages.host.upcase}"
+
+ expect(described_class.find_by_pages_host(host)).to be_nil
+ end
+
+ it 'finds right top level group' do
+ group = create(:group, path: 'pages')
+
+ host = "pages.#{Settings.pages.host.upcase}"
+
+ expect(described_class.find_by_pages_host(host)).to eq(group)
+ end
+ end
+
it "returns no result if the provided host is not subdomain of the Pages host" do
create(:namespace, name: 'namespace.io')
host = "namespace.io"
diff --git a/spec/models/user_highest_role_spec.rb b/spec/models/user_highest_role_spec.rb
new file mode 100644
index 00000000000..5d31dae8339
--- /dev/null
+++ b/spec/models/user_highest_role_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe UserHighestRole do
+ describe 'associations' do
+ it { is_expected.to belong_to(:user).required }
+ end
+
+ describe 'validations' do
+ it { is_expected.to validate_inclusion_of(:highest_access_level).in_array([nil, *Gitlab::Access.all_values]) }
+ end
+end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 39a31801720..6303fe8a5bb 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -30,6 +30,7 @@ describe User, :do_not_mock_admin_mode do
it { is_expected.to have_one(:status) }
it { is_expected.to have_one(:max_access_level_membership) }
it { is_expected.to have_one(:user_detail) }
+ it { is_expected.to have_one(:user_highest_role) }
it { is_expected.to have_many(:snippets).dependent(:destroy) }
it { is_expected.to have_many(:members) }
it { is_expected.to have_many(:project_members) }
diff --git a/spec/requests/api/groups_spec.rb b/spec/requests/api/groups_spec.rb
index 7dfa239cd1e..54bb2e670da 100644
--- a/spec/requests/api/groups_spec.rb
+++ b/spec/requests/api/groups_spec.rb
@@ -48,7 +48,7 @@ describe API::Groups do
context 'when file format is not supported' do
let(:file_path) { 'spec/fixtures/doc_sample.txt' }
- let(:message) { 'file format is not supported. Please try one of the following supported formats: png, jpg, jpeg, gif, bmp, tiff, ico' }
+ let(:message) { 'file format is not supported. Please try one of the following supported formats: image/png, image/jpeg, image/gif, image/bmp, image/tiff, image/vnd.microsoft.icon' }
it_behaves_like 'invalid file upload request'
end
diff --git a/spec/support/shared_contexts/upload_type_check_shared_context.rb b/spec/support/shared_contexts/upload_type_check_shared_context.rb
index d29c498fd15..b0b569fe83f 100644
--- a/spec/support/shared_contexts/upload_type_check_shared_context.rb
+++ b/spec/support/shared_contexts/upload_type_check_shared_context.rb
@@ -20,6 +20,7 @@ RSpec.shared_context 'uploader with type check' do
end
end
+# This works with the UploadTypeCheck::Concern
RSpec.shared_context 'stubbed MimeMagic mime type detection' do
let(:mime_type) { '' }
let(:magic_mime) { mime_type }
@@ -31,3 +32,19 @@ RSpec.shared_context 'stubbed MimeMagic mime type detection' do
allow(MimeMagic).to receive(:by_path).with(anything).and_return(ext_mime_obj)
end
end
+
+# @param uploader [CarrierWave::Uploader::Base] uploader with extension_whitelist method.
+RSpec.shared_context 'ignore extension whitelist check' do
+ before do
+ allow(uploader).to receive(:extension_whitelist).and_return(nil)
+ end
+end
+
+# This works with a content_type_whitelist and content_type_blacklist type check.
+# @param mime_type [String] mime type to forcibly detect.
+RSpec.shared_context 'force content type detection to mime_type' do
+ before do
+ magic_mime_obj = MimeMagic.new(mime_type)
+ allow(MimeMagic).to receive(:by_magic).with(anything).and_return(magic_mime_obj)
+ end
+end
diff --git a/spec/support/shared_examples/uploaders/upload_type_shared_examples.rb b/spec/support/shared_examples/uploaders/upload_type_shared_examples.rb
index 6e5075e135d..99da2a14bb6 100644
--- a/spec/support/shared_examples/uploaders/upload_type_shared_examples.rb
+++ b/spec/support/shared_examples/uploaders/upload_type_shared_examples.rb
@@ -1,5 +1,32 @@
# frozen_string_literal: true
+# @param path [String] the path to file to upload. E.g. File.join('spec', 'fixtures', 'sanitized.svg')
+# @param uploader [CarrierWave::Uploader::Base] uploader to handle the upload.
+shared_examples 'denied carrierwave upload' do
+ it 'will deny upload' do
+ fixture_file = fixture_file_upload(path)
+ expect { uploader.cache!(fixture_file) }.to raise_exception(CarrierWave::IntegrityError)
+ end
+end
+
+# @param path [String] the path to file to upload. E.g. File.join('spec', 'fixtures', 'sanitized.svg')
+# @param uploader [CarrierWave::Uploader::Base] uploader to handle the upload.
+shared_examples 'accepted carrierwave upload' do
+ let(:fixture_file) { fixture_file_upload(path) }
+
+ before do
+ uploader.remove!
+ end
+
+ it 'will accept upload' do
+ expect { uploader.cache!(fixture_file) }.not_to raise_exception
+ end
+
+ it 'will cache uploaded file' do
+ expect { uploader.cache!(fixture_file) }.to change { uploader.file }.from(nil).to(kind_of(CarrierWave::SanitizedFile))
+ end
+end
+
def check_content_matches_extension!(file = double(read: nil, path: ''))
magic_file = UploadTypeCheck::MagicFile.new(file)
uploader.check_content_matches_extension!(magic_file)
diff --git a/spec/uploaders/avatar_uploader_spec.rb b/spec/uploaders/avatar_uploader_spec.rb
index 669f75b2ee8..142ee557afa 100644
--- a/spec/uploaders/avatar_uploader_spec.rb
+++ b/spec/uploaders/avatar_uploader_spec.rb
@@ -47,15 +47,29 @@ describe AvatarUploader do
end
end
- context 'upload type check' do
- AvatarUploader::SAFE_IMAGE_EXT.each do |ext|
- context "#{ext} extension" do
- it_behaves_like 'type checked uploads', filenames: "image.#{ext}"
- end
- end
+ context 'accept whitelist file content type' do
+ # We need to feed through a valid path, but we force the parsed mime type
+ # in a stub below so we can set any path.
+ let_it_be(:path) { File.join('spec', 'fixtures', 'video_sample.mp4') }
+
+ where(:mime_type) { described_class::MIME_WHITELIST }
+
+ with_them do
+ include_context 'force content type detection to mime_type'
- context 'skip image/svg+xml integrity check' do
- it_behaves_like 'skipped type checked uploads', filenames: 'image.svg'
+ it_behaves_like 'accepted carrierwave upload'
end
end
+
+ context 'upload non-whitelisted file content type' do
+ let_it_be(:path) { File.join('spec', 'fixtures', 'sanitized.svg') }
+
+ it_behaves_like 'denied carrierwave upload'
+ end
+
+ context 'upload misnamed non-whitelisted file content type' do
+ let_it_be(:path) { File.join('spec', 'fixtures', 'not_a_png.png') }
+
+ it_behaves_like 'denied carrierwave upload'
+ end
end
diff --git a/spec/uploaders/content_type_whitelist_spec.rb b/spec/uploaders/content_type_whitelist_spec.rb
new file mode 100644
index 00000000000..be519ead1c8
--- /dev/null
+++ b/spec/uploaders/content_type_whitelist_spec.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe ContentTypeWhitelist do
+ class DummyUploader < CarrierWave::Uploader::Base
+ include ContentTypeWhitelist::Concern
+
+ def content_type_whitelist
+ %w[image/png image/jpeg]
+ end
+ end
+
+ let_it_be(:model) { build_stubbed(:user) }
+ let_it_be(:uploader) { DummyUploader.new(model, :dummy) }
+
+ context 'upload whitelisted file content type' do
+ let(:path) { File.join('spec', 'fixtures', 'rails_sample.jpg') }
+
+ it_behaves_like 'accepted carrierwave upload'
+ end
+
+ context 'upload non-whitelisted file content type' do
+ let(:path) { File.join('spec', 'fixtures', 'sanitized.svg') }
+
+ it_behaves_like 'denied carrierwave upload'
+ end
+
+ context 'upload misnamed non-whitelisted file content type' do
+ let(:path) { File.join('spec', 'fixtures', 'not_a_png.png') }
+
+ it_behaves_like 'denied carrierwave upload'
+ end
+end
diff --git a/spec/uploaders/favicon_uploader_spec.rb b/spec/uploaders/favicon_uploader_spec.rb
index 4d6c849883a..0f5941b3f0a 100644
--- a/spec/uploaders/favicon_uploader_spec.rb
+++ b/spec/uploaders/favicon_uploader_spec.rb
@@ -6,19 +6,35 @@ describe FaviconUploader do
let_it_be(:model) { build_stubbed(:user) }
let_it_be(:uploader) { described_class.new(model, :favicon) }
- context 'upload type check' do
- FaviconUploader::EXTENSION_WHITELIST.each do |ext|
- context "#{ext} extension" do
- it_behaves_like 'type checked uploads', filenames: "image.#{ext}"
- end
+ context 'accept whitelist file content type' do
+ include_context 'ignore extension whitelist check'
+
+ # We need to feed through a valid path, but we force the parsed mime type
+ # in a stub below so we can set any path.
+ let_it_be(:path) { File.join('spec', 'fixtures', 'video_sample.mp4') }
+
+ where(:mime_type) { described_class::MIME_WHITELIST }
+
+ with_them do
+ include_context 'force content type detection to mime_type'
+
+ it_behaves_like 'accepted carrierwave upload'
end
end
- context 'upload non-whitelisted file extensions' do
- it 'will deny upload' do
- path = File.join('spec', 'fixtures', 'banana_sample.gif')
- fixture_file = fixture_file_upload(path)
- expect { uploader.cache!(fixture_file) }.to raise_exception(CarrierWave::IntegrityError)
- end
+ context 'upload non-whitelisted file content type' do
+ include_context 'ignore extension whitelist check'
+
+ let_it_be(:path) { File.join('spec', 'fixtures', 'sanitized.svg') }
+
+ it_behaves_like 'denied carrierwave upload'
+ end
+
+ context 'upload misnamed non-whitelisted file content type' do
+ include_context 'ignore extension whitelist check'
+
+ let_it_be(:path) { File.join('spec', 'fixtures', 'not_a_png.png') }
+
+ it_behaves_like 'denied carrierwave upload'
end
end
diff --git a/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb b/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb
index 3437839765d..cd622807c09 100644
--- a/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb
+++ b/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb
@@ -166,7 +166,6 @@ describe 'layouts/nav/sidebar/_project' do
before do
allow(view).to receive(:can?).with(nil, :read_cycle_analytics, project).and_return(read_cycle_analytics)
- stub_feature_flags(analytics_pages_under_project_analytics_sidebar: { enabled: false, thing: project })
end
describe 'when value stream analytics is enabled' do
diff --git a/spec/workers/update_merge_requests_worker_spec.rb b/spec/workers/update_merge_requests_worker_spec.rb
index 486dade454a..14a363f9d59 100644
--- a/spec/workers/update_merge_requests_worker_spec.rb
+++ b/spec/workers/update_merge_requests_worker_spec.rb
@@ -26,17 +26,5 @@ describe UpdateMergeRequestsWorker do
perform
end
-
- context 'when slow' do
- before do
- stub_const("UpdateMergeRequestsWorker::LOG_TIME_THRESHOLD", -1)
- end
-
- it 'logs debug info' do
- expect(Rails.logger).to receive(:info).with(a_string_matching(/\AUpdateMergeRequestsWorker#perform.*project_id=#{project.id},user_id=#{user.id},oldrev=#{oldrev},newrev=#{newrev},ref=#{ref}/))
-
- perform
- end
- end
end
end