Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.rubocop_todo/gitlab/namespaced_class.yml1
-rw-r--r--.rubocop_todo/layout/line_length.yml1
-rw-r--r--.rubocop_todo/naming/rescued_exceptions_variable_name.yml1
-rw-r--r--.rubocop_todo/style/string_concatenation.yml1
-rw-r--r--app/assets/javascripts/editor/schema/ci.json5
-rw-r--r--app/assets/javascripts/pipelines/components/graph/linked_pipeline.vue9
-rw-r--r--app/assets/javascripts/repository/components/blob_viewers/sketch_viewer.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/notes/skeleton_note.vue6
-rw-r--r--app/controllers/admin/users_controller.rb2
-rw-r--r--app/controllers/confirmations_controller.rb2
-rw-r--r--app/controllers/profiles/accounts_controller.rb2
-rw-r--r--app/controllers/profiles/active_sessions_controller.rb2
-rw-r--r--app/controllers/profiles_controller.rb5
-rw-r--r--app/controllers/users/terms_controller.rb2
-rw-r--r--app/controllers/users_controller.rb3
-rw-r--r--app/models/application_setting_implementation.rb27
-rw-r--r--app/models/concerns/cache_markdown_field.rb7
-rw-r--r--app/models/integration.rb6
-rw-r--r--app/services/issuable/clone/base_service.rb7
-rw-r--r--app/services/markdown_content_rewriter_service.rb62
-rw-r--r--app/services/members/approve_access_request_service.rb17
-rw-r--r--app/services/notes/copy_service.rb17
-rw-r--r--app/workers/all_queues.yml9
-rw-r--r--app/workers/integrations/execute_worker.rb27
-rw-r--r--app/workers/project_service_worker.rb21
-rw-r--r--config/feature_flags/development/rename_integrations_workers.yml8
-rw-r--r--config/routes.rb1
-rw-r--r--config/sidekiq_queues.yml2
-rw-r--r--data/deprecations/14-10-dependency-scanning-default-java-version.yml2
-rw-r--r--data/deprecations/14-10-old-search-migration-removal.yml2
-rw-r--r--data/deprecations/14-8-ci-build-variables.yml2
-rw-r--r--data/deprecations/14-8-compliance-required-pipeline-configuration-premium.yml2
-rw-r--r--data/deprecations/14-8-compliance-status-check-api-field.yml2
-rw-r--r--data/deprecations/14-8-request-profiling.yml2
-rw-r--r--data/deprecations/14-8-secure-ca-python-deprecation.yml2
-rw-r--r--data/deprecations/distribution_deprecations_14-4.yml2
-rw-r--r--db/migrate/20220525123825_add_raw_to_ci_pipeline_variables.rb9
-rw-r--r--db/migrate/20220525123851_add_raw_to_ci_group_variables.rb9
-rw-r--r--db/migrate/20220525123914_add_raw_to_ci_instance_variables.rb9
-rw-r--r--db/migrate/20220525123940_add_raw_to_ci_job_variables.rb9
-rw-r--r--db/migrate/20220525124104_add_raw_to_ci_pipeline_schedule_variables.rb9
-rw-r--r--db/migrate/20220525124125_add_raw_to_ci_variables.rb9
-rw-r--r--db/post_migrate/20220418180958_remove_integrations_properties.rb9
-rw-r--r--db/post_migrate/20220525141540_migrate_project_service_worker_queue.rb11
-rw-r--r--db/post_migrate/20220530170915_add_index_for_vulnerability_state_transition.rb19
-rw-r--r--db/post_migrate/20220601040233_finalize_backfill_issue_search_data.rb22
-rw-r--r--db/schema_migrations/202204181809581
-rw-r--r--db/schema_migrations/202205251238251
-rw-r--r--db/schema_migrations/202205251238511
-rw-r--r--db/schema_migrations/202205251239141
-rw-r--r--db/schema_migrations/202205251239401
-rw-r--r--db/schema_migrations/202205251241041
-rw-r--r--db/schema_migrations/202205251241251
-rw-r--r--db/schema_migrations/202205251415401
-rw-r--r--db/schema_migrations/202205301709151
-rw-r--r--db/schema_migrations/202206010402331
-rw-r--r--db/structure.sql17
-rw-r--r--doc/update/deprecations.md6
-rw-r--r--doc/user/permissions.md4
-rw-r--r--doc/user/project/integrations/slack.md2
-rw-r--r--doc/user/project/members/index.md5
-rw-r--r--lib/gitlab/gfm/reference_rewriter.rb21
-rw-r--r--lib/gitlab/gfm/uploads_rewriter.rb16
-rw-r--r--locale/gitlab.pot9
-rw-r--r--spec/controllers/admin/integrations_controller_spec.rb2
-rw-r--r--spec/controllers/groups/settings/integrations_controller_spec.rb2
-rw-r--r--spec/controllers/projects/import/jira_controller_spec.rb2
-rw-r--r--spec/controllers/projects/settings/integrations_controller_spec.rb2
-rw-r--r--spec/factories/application_settings.rb4
-rw-r--r--spec/features/projects/integrations/user_activates_jira_spec.rb2
-rw-r--r--spec/features/projects/integrations/user_uses_inherited_settings_spec.rb2
-rw-r--r--spec/frontend/notes/components/notes_app_spec.js2
-rw-r--r--spec/frontend/pipelines/graph/linked_pipeline_spec.js16
-rw-r--r--spec/lib/gitlab/background_migration/encrypt_integration_properties_spec.rb2
-rw-r--r--spec/lib/gitlab/gfm/reference_rewriter_spec.rb3
-rw-r--r--spec/lib/gitlab/gfm/uploads_rewriter_spec.rb22
-rw-r--r--spec/lib/gitlab/jira_import/base_importer_spec.rb2
-rw-r--r--spec/lib/gitlab/jira_import/issues_importer_spec.rb2
-rw-r--r--spec/lib/gitlab/jira_import/labels_importer_spec.rb2
-rw-r--r--spec/lib/gitlab/jira_import_spec.rb2
-rw-r--r--spec/models/application_setting_spec.rb40
-rw-r--r--spec/models/concerns/cache_markdown_field_spec.rb10
-rw-r--r--spec/models/integration_spec.rb42
-rw-r--r--spec/requests/api/graphql/mutations/jira_import/import_users_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/jira_import/start_spec.rb2
-rw-r--r--spec/services/bulk_create_integration_service_spec.rb2
-rw-r--r--spec/services/bulk_update_integration_service_spec.rb2
-rw-r--r--spec/services/git/branch_push_service_spec.rb2
-rw-r--r--spec/services/integrations/propagate_service_spec.rb2
-rw-r--r--spec/services/jira_import/start_import_service_spec.rb2
-rw-r--r--spec/services/jira_import/users_importer_spec.rb2
-rw-r--r--spec/services/markdown_content_rewriter_service_spec.rb83
-rw-r--r--spec/services/members/approve_access_request_service_spec.rb53
-rw-r--r--spec/services/merge_requests/merge_service_spec.rb2
-rw-r--r--spec/services/notes/copy_service_spec.rb28
-rw-r--r--spec/support/helpers/jira_integration_helpers.rb (renamed from spec/support/helpers/jira_service_helper.rb)20
-rw-r--r--spec/support/shared_contexts/features/integrations/integrations_shared_context.rb2
-rw-r--r--spec/support/shared_examples/models/application_setting_shared_examples.rb12
-rw-r--r--spec/support/shared_examples/services/alert_management_shared_examples.rb2
-rw-r--r--spec/workers/deployments/hooks_worker_spec.rb8
-rw-r--r--spec/workers/every_sidekiq_worker_spec.rb1
-rw-r--r--spec/workers/gitlab/jira_import/stage/import_issues_worker_spec.rb2
-rw-r--r--spec/workers/gitlab/jira_import/stage/import_labels_worker_spec.rb2
-rw-r--r--spec/workers/integrations/execute_worker_spec.rb (renamed from spec/workers/project_service_worker_spec.rb)24
104 files changed, 709 insertions, 183 deletions
diff --git a/.rubocop_todo/gitlab/namespaced_class.yml b/.rubocop_todo/gitlab/namespaced_class.yml
index eb333cbf058..36348324bd0 100644
--- a/.rubocop_todo/gitlab/namespaced_class.yml
+++ b/.rubocop_todo/gitlab/namespaced_class.yml
@@ -820,7 +820,6 @@ Gitlab/NamespacedClass:
- 'app/workers/project_daily_statistics_worker.rb'
- 'app/workers/project_destroy_worker.rb'
- 'app/workers/project_export_worker.rb'
- - 'app/workers/project_service_worker.rb'
- 'app/workers/propagate_integration_group_worker.rb'
- 'app/workers/propagate_integration_inherit_descendant_worker.rb'
- 'app/workers/propagate_integration_inherit_worker.rb'
diff --git a/.rubocop_todo/layout/line_length.yml b/.rubocop_todo/layout/line_length.yml
index e98fd267831..a8fd3dee6be 100644
--- a/.rubocop_todo/layout/line_length.yml
+++ b/.rubocop_todo/layout/line_length.yml
@@ -6216,7 +6216,6 @@ Layout/LineLength:
- 'spec/support/helpers/global_id_deprecation_helpers.rb'
- 'spec/support/helpers/graphql_helpers.rb'
- 'spec/support/helpers/javascript_fixtures_helpers.rb'
- - 'spec/support/helpers/jira_service_helper.rb'
- 'spec/support/helpers/kubernetes_helpers.rb'
- 'spec/support/helpers/lets_encrypt_helpers.rb'
- 'spec/support/helpers/live_debugger.rb'
diff --git a/.rubocop_todo/naming/rescued_exceptions_variable_name.yml b/.rubocop_todo/naming/rescued_exceptions_variable_name.yml
index 8d4d2da29ac..0e753a53dc3 100644
--- a/.rubocop_todo/naming/rescued_exceptions_variable_name.yml
+++ b/.rubocop_todo/naming/rescued_exceptions_variable_name.yml
@@ -86,7 +86,6 @@ Naming/RescuedExceptionsVariableName:
- 'app/workers/namespaces/schedule_aggregation_worker.rb'
- 'app/workers/packages/go/sync_packages_worker.rb'
- 'app/workers/project_destroy_worker.rb'
- - 'app/workers/project_service_worker.rb'
- 'app/workers/projects/git_garbage_collect_worker.rb'
- 'app/workers/remove_expired_members_worker.rb'
- 'app/workers/users/create_statistics_worker.rb'
diff --git a/.rubocop_todo/style/string_concatenation.yml b/.rubocop_todo/style/string_concatenation.yml
index 23a16f928f5..e21fecfb5e3 100644
--- a/.rubocop_todo/style/string_concatenation.yml
+++ b/.rubocop_todo/style/string_concatenation.yml
@@ -317,7 +317,6 @@ Style/StringConcatenation:
- 'spec/support/helpers/git_helpers.rb'
- 'spec/support/helpers/gitaly_setup.rb'
- 'spec/support/helpers/javascript_fixtures_helpers.rb'
- - 'spec/support/helpers/jira_service_helper.rb'
- 'spec/support/helpers/kubernetes_helpers.rb'
- 'spec/support/helpers/stub_configuration.rb'
- 'spec/support/helpers/workhorse_helpers.rb'
diff --git a/app/assets/javascripts/editor/schema/ci.json b/app/assets/javascripts/editor/schema/ci.json
index 7ea1db0b5ad..8262dae2b89 100644
--- a/app/assets/javascripts/editor/schema/ci.json
+++ b/app/assets/javascripts/editor/schema/ci.json
@@ -63,7 +63,10 @@
"rules": {
"type": "array",
"items": {
- "type": "object",
+ "anyOf": [
+ {"type": "object"},
+ {"type": "array", "minLength": 1, "items": { "type": "string" }}
+ ],
"properties": {
"if": { "$ref": "#/definitions/if" },
"changes": { "$ref": "#/definitions/changes" },
diff --git a/app/assets/javascripts/pipelines/components/graph/linked_pipeline.vue b/app/assets/javascripts/pipelines/components/graph/linked_pipeline.vue
index e46578acc18..119dc645f6d 100644
--- a/app/assets/javascripts/pipelines/components/graph/linked_pipeline.vue
+++ b/app/assets/javascripts/pipelines/components/graph/linked_pipeline.vue
@@ -107,6 +107,9 @@ export default {
}
return this.expanded ? 'angle-left' : 'angle-right';
},
+ expandBtnText() {
+ return this.expanded ? __('Collapse jobs') : __('Expand jobs');
+ },
childPipeline() {
return this.isDownstream && this.isSameProject;
},
@@ -161,7 +164,7 @@ export default {
return Boolean(this.action?.method && this.action?.icon && this.action?.ariaLabel);
},
showCardTooltip() {
- return !this.hasActionTooltip;
+ return !this.hasActionTooltip && !this.isExpandBtnFocus;
},
sourceJobName() {
return this.pipeline.sourceJob?.name ?? '';
@@ -284,10 +287,12 @@ export default {
<div class="gl-display-flex">
<gl-button
:id="buttonId"
+ v-gl-tooltip
+ :title="expandBtnText"
class="gl-border! gl-rounded-lg!"
:class="[`js-pipeline-expand-${pipeline.id}`, buttonBorderClasses, buttonShadowClass]"
:icon="expandedIcon"
- :aria-label="__('Expand pipeline')"
+ :aria-label="expandBtnText"
data-testid="expand-pipeline-button"
data-qa-selector="expand_linked_pipeline_button"
@mouseover="setExpandBtnActiveState(true)"
diff --git a/app/assets/javascripts/repository/components/blob_viewers/sketch_viewer.vue b/app/assets/javascripts/repository/components/blob_viewers/sketch_viewer.vue
index 32e24a9cc07..b48af02e541 100644
--- a/app/assets/javascripts/repository/components/blob_viewers/sketch_viewer.vue
+++ b/app/assets/javascripts/repository/components/blob_viewers/sketch_viewer.vue
@@ -26,6 +26,6 @@ export default {
<template>
<div ref="viewer" class="file-content" :data-endpoint="url" data-testid="sketch">
- <gl-loading-icon class="my-4 js-loading-icon" size="md" />
+ <gl-loading-icon class="my-4 js-loading-icon" size="lg" />
</div>
</template>
diff --git a/app/assets/javascripts/vue_shared/components/notes/skeleton_note.vue b/app/assets/javascripts/vue_shared/components/notes/skeleton_note.vue
index 3aca068c074..2206ae98c73 100644
--- a/app/assets/javascripts/vue_shared/components/notes/skeleton_note.vue
+++ b/app/assets/javascripts/vue_shared/components/notes/skeleton_note.vue
@@ -1,11 +1,11 @@
<script>
-import { GlDeprecatedSkeletonLoading as GlSkeletonLoading } from '@gitlab/ui';
+import { GlSkeletonLoader } from '@gitlab/ui';
import TimelineEntryItem from '~/vue_shared/components/notes/timeline_entry_item.vue';
export default {
name: 'SkeletonNote',
components: {
- GlSkeletonLoading,
+ GlSkeletonLoader,
TimelineEntryItem,
},
};
@@ -16,7 +16,7 @@ export default {
<div class="timeline-icon"></div>
<div class="timeline-content">
<div class="note-header"></div>
- <div class="note-body"><gl-skeleton-loading /></div>
+ <div class="note-body"><gl-skeleton-loader /></div>
</div>
</timeline-entry-item>
</template>
diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index 6b11b8eda5c..874eb8985fb 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -9,7 +9,7 @@ class Admin::UsersController < Admin::ApplicationController
before_action :ensure_destroy_prerequisites_met, only: [:destroy]
before_action :check_ban_user_feature_flag, only: [:ban]
- feature_category :users
+ feature_category :user_management
PAGINATION_WITH_COUNT_LIMIT = 1000
diff --git a/app/controllers/confirmations_controller.rb b/app/controllers/confirmations_controller.rb
index dd30d688fa8..704453fbf44 100644
--- a/app/controllers/confirmations_controller.rb
+++ b/app/controllers/confirmations_controller.rb
@@ -8,7 +8,7 @@ class ConfirmationsController < Devise::ConfirmationsController
prepend_before_action :check_recaptcha, only: :create
before_action :load_recaptcha, only: :new
- feature_category :users
+ feature_category :authentication_and_authorization
def almost_there
flash[:notice] = nil
diff --git a/app/controllers/profiles/accounts_controller.rb b/app/controllers/profiles/accounts_controller.rb
index 83eabbb736e..cb8b2783000 100644
--- a/app/controllers/profiles/accounts_controller.rb
+++ b/app/controllers/profiles/accounts_controller.rb
@@ -3,7 +3,7 @@
class Profiles::AccountsController < Profiles::ApplicationController
include AuthHelper
- feature_category :users
+ feature_category :authentication_and_authorization
urgency :low, [:show]
def show
diff --git a/app/controllers/profiles/active_sessions_controller.rb b/app/controllers/profiles/active_sessions_controller.rb
index aafd7c2b65b..2607ba7d404 100644
--- a/app/controllers/profiles/active_sessions_controller.rb
+++ b/app/controllers/profiles/active_sessions_controller.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
class Profiles::ActiveSessionsController < Profiles::ApplicationController
- feature_category :users
+ feature_category :authentication_and_authorization
def index
@sessions = ActiveSession.list(current_user).reject(&:is_impersonated)
diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb
index d5e7195a157..dd1ac526b89 100644
--- a/app/controllers/profiles_controller.rb
+++ b/app/controllers/profiles_controller.rb
@@ -14,7 +14,10 @@ class ProfilesController < Profiles::ApplicationController
push_frontend_feature_flag(:webauthn)
end
- feature_category :users
+ feature_category :users, [:show, :update, :reset_incoming_email_token, :reset_feed_token,
+ :reset_static_object_token, :update_username]
+
+ feature_category :authentication_and_authorization, [:audit_log]
urgency :low, [:show, :update]
def show
diff --git a/app/controllers/users/terms_controller.rb b/app/controllers/users/terms_controller.rb
index f0d95b56d33..f7eb2aad9dc 100644
--- a/app/controllers/users/terms_controller.rb
+++ b/app/controllers/users/terms_controller.rb
@@ -15,7 +15,7 @@ module Users
layout 'terms'
- feature_category :users
+ feature_category :user_management
def index
@redirect = redirect_path
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 37c4ffe2a5e..2799479d922 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -29,9 +29,10 @@ class UsersController < ApplicationController
feature_category :users, [:show, :activity, :groups, :projects, :contributed, :starred,
:followers, :following, :calendar, :calendar_activities,
- :exists, :activity, :follow, :unfollow, :ssh_keys, :gpg_keys]
+ :exists, :activity, :follow, :unfollow, :ssh_keys]
feature_category :snippets, [:snippets]
+ feature_category :source_code_management, [:gpg_keys]
# TODO: Set higher urgency after resolving https://gitlab.com/gitlab-org/gitlab/-/issues/357914
urgency :low, [:show, :calendar_activities, :contributed, :activity, :projects, :groups, :calendar]
diff --git a/app/models/application_setting_implementation.rb b/app/models/application_setting_implementation.rb
index 8ccd27f468b..a89ea05fb62 100644
--- a/app/models/application_setting_implementation.rb
+++ b/app/models/application_setting_implementation.rb
@@ -510,8 +510,35 @@ module ApplicationSettingImplementation
'https://sandbox-prod.gitlab-static.net'
end
+ def ensure_key_restrictions!
+ return if Gitlab::Database.read_only?
+ return unless Gitlab::FIPS.enabled?
+
+ Gitlab::SSHPublicKey.supported_types.each do |key_type|
+ set_max_key_restriction!(key_type)
+ end
+ end
+
private
+ def set_max_key_restriction!(key_type)
+ attr_name = "#{key_type}_key_restriction"
+ current = self.attributes[attr_name].to_i
+
+ return if current == KeyRestrictionValidator::FORBIDDEN
+
+ min_size = self.class.default_min_key_size(key_type)
+
+ new_value =
+ if min_size == KeyRestrictionValidator::FORBIDDEN
+ min_size
+ else
+ [min_size, current].max
+ end
+
+ self.assign_attributes({ attr_name => new_value })
+ end
+
def separate_allowlists(string_array)
string_array.reduce([[], []]) do |(ip_allowlist, domain_allowlist), string|
address, port = parse_addr_and_port(string)
diff --git a/app/models/concerns/cache_markdown_field.rb b/app/models/concerns/cache_markdown_field.rb
index 9414d16beef..99dbe464a7c 100644
--- a/app/models/concerns/cache_markdown_field.rb
+++ b/app/models/concerns/cache_markdown_field.rb
@@ -24,6 +24,9 @@ module CacheMarkdownField
true
end
+ attr_accessor :skip_markdown_cache_validation
+ alias_method :skip_markdown_cache_validation?, :skip_markdown_cache_validation
+
# Returns the default Banzai render context for the cached markdown field.
def banzai_render_context(field)
raise ArgumentError, "Unknown field: #{field.inspect}" unless
@@ -91,7 +94,7 @@ module CacheMarkdownField
end
def invalidated_markdown_cache?
- cached_markdown_fields.html_fields.any? {|html_field| attribute_invalidated?(html_field) }
+ cached_markdown_fields.html_fields.any? { |html_field| attribute_invalidated?(html_field) }
end
def attribute_invalidated?(attr)
@@ -218,6 +221,8 @@ module CacheMarkdownField
# The HTML becomes invalid if any dependent fields change. For now, assume
# author and project invalidate the cache in all circumstances.
define_method(invalidation_method) do
+ return false if skip_markdown_cache_validation?
+
changed_fields = changed_attributes.keys
invalidations = changed_fields & [markdown_field.to_s, *INVALIDATED_BY]
!invalidations.empty? || !cached_html_up_to_date?(markdown_field)
diff --git a/app/models/integration.rb b/app/models/integration.rb
index a16e8dc960a..316f2877059 100644
--- a/app/models/integration.rb
+++ b/app/models/integration.rb
@@ -576,7 +576,11 @@ class Integration < ApplicationRecord
def async_execute(data)
return unless supported_events.include?(data[:object_kind])
- ProjectServiceWorker.perform_async(id, data)
+ if Feature.enabled?(:rename_integrations_workers)
+ Integrations::ExecuteWorker.perform_async(id, data)
+ else
+ ProjectServiceWorker.perform_async(id, data)
+ end
end
# override if needed
diff --git a/app/services/issuable/clone/base_service.rb b/app/services/issuable/clone/base_service.rb
index 1d2c5c06d1b..ce9918a4b56 100644
--- a/app/services/issuable/clone/base_service.rb
+++ b/app/services/issuable/clone/base_service.rb
@@ -41,14 +41,15 @@ module Issuable
end
def update_new_entity_description
- rewritten_description = MarkdownContentRewriterService.new(
+ update_description_params = MarkdownContentRewriterService.new(
current_user,
- original_entity.description,
+ original_entity,
+ :description,
original_entity.project,
new_parent
).execute
- new_entity.update!(description: rewritten_description)
+ new_entity.update!(update_description_params)
end
def update_new_entity_attributes
diff --git a/app/services/markdown_content_rewriter_service.rb b/app/services/markdown_content_rewriter_service.rb
index bc6fd592eaa..4d8f523fa77 100644
--- a/app/services/markdown_content_rewriter_service.rb
+++ b/app/services/markdown_content_rewriter_service.rb
@@ -4,29 +4,69 @@
# which rewrite references to GitLab objects and uploads within the content
# based on their visibility by the `target_parent`.
class MarkdownContentRewriterService
- REWRITERS = [Gitlab::Gfm::ReferenceRewriter, Gitlab::Gfm::UploadsRewriter].freeze
+ include Gitlab::Utils::StrongMemoize
- def initialize(current_user, content, source_parent, target_parent)
- # See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/39654#note_399095117
- raise ArgumentError, 'The rewriter classes require that `source_parent` is a `Project`' \
- unless source_parent.is_a?(Project)
+ REWRITERS = [Gitlab::Gfm::ReferenceRewriter, Gitlab::Gfm::UploadsRewriter].freeze
+ def initialize(current_user, object, field, source_parent, target_parent)
@current_user = current_user
- @content = content.presence
@source_parent = source_parent
@target_parent = target_parent
+ @object = object
+ @field = field
+
+ validate_parameters!
+
+ @content = object[field].dup.presence
+ @html_field = object.cached_markdown_fields.html_field(field)
+ @content_html = object.cached_html_for(field)
+
+ @rewriters =
+ REWRITERS.map do |rewriter_class|
+ rewriter_class.new(@content, content_html, source_parent, current_user)
+ end
+
+ @result = {
+ field => nil,
+ html_field => nil
+ }.with_indifferent_access
end
def execute
- return unless content
+ return result unless content
- REWRITERS.inject(content) do |text, klass|
- rewriter = klass.new(text, source_parent, current_user)
- rewriter.rewrite(target_parent)
+ unless safe_to_copy_markdown?
+ rewriters.each do |rewriter|
+ rewriter.rewrite(target_parent)
+ end
+ end
+
+ result[field] = content
+ result[html_field] = content_html if safe_to_copy_markdown?
+ result[:skip_markdown_cache_validation] = safe_to_copy_markdown?
+
+ result
+ end
+
+ def safe_to_copy_markdown?
+ strong_memoize(:safe_to_copy_markdown) do
+ rewriters.none?(&:needs_rewrite?)
end
end
private
- attr_reader :current_user, :content, :source_parent, :target_parent
+ def validate_parameters!
+ # See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/39654#note_399095117
+ raise ArgumentError, 'The rewriter classes require that `source_parent` is a `Project`' \
+ unless source_parent.is_a?(Project)
+
+ if object.cached_markdown_fields[field].nil?
+ raise ArgumentError, 'The `field` attribute does not contain cached markdown'
+ end
+ end
+
+ attr_reader :current_user, :content, :source_parent,
+ :target_parent, :rewriters, :content_html,
+ :field, :html_field, :object, :result
end
diff --git a/app/services/members/approve_access_request_service.rb b/app/services/members/approve_access_request_service.rb
index 919c22894c1..5337279f702 100644
--- a/app/services/members/approve_access_request_service.rb
+++ b/app/services/members/approve_access_request_service.rb
@@ -3,7 +3,7 @@
module Members
class ApproveAccessRequestService < Members::BaseService
def execute(access_requester, skip_authorization: false, skip_log_audit_event: false)
- raise Gitlab::Access::AccessDeniedError unless skip_authorization || can_update_access_requester?(access_requester)
+ validate_access!(access_requester) unless skip_authorization
access_requester.access_level = params[:access_level] if params[:access_level]
access_requester.accept_request
@@ -15,9 +15,24 @@ module Members
private
+ def validate_access!(access_requester)
+ raise Gitlab::Access::AccessDeniedError unless can_update_access_requester?(access_requester)
+
+ if approving_member_with_owner_access_level?(access_requester) &&
+ cannot_assign_owner_responsibilities_to_member_in_project?(access_requester)
+ raise Gitlab::Access::AccessDeniedError
+ end
+ end
+
def can_update_access_requester?(access_requester)
can?(current_user, update_member_permission(access_requester), access_requester)
end
+
+ def approving_member_with_owner_access_level?(access_requester)
+ access_level_value = params[:access_level] || access_requester.access_level
+
+ access_level_value == Gitlab::Access::OWNER
+ end
end
end
diff --git a/app/services/notes/copy_service.rb b/app/services/notes/copy_service.rb
index 6e5b4596602..e7182350837 100644
--- a/app/services/notes/copy_service.rb
+++ b/app/services/notes/copy_service.rb
@@ -38,17 +38,16 @@ module Notes
def params_from_note(note, new_note)
new_discussion_ids[note.discussion_id] ||= Discussion.discussion_id(new_note)
- rewritten_note = MarkdownContentRewriterService.new(current_user, note.note, from_project, to_noteable.resource_parent).execute
- new_params = {
+ new_params = sanitized_note_params(note)
+
+ new_params.merge!(
project: to_noteable.project,
noteable: to_noteable,
discussion_id: new_discussion_ids[note.discussion_id],
- note: rewritten_note,
- note_html: nil,
created_at: note.created_at,
updated_at: note.updated_at
- }
+ )
if note.system_note_metadata
new_params[:system_note_metadata] = note.system_note_metadata.dup
@@ -61,6 +60,14 @@ module Notes
new_params
end
+ # Skip copying cached markdown HTML if text
+ # does not contain references or uploads.
+ def sanitized_note_params(note)
+ MarkdownContentRewriterService
+ .new(current_user, note, :note, from_project, to_noteable.resource_parent)
+ .execute
+ end
+
def copy_award_emoji(from_note, to_note)
AwardEmojis::CopyService.new(from_note, to_note).execute
end
diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml
index 87a621980c7..fe321c598aa 100644
--- a/app/workers/all_queues.yml
+++ b/app/workers/all_queues.yml
@@ -2371,6 +2371,15 @@
:weight: 1
:idempotent: true
:tags: []
+- :name: integrations_execute
+ :worker_name: Integrations::ExecuteWorker
+ :feature_category: :integrations
+ :has_external_dependencies: true
+ :urgency: :low
+ :resource_boundary: :unknown
+ :weight: 1
+ :idempotent:
+ :tags: []
- :name: invalid_gpg_signature_update
:worker_name: InvalidGpgSignatureUpdateWorker
:feature_category: :source_code_management
diff --git a/app/workers/integrations/execute_worker.rb b/app/workers/integrations/execute_worker.rb
new file mode 100644
index 00000000000..443f1d9fe8e
--- /dev/null
+++ b/app/workers/integrations/execute_worker.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+module Integrations
+ class ExecuteWorker # rubocop:disable Scalability/IdempotentWorker
+ include ApplicationWorker
+
+ data_consistency :always
+ sidekiq_options retry: 3
+ sidekiq_options dead: false
+ feature_category :integrations
+ urgency :low
+
+ worker_has_external_dependencies!
+
+ def perform(hook_id, data)
+ data = data.with_indifferent_access
+ integration = Integration.find_by_id(hook_id)
+ return unless integration
+
+ begin
+ integration.execute(data)
+ rescue StandardError => e
+ integration.log_exception(e)
+ end
+ end
+ end
+end
diff --git a/app/workers/project_service_worker.rb b/app/workers/project_service_worker.rb
index f73958a6ef9..f45eec0bcd9 100644
--- a/app/workers/project_service_worker.rb
+++ b/app/workers/project_service_worker.rb
@@ -1,8 +1,11 @@
# frozen_string_literal: true
-class ProjectServiceWorker # rubocop:disable Scalability/IdempotentWorker
- include ApplicationWorker
-
+# This worker was renamed in 15.1, we can delete it in 15.2.
+# See: https://gitlab.com/gitlab-org/gitlab/-/issues/364107
+#
+# rubocop: disable Gitlab/NamespacedClass
+# rubocop: disable Scalability/IdempotentWorker
+class ProjectServiceWorker < Integrations::ExecuteWorker
data_consistency :always
sidekiq_options retry: 3
sidekiq_options dead: false
@@ -10,16 +13,4 @@ class ProjectServiceWorker # rubocop:disable Scalability/IdempotentWorker
urgency :low
worker_has_external_dependencies!
-
- def perform(hook_id, data)
- data = data.with_indifferent_access
- integration = Integration.find_by_id(hook_id)
- return unless integration
-
- begin
- integration.execute(data)
- rescue StandardError => error
- integration.log_exception(error)
- end
- end
end
diff --git a/config/feature_flags/development/rename_integrations_workers.yml b/config/feature_flags/development/rename_integrations_workers.yml
new file mode 100644
index 00000000000..91f8f7f7166
--- /dev/null
+++ b/config/feature_flags/development/rename_integrations_workers.yml
@@ -0,0 +1,8 @@
+---
+name: rename_integrations_workers
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/88558
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/364112
+milestone: '15.1'
+type: development
+group: group::integrations
+default_enabled: false
diff --git a/config/routes.rb b/config/routes.rb
index 2eb7ece9a95..44e89f0d387 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -109,6 +109,7 @@ Rails.application.routes.draw do
get '/autocomplete/project_groups' => 'autocomplete#project_groups'
get '/autocomplete/project_routes' => 'autocomplete#project_routes'
get '/autocomplete/namespace_routes' => 'autocomplete#namespace_routes'
+ get '/autocomplete/group_subgroups' => 'autocomplete#group_subgroups'
end
# sandbox
diff --git a/config/sidekiq_queues.yml b/config/sidekiq_queues.yml
index 9f2eede1c47..1ffc9d97a0e 100644
--- a/config/sidekiq_queues.yml
+++ b/config/sidekiq_queues.yml
@@ -223,6 +223,8 @@
- 1
- - integrations_create_external_cross_reference
- 1
+- - integrations_execute
+ - 1
- - invalid_gpg_signature_update
- 2
- - irker
diff --git a/data/deprecations/14-10-dependency-scanning-default-java-version.yml b/data/deprecations/14-10-dependency-scanning-default-java-version.yml
index c589f2bb3ac..1717c452891 100644
--- a/data/deprecations/14-10-dependency-scanning-default-java-version.yml
+++ b/data/deprecations/14-10-dependency-scanning-default-java-version.yml
@@ -2,7 +2,7 @@
announcement_milestone: "14.10"
announcement_date: "2022-04-22"
removal_milestone: "15.0"
- removal_date: "2021-05-22"
+ removal_date: "2022-05-22"
breaking_change: true
reporter: NicoleSchwartz
body: |
diff --git a/data/deprecations/14-10-old-search-migration-removal.yml b/data/deprecations/14-10-old-search-migration-removal.yml
index d7036150059..a0074c53ffb 100644
--- a/data/deprecations/14-10-old-search-migration-removal.yml
+++ b/data/deprecations/14-10-old-search-migration-removal.yml
@@ -2,7 +2,7 @@
announcement_milestone: "14.10"
announcement_date: "2021-04-22"
removal_milestone: "15.0"
- removal_date: "2021-05-22"
+ removal_date: "2022-05-22"
breaking_change: true
body: |
As Advanced Search migrations usually require support multiple code paths for a long period of time, it’s important to clean those up when we safely can. We use GitLab major version upgrades as a safe time to remove backward compatibility for indices that have not been fully migrated. See the [upgrade documentation](https://docs.gitlab.com/ee/update/index.html#upgrading-to-a-new-major-version) for details.
diff --git a/data/deprecations/14-8-ci-build-variables.yml b/data/deprecations/14-8-ci-build-variables.yml
index a87c6a2fa17..dba841841f2 100644
--- a/data/deprecations/14-8-ci-build-variables.yml
+++ b/data/deprecations/14-8-ci-build-variables.yml
@@ -1,6 +1,6 @@
- name: "`CI_BUILD_*` predefined variables"
announcement_milestone: "14.8"
- announcement_date: "2021-02-22"
+ announcement_date: "2022-02-22"
removal_milestone: "16.0"
removal_date: "2023-04-22"
breaking_change: true
diff --git a/data/deprecations/14-8-compliance-required-pipeline-configuration-premium.yml b/data/deprecations/14-8-compliance-required-pipeline-configuration-premium.yml
index 104dbc5f72d..aabd330d567 100644
--- a/data/deprecations/14-8-compliance-required-pipeline-configuration-premium.yml
+++ b/data/deprecations/14-8-compliance-required-pipeline-configuration-premium.yml
@@ -1,6 +1,6 @@
- name: "Required pipeline configurations in Premium tier"
announcement_milestone: "14.8"
- announcement_date: "2021-02-22"
+ announcement_date: "2022-02-22"
removal_milestone: "15.0"
removal_date: "2022-05-22"
breaking_change: true
diff --git a/data/deprecations/14-8-compliance-status-check-api-field.yml b/data/deprecations/14-8-compliance-status-check-api-field.yml
index b98dab9e905..ba8c84343bd 100644
--- a/data/deprecations/14-8-compliance-status-check-api-field.yml
+++ b/data/deprecations/14-8-compliance-status-check-api-field.yml
@@ -1,6 +1,6 @@
- name: "External status check API breaking changes"
announcement_milestone: "14.8"
- announcement_date: "2021-02-22"
+ announcement_date: "2022-02-22"
removal_milestone: "15.0"
removal_date: "2022-05-22"
breaking_change: true
diff --git a/data/deprecations/14-8-request-profiling.yml b/data/deprecations/14-8-request-profiling.yml
index 82d2aadd149..ea3833d98ef 100644
--- a/data/deprecations/14-8-request-profiling.yml
+++ b/data/deprecations/14-8-request-profiling.yml
@@ -1,6 +1,6 @@
- name: "Request profiling"
announcement_milestone: "14.8"
- announcement_date: "2021-02-22"
+ announcement_date: "2022-02-22"
removal_milestone: "15.0"
removal_date: "2022-05-22"
breaking_change: true
diff --git a/data/deprecations/14-8-secure-ca-python-deprecation.yml b/data/deprecations/14-8-secure-ca-python-deprecation.yml
index c97271e4db2..21b3b01a590 100644
--- a/data/deprecations/14-8-secure-ca-python-deprecation.yml
+++ b/data/deprecations/14-8-secure-ca-python-deprecation.yml
@@ -2,7 +2,7 @@
announcement_milestone: "14.8" # The milestone when this feature was first announced as deprecated.
announcement_date: "2021-02-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: "2021-05-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_date: "2022-05-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
breaking_change: true # If this deprecation is a breaking change, set this value to true
body: | # Do not modify this line, instead modify the lines below.
For those using Dependency Scanning for Python projects, we are deprecating the default `gemnasium-python:2` image which uses Python 3.6 as well as the custom `gemnasium-python:2-python-3.9` image which uses Python 3.9. The new default image as of GitLab 15.0 will be for Python 3.9 as it is a [supported version](https://endoflife.date/python) and 3.6 [is no longer supported](https://endoflife.date/python).
diff --git a/data/deprecations/distribution_deprecations_14-4.yml b/data/deprecations/distribution_deprecations_14-4.yml
index 5b7163d5b4d..e54108d2947 100644
--- a/data/deprecations/distribution_deprecations_14-4.yml
+++ b/data/deprecations/distribution_deprecations_14-4.yml
@@ -1,6 +1,6 @@
- name: "Move `custom_hooks_dir` setting from GitLab Shell to Gitaly" # The name of the feature to be deprecated
announcement_milestone: "14.9" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2021-10-22"
+ announcement_date: "2022-03-22"
removal_milestone: "15.0" # the milestone when this feature is planned to be removed
removal_date: "2022-05-22"
body: | # Do not modify this line, instead modify the lines below.
diff --git a/db/migrate/20220525123825_add_raw_to_ci_pipeline_variables.rb b/db/migrate/20220525123825_add_raw_to_ci_pipeline_variables.rb
new file mode 100644
index 00000000000..258b4631643
--- /dev/null
+++ b/db/migrate/20220525123825_add_raw_to_ci_pipeline_variables.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddRawToCiPipelineVariables < Gitlab::Database::Migration[2.0]
+ enable_lock_retries!
+
+ def change
+ add_column :ci_pipeline_variables, :raw, :boolean, null: false, default: true
+ end
+end
diff --git a/db/migrate/20220525123851_add_raw_to_ci_group_variables.rb b/db/migrate/20220525123851_add_raw_to_ci_group_variables.rb
new file mode 100644
index 00000000000..9eae210d8c3
--- /dev/null
+++ b/db/migrate/20220525123851_add_raw_to_ci_group_variables.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddRawToCiGroupVariables < Gitlab::Database::Migration[2.0]
+ enable_lock_retries!
+
+ def change
+ add_column :ci_group_variables, :raw, :boolean, null: false, default: true
+ end
+end
diff --git a/db/migrate/20220525123914_add_raw_to_ci_instance_variables.rb b/db/migrate/20220525123914_add_raw_to_ci_instance_variables.rb
new file mode 100644
index 00000000000..71674b48e39
--- /dev/null
+++ b/db/migrate/20220525123914_add_raw_to_ci_instance_variables.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddRawToCiInstanceVariables < Gitlab::Database::Migration[2.0]
+ enable_lock_retries!
+
+ def change
+ add_column :ci_instance_variables, :raw, :boolean, null: false, default: true
+ end
+end
diff --git a/db/migrate/20220525123940_add_raw_to_ci_job_variables.rb b/db/migrate/20220525123940_add_raw_to_ci_job_variables.rb
new file mode 100644
index 00000000000..abd1f1eb211
--- /dev/null
+++ b/db/migrate/20220525123940_add_raw_to_ci_job_variables.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddRawToCiJobVariables < Gitlab::Database::Migration[2.0]
+ enable_lock_retries!
+
+ def change
+ add_column :ci_job_variables, :raw, :boolean, null: false, default: true
+ end
+end
diff --git a/db/migrate/20220525124104_add_raw_to_ci_pipeline_schedule_variables.rb b/db/migrate/20220525124104_add_raw_to_ci_pipeline_schedule_variables.rb
new file mode 100644
index 00000000000..c7a3b832552
--- /dev/null
+++ b/db/migrate/20220525124104_add_raw_to_ci_pipeline_schedule_variables.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddRawToCiPipelineScheduleVariables < Gitlab::Database::Migration[2.0]
+ enable_lock_retries!
+
+ def change
+ add_column :ci_pipeline_schedule_variables, :raw, :boolean, null: false, default: true
+ end
+end
diff --git a/db/migrate/20220525124125_add_raw_to_ci_variables.rb b/db/migrate/20220525124125_add_raw_to_ci_variables.rb
new file mode 100644
index 00000000000..168cd107d1c
--- /dev/null
+++ b/db/migrate/20220525124125_add_raw_to_ci_variables.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddRawToCiVariables < Gitlab::Database::Migration[2.0]
+ enable_lock_retries!
+
+ def change
+ add_column :ci_variables, :raw, :boolean, null: false, default: true
+ end
+end
diff --git a/db/post_migrate/20220418180958_remove_integrations_properties.rb b/db/post_migrate/20220418180958_remove_integrations_properties.rb
new file mode 100644
index 00000000000..781b8c8ac72
--- /dev/null
+++ b/db/post_migrate/20220418180958_remove_integrations_properties.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class RemoveIntegrationsProperties < Gitlab::Database::Migration[2.0]
+ disable_ddl_transaction!
+
+ def change
+ remove_column :integrations, :properties, :text
+ end
+end
diff --git a/db/post_migrate/20220525141540_migrate_project_service_worker_queue.rb b/db/post_migrate/20220525141540_migrate_project_service_worker_queue.rb
new file mode 100644
index 00000000000..acfb8b227fe
--- /dev/null
+++ b/db/post_migrate/20220525141540_migrate_project_service_worker_queue.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class MigrateProjectServiceWorkerQueue < Gitlab::Database::Migration[2.0]
+ def up
+ sidekiq_queue_migrate 'project_service', to: 'integrations_execute'
+ end
+
+ def down
+ sidekiq_queue_migrate 'integrations_execute', to: 'project_service'
+ end
+end
diff --git a/db/post_migrate/20220530170915_add_index_for_vulnerability_state_transition.rb b/db/post_migrate/20220530170915_add_index_for_vulnerability_state_transition.rb
new file mode 100644
index 00000000000..46ff79c2441
--- /dev/null
+++ b/db/post_migrate/20220530170915_add_index_for_vulnerability_state_transition.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddIndexForVulnerabilityStateTransition < Gitlab::Database::Migration[2.0]
+ disable_ddl_transaction!
+ NEW_INDEX_NAME = 'index_vulnerability_state_transitions_id_and_vulnerability_id'
+ OLD_INDEX_NAME = 'index_vulnerability_state_transitions_on_vulnerability_id'
+
+ def up
+ add_concurrent_index(:vulnerability_state_transitions, [:vulnerability_id, :id], name: NEW_INDEX_NAME)
+
+ remove_concurrent_index_by_name(:vulnerability_state_transitions, OLD_INDEX_NAME)
+ end
+
+ def down
+ remove_concurrent_index_by_name(:vulnerability_state_transitions, NEW_INDEX_NAME)
+
+ add_concurrent_index(:vulnerability_state_transitions, [:vulnerability_id], name: OLD_INDEX_NAME)
+ end
+end
diff --git a/db/post_migrate/20220601040233_finalize_backfill_issue_search_data.rb b/db/post_migrate/20220601040233_finalize_backfill_issue_search_data.rb
new file mode 100644
index 00000000000..7b5cd405fa8
--- /dev/null
+++ b/db/post_migrate/20220601040233_finalize_backfill_issue_search_data.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+class FinalizeBackfillIssueSearchData < Gitlab::Database::Migration[2.0]
+ MIGRATION = 'BackfillIssueSearchData'
+ disable_ddl_transaction!
+
+ restrict_gitlab_migration gitlab_schema: :gitlab_main
+
+ def up
+ ensure_batched_background_migration_is_finished(
+ job_class_name: MIGRATION,
+ table_name: :issues,
+ column_name: :id,
+ job_arguments: [],
+ finalize: true
+ )
+ end
+
+ def down
+ # no-op
+ end
+end
diff --git a/db/schema_migrations/20220418180958 b/db/schema_migrations/20220418180958
new file mode 100644
index 00000000000..74aaa9c2f46
--- /dev/null
+++ b/db/schema_migrations/20220418180958
@@ -0,0 +1 @@
+0108fa3b92704107f712552b51eb3addd53f1482db4866a3b8ccaba2a52239ba \ No newline at end of file
diff --git a/db/schema_migrations/20220525123825 b/db/schema_migrations/20220525123825
new file mode 100644
index 00000000000..47d4bc2c8a3
--- /dev/null
+++ b/db/schema_migrations/20220525123825
@@ -0,0 +1 @@
+8a30ec71e2c28929e0a7ebf744941246e460c37745e60dcd9f13a94b7d005772 \ No newline at end of file
diff --git a/db/schema_migrations/20220525123851 b/db/schema_migrations/20220525123851
new file mode 100644
index 00000000000..fd16775f784
--- /dev/null
+++ b/db/schema_migrations/20220525123851
@@ -0,0 +1 @@
+f6fcea6f6beef6c2d4848bd4bc11f0854acc9e19771438778f763171e0eaa3c7 \ No newline at end of file
diff --git a/db/schema_migrations/20220525123914 b/db/schema_migrations/20220525123914
new file mode 100644
index 00000000000..564ceb0dbe2
--- /dev/null
+++ b/db/schema_migrations/20220525123914
@@ -0,0 +1 @@
+504e43ab17c644707c65e396b8aa88a11472372a9c3b8d2b9ef88b9de978b0c3 \ No newline at end of file
diff --git a/db/schema_migrations/20220525123940 b/db/schema_migrations/20220525123940
new file mode 100644
index 00000000000..7bb5b598247
--- /dev/null
+++ b/db/schema_migrations/20220525123940
@@ -0,0 +1 @@
+7ddd1f03efe86f45b6105c6b0816e28e318e9de219dcd38801a11451745ae5f9 \ No newline at end of file
diff --git a/db/schema_migrations/20220525124104 b/db/schema_migrations/20220525124104
new file mode 100644
index 00000000000..229fb6ae2a6
--- /dev/null
+++ b/db/schema_migrations/20220525124104
@@ -0,0 +1 @@
+8c1ccabb6d2b3054398a015836bb9fe06f28936625f7a8220b4c58000a891b8a \ No newline at end of file
diff --git a/db/schema_migrations/20220525124125 b/db/schema_migrations/20220525124125
new file mode 100644
index 00000000000..8ccc434a7ac
--- /dev/null
+++ b/db/schema_migrations/20220525124125
@@ -0,0 +1 @@
+5e9f67479903590d5118e04811bc3c4aacf92fd11b90efa011975d4292dd0207 \ No newline at end of file
diff --git a/db/schema_migrations/20220525141540 b/db/schema_migrations/20220525141540
new file mode 100644
index 00000000000..5d44edb76dd
--- /dev/null
+++ b/db/schema_migrations/20220525141540
@@ -0,0 +1 @@
+ecb575072a1176378b180e95090915b191792ce350df84c6a0c198dfb816df96 \ No newline at end of file
diff --git a/db/schema_migrations/20220530170915 b/db/schema_migrations/20220530170915
new file mode 100644
index 00000000000..9fa7d0128a2
--- /dev/null
+++ b/db/schema_migrations/20220530170915
@@ -0,0 +1 @@
+6182d4a468348076aab761714990dd55f69f44a5fafcf566fd11b73486c7d656 \ No newline at end of file
diff --git a/db/schema_migrations/20220601040233 b/db/schema_migrations/20220601040233
new file mode 100644
index 00000000000..5acfd2851ca
--- /dev/null
+++ b/db/schema_migrations/20220601040233
@@ -0,0 +1 @@
+d7e3650b7f83a324c6c7f8da0ec37096c0e538072ab8fd0ac00672fa02e92c77 \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 5f7a15891d9..8dce81b5e1c 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -12534,6 +12534,7 @@ CREATE TABLE ci_group_variables (
masked boolean DEFAULT false NOT NULL,
variable_type smallint DEFAULT 1 NOT NULL,
environment_scope text DEFAULT '*'::text NOT NULL,
+ raw boolean DEFAULT true NOT NULL,
CONSTRAINT check_dfe009485a CHECK ((char_length(environment_scope) <= 255))
);
@@ -12554,6 +12555,7 @@ CREATE TABLE ci_instance_variables (
key text NOT NULL,
encrypted_value text,
encrypted_value_iv text,
+ raw boolean DEFAULT true NOT NULL,
CONSTRAINT check_07a45a5bcb CHECK ((char_length(encrypted_value_iv) <= 255)),
CONSTRAINT check_5aede12208 CHECK ((char_length(key) <= 255)),
CONSTRAINT check_956afd70f1 CHECK ((char_length(encrypted_value) <= 13579))
@@ -12642,7 +12644,8 @@ CREATE TABLE ci_job_variables (
encrypted_value_iv character varying,
job_id bigint NOT NULL,
variable_type smallint DEFAULT 1 NOT NULL,
- source smallint DEFAULT 0 NOT NULL
+ source smallint DEFAULT 0 NOT NULL,
+ raw boolean DEFAULT true NOT NULL
);
CREATE SEQUENCE ci_job_variables_id_seq
@@ -12808,7 +12811,8 @@ CREATE TABLE ci_pipeline_schedule_variables (
pipeline_schedule_id integer NOT NULL,
created_at timestamp with time zone,
updated_at timestamp with time zone,
- variable_type smallint DEFAULT 1 NOT NULL
+ variable_type smallint DEFAULT 1 NOT NULL,
+ raw boolean DEFAULT true NOT NULL
);
CREATE SEQUENCE ci_pipeline_schedule_variables_id_seq
@@ -12851,7 +12855,8 @@ CREATE TABLE ci_pipeline_variables (
encrypted_value_salt character varying,
encrypted_value_iv character varying,
pipeline_id integer NOT NULL,
- variable_type smallint DEFAULT 1 NOT NULL
+ variable_type smallint DEFAULT 1 NOT NULL,
+ raw boolean DEFAULT true NOT NULL
);
CREATE SEQUENCE ci_pipeline_variables_id_seq
@@ -13292,7 +13297,8 @@ CREATE TABLE ci_variables (
protected boolean DEFAULT false NOT NULL,
environment_scope character varying DEFAULT '*'::character varying NOT NULL,
masked boolean DEFAULT false NOT NULL,
- variable_type smallint DEFAULT 1 NOT NULL
+ variable_type smallint DEFAULT 1 NOT NULL,
+ raw boolean DEFAULT true NOT NULL
);
CREATE SEQUENCE ci_variables_id_seq
@@ -16195,7 +16201,6 @@ CREATE TABLE integrations (
created_at timestamp without time zone,
updated_at timestamp without time zone,
active boolean DEFAULT false NOT NULL,
- properties text,
push_events boolean DEFAULT true,
issues_events boolean DEFAULT true,
merge_requests_events boolean DEFAULT true,
@@ -29819,7 +29824,7 @@ CREATE UNIQUE INDEX index_vulnerability_remediations_on_project_id_and_checksum
CREATE UNIQUE INDEX index_vulnerability_scanners_on_project_id_and_external_id ON vulnerability_scanners USING btree (project_id, external_id);
-CREATE INDEX index_vulnerability_state_transitions_on_vulnerability_id ON vulnerability_state_transitions USING btree (vulnerability_id);
+CREATE INDEX index_vulnerability_state_transitions_id_and_vulnerability_id ON vulnerability_state_transitions USING btree (vulnerability_id, id);
CREATE INDEX index_vulnerability_statistics_on_latest_pipeline_id ON vulnerability_statistics USING btree (latest_pipeline_id);
diff --git a/doc/update/deprecations.md b/doc/update/deprecations.md
index 73f1d3752fe..3f90f540c7a 100644
--- a/doc/update/deprecations.md
+++ b/doc/update/deprecations.md
@@ -158,7 +158,7 @@ GitLab 15.2 to simplify the codebase and prevent any unwanted performance degrad
### Dependency Scanning default Java version changed to 17
-Planned removal: GitLab <span class="removal-milestone">15.0</span> (2021-05-22)
+Planned removal: GitLab <span class="removal-milestone">15.0</span> (2022-05-22)
WARNING:
This is a [breaking change](https://docs.gitlab.com/ee/development/contributing/#breaking-changes).
@@ -204,7 +204,7 @@ For more information about iteration cadences, you can refer to
### Outdated indices of Advanced Search migrations
-Planned removal: GitLab <span class="removal-milestone">15.0</span> (2021-05-22)
+Planned removal: GitLab <span class="removal-milestone">15.0</span> (2022-05-22)
WARNING:
This is a [breaking change](https://docs.gitlab.com/ee/development/contributing/#breaking-changes).
@@ -412,7 +412,7 @@ For additional context, or to provide feedback regarding this change, please ref
### Dependency Scanning Python 3.9 and 3.6 image deprecation
-Planned removal: GitLab <span class="removal-milestone">15.0</span> (2021-05-22)
+Planned removal: GitLab <span class="removal-milestone">15.0</span> (2022-05-22)
WARNING:
This is a [breaking change](https://docs.gitlab.com/ee/development/contributing/#breaking-changes).
diff --git a/doc/user/permissions.md b/doc/user/permissions.md
index b4822f48be0..dc8796ffe4d 100644
--- a/doc/user/permissions.md
+++ b/doc/user/permissions.md
@@ -158,7 +158,7 @@ The following table lists project permissions available for each role:
| [Projects](project/index.md):<br>Edit project badges | | | | ✓ | ✓ |
| [Projects](project/index.md):<br>Edit project settings | | | | ✓ | ✓ |
| [Projects](project/index.md):<br>Export project | | | | ✓ | ✓ |
-| [Projects](project/index.md):<br>Manage [project access tokens](project/settings/project_access_tokens.md) (*11*) | | | | ✓ | ✓ |
+| [Projects](project/index.md):<br>Manage [project access tokens](project/settings/project_access_tokens.md) (*11*) | | | | ✓ (*21*) | ✓ |
| [Projects](project/index.md):<br>Manage [Project Operations](../operations/index.md) | | | | ✓ | ✓ |
| [Projects](project/index.md):<br>Rename project | | | | ✓ | ✓ |
| [Projects](project/index.md):<br>Share (invite) projects with groups | | | | ✓ (*7*) | ✓ (*7*) |
@@ -238,7 +238,7 @@ The following table lists project permissions available for each role:
18. Authors and assignees of issues can modify the title and description even if they don't have the Reporter role.
19. Authors and assignees can close and reopen issues even if they don't have the Reporter role.
20. The ability to view the Container Registry and pull images is controlled by the [Container Registry's visibility permissions](packages/container_registry/index.md#container-registry-visibility-permissions).
-21. Maintainers cannot create, demote, or remove Owners, and they cannot promote users to the Owner role.
+21. Maintainers cannot create, demote, or remove Owners, and they cannot promote users to the Owner role. They also cannot approve Owner role access requests.
<!-- markdownlint-enable MD029 -->
diff --git a/doc/user/project/integrations/slack.md b/doc/user/project/integrations/slack.md
index 870554100b7..bd93fbcbcbc 100644
--- a/doc/user/project/integrations/slack.md
+++ b/doc/user/project/integrations/slack.md
@@ -91,7 +91,7 @@ the error message and keep troubleshooting from there.
You might see an entry like the following in your Sidekiq log:
```plaintext
-2019-01-10_13:22:08.42572 2019-01-10T13:22:08.425Z 6877 TID-abcdefg ProjectServiceWorker JID-3bade5fb3dd47a85db6d78c5 ERROR: {:class=>"ProjectServiceWorker", :service_class=>"SlackService", :message=>"SSL_connect returned=1 errno=0 state=error: certificate verify failed"}
+2019-01-10_13:22:08.42572 2019-01-10T13:22:08.425Z 6877 TID-abcdefg Integrations::ExecuteWorker JID-3bade5fb3dd47a85db6d78c5 ERROR: {:class=>"Integrations::ExecuteWorker :service_class=>"SlackService", :message=>"SSL_connect returned=1 errno=0 state=error: certificate verify failed"}
```
This issue occurs when there is a problem with GitLab communicating with Slack,
diff --git a/doc/user/project/members/index.md b/doc/user/project/members/index.md
index 28bd353d8cc..7bea57d180b 100644
--- a/doc/user/project/members/index.md
+++ b/doc/user/project/members/index.md
@@ -225,9 +225,10 @@ GitLab users can request to become a member of a project.
An email is sent to the most recently active project maintainers.
Up to ten project maintainers are notified.
-Any project maintainer can approve or decline the request.
+Any project owner or maintainer can approve or decline the request.
+Project maintainers cannot approve Owner role access requests.
-If a project does not have any maintainers, the notification is sent to the
+If a project does not have any direct owners or maintainers, the notification is sent to the
most recently active owners of the project's group.
If you change your mind before your request is approved, select
diff --git a/lib/gitlab/gfm/reference_rewriter.rb b/lib/gitlab/gfm/reference_rewriter.rb
index 5d0a638f97a..40dcac5f46f 100644
--- a/lib/gitlab/gfm/reference_rewriter.rb
+++ b/lib/gitlab/gfm/reference_rewriter.rb
@@ -31,30 +31,41 @@ module Gitlab
# http://gitlab.com/some/link/#1234, and code `puts #1234`'
#
class ReferenceRewriter
+ include Gitlab::Utils::StrongMemoize
+
RewriteError = Class.new(StandardError)
- def initialize(text, source_parent, current_user)
+ def initialize(text, text_html, source_parent, current_user)
@text = text
+
+ # If for some reason cached html is not present it gets rendered here
+ @text_html = text_html || original_html
+
@source_parent = source_parent
@current_user = current_user
- @original_html = markdown(text)
@pattern = Gitlab::ReferenceExtractor.references_pattern
end
def rewrite(target_parent)
return @text unless needs_rewrite?
- @text.gsub(@pattern) do |reference|
+ @text.gsub!(@pattern) do |reference|
unfold_reference(reference, Regexp.last_match, target_parent)
end
end
def needs_rewrite?
- @text =~ @pattern
+ strong_memoize(:needs_rewrite) { @text_html.include?('data-reference-type=') }
end
private
+ def original_html
+ strong_memoize(:original_html) do
+ markdown(@text)
+ end
+ end
+
def unfold_reference(reference, match, target_parent)
before = @text[0...match.begin(0)]
after = @text[match.end(0)..]
@@ -89,7 +100,7 @@ module Gitlab
end
def substitution_valid?(substituted)
- @original_html == markdown(substituted)
+ original_html == markdown(substituted)
end
def markdown(text)
diff --git a/lib/gitlab/gfm/uploads_rewriter.rb b/lib/gitlab/gfm/uploads_rewriter.rb
index 82ef7eed56a..b0bf68f4204 100644
--- a/lib/gitlab/gfm/uploads_rewriter.rb
+++ b/lib/gitlab/gfm/uploads_rewriter.rb
@@ -12,7 +12,9 @@ module Gitlab
#
#
class UploadsRewriter
- def initialize(text, source_project, _current_user)
+ include Gitlab::Utils::StrongMemoize
+
+ def initialize(text, _text_html, source_project, _current_user)
@text = text
@source_project = source_project
@pattern = FileUploader::MARKDOWN_PATTERN
@@ -21,7 +23,7 @@ module Gitlab
def rewrite(target_parent)
return @text unless needs_rewrite?
- @text.gsub(@pattern) do |markdown|
+ @text.gsub!(@pattern) do |markdown|
file = find_file($~[:secret], $~[:file])
# No file will be returned for a path traversal
next if file.nil?
@@ -43,15 +45,9 @@ module Gitlab
end
def needs_rewrite?
- files.any?
- end
-
- def files
- referenced_files = @text.scan(@pattern).map do
- find_file($~[:secret], $~[:file])
+ strong_memoize(:needs_rewrite) do
+ FileUploader::MARKDOWN_PATTERN.match?(@text)
end
-
- referenced_files.compact.select(&:exists?)
end
def was_embedded?(markdown)
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 1b4368c7e8f..55cc184d89e 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -8978,6 +8978,9 @@ msgstr ""
msgid "Collapse issues"
msgstr ""
+msgid "Collapse jobs"
+msgstr ""
+
msgid "Collapse milestones"
msgstr ""
@@ -15193,13 +15196,13 @@ msgstr ""
msgid "Expand issues"
msgstr ""
-msgid "Expand milestones"
+msgid "Expand jobs"
msgstr ""
-msgid "Expand panel"
+msgid "Expand milestones"
msgstr ""
-msgid "Expand pipeline"
+msgid "Expand panel"
msgstr ""
msgid "Expand settings section"
diff --git a/spec/controllers/admin/integrations_controller_spec.rb b/spec/controllers/admin/integrations_controller_spec.rb
index 410bc0ddc1d..0e456858b49 100644
--- a/spec/controllers/admin/integrations_controller_spec.rb
+++ b/spec/controllers/admin/integrations_controller_spec.rb
@@ -43,7 +43,7 @@ RSpec.describe Admin::IntegrationsController do
end
describe '#update' do
- include JiraServiceHelper
+ include JiraIntegrationHelpers
let(:integration) { create(:jira_integration, :instance) }
diff --git a/spec/controllers/groups/settings/integrations_controller_spec.rb b/spec/controllers/groups/settings/integrations_controller_spec.rb
index c070094babd..377c38ce087 100644
--- a/spec/controllers/groups/settings/integrations_controller_spec.rb
+++ b/spec/controllers/groups/settings/integrations_controller_spec.rb
@@ -76,7 +76,7 @@ RSpec.describe Groups::Settings::IntegrationsController do
end
describe '#update' do
- include JiraServiceHelper
+ include JiraIntegrationHelpers
let(:integration) { create(:jira_integration, :group, group: group) }
diff --git a/spec/controllers/projects/import/jira_controller_spec.rb b/spec/controllers/projects/import/jira_controller_spec.rb
index 5288c0fcf21..3f149afbb02 100644
--- a/spec/controllers/projects/import/jira_controller_spec.rb
+++ b/spec/controllers/projects/import/jira_controller_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Projects::Import::JiraController do
- include JiraServiceHelper
+ include JiraIntegrationHelpers
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project) }
diff --git a/spec/controllers/projects/settings/integrations_controller_spec.rb b/spec/controllers/projects/settings/integrations_controller_spec.rb
index 16f32ee83b4..e6ca088a533 100644
--- a/spec/controllers/projects/settings/integrations_controller_spec.rb
+++ b/spec/controllers/projects/settings/integrations_controller_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Projects::Settings::IntegrationsController do
- include JiraServiceHelper
+ include JiraIntegrationHelpers
include AfterNextHelpers
let_it_be(:project) { create(:project, :repository) }
diff --git a/spec/factories/application_settings.rb b/spec/factories/application_settings.rb
index c28d3c20a86..844e21df60c 100644
--- a/spec/factories/application_settings.rb
+++ b/spec/factories/application_settings.rb
@@ -5,5 +5,9 @@ FactoryBot.define do
default_projects_limit { 42 }
import_sources { [] }
restricted_visibility_levels { [] }
+
+ after(:build) do |settings|
+ settings.ensure_key_restrictions!
+ end
end
end
diff --git a/spec/features/projects/integrations/user_activates_jira_spec.rb b/spec/features/projects/integrations/user_activates_jira_spec.rb
index b63c7a115bc..dad201ffbb6 100644
--- a/spec/features/projects/integrations/user_activates_jira_spec.rb
+++ b/spec/features/projects/integrations/user_activates_jira_spec.rb
@@ -61,7 +61,7 @@ RSpec.describe 'User activates Jira', :js do
end
describe 'user disables the Jira integration' do
- include JiraServiceHelper
+ include JiraIntegrationHelpers
before do
stub_jira_integration_test
diff --git a/spec/features/projects/integrations/user_uses_inherited_settings_spec.rb b/spec/features/projects/integrations/user_uses_inherited_settings_spec.rb
index fcb04c338a9..8a2881c95dc 100644
--- a/spec/features/projects/integrations/user_uses_inherited_settings_spec.rb
+++ b/spec/features/projects/integrations/user_uses_inherited_settings_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe 'User uses inherited settings', :js do
- include JiraServiceHelper
+ include JiraIntegrationHelpers
include_context 'project integration activation'
diff --git a/spec/frontend/notes/components/notes_app_spec.js b/spec/frontend/notes/components/notes_app_spec.js
index e018523472b..f4eb69e0d49 100644
--- a/spec/frontend/notes/components/notes_app_spec.js
+++ b/spec/frontend/notes/components/notes_app_spec.js
@@ -222,7 +222,7 @@ describe('note_app', () => {
});
it('renders skeleton notes', () => {
- expect(wrapper.find('.animation-container').exists()).toBe(true);
+ expect(wrapper.find('.gl-skeleton-loader-default-container').exists()).toBe(true);
});
it('should render form', () => {
diff --git a/spec/frontend/pipelines/graph/linked_pipeline_spec.js b/spec/frontend/pipelines/graph/linked_pipeline_spec.js
index 1a66320dd29..1e693184d73 100644
--- a/spec/frontend/pipelines/graph/linked_pipeline_spec.js
+++ b/spec/frontend/pipelines/graph/linked_pipeline_spec.js
@@ -200,10 +200,14 @@ describe('Linked pipeline', () => {
expect(findRetryButton().exists()).toBe(true);
});
- it('hides the card tooltip when the action button tooltip is hovered', async () => {
+ it.each`
+ findElement | name
+ ${findRetryButton} | ${'retry button'}
+ ${findExpandButton} | ${'expand button'}
+ `('hides the card tooltip when $name is hovered', async ({ findElement }) => {
expect(findCardTooltip().exists()).toBe(true);
- await findRetryButton().trigger('mouseover');
+ await findElement().trigger('mouseover');
expect(findCardTooltip().exists()).toBe(false);
});
@@ -262,10 +266,14 @@ describe('Linked pipeline', () => {
expect(findRetryButton().exists()).toBe(false);
});
- it('hides the card tooltip when the action button tooltip is hovered', async () => {
+ it.each`
+ findElement | name
+ ${findCancelButton} | ${'cancel button'}
+ ${findExpandButton} | ${'expand button'}
+ `('hides the card tooltip when $name is hovered', async ({ findElement }) => {
expect(findCardTooltip().exists()).toBe(true);
- await findCancelButton().trigger('mouseover');
+ await findElement().trigger('mouseover');
expect(findCardTooltip().exists()).toBe(false);
});
diff --git a/spec/lib/gitlab/background_migration/encrypt_integration_properties_spec.rb b/spec/lib/gitlab/background_migration/encrypt_integration_properties_spec.rb
index 7334867e8fb..38e8b159e63 100644
--- a/spec/lib/gitlab/background_migration/encrypt_integration_properties_spec.rb
+++ b/spec/lib/gitlab/background_migration/encrypt_integration_properties_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::EncryptIntegrationProperties do
+RSpec.describe Gitlab::BackgroundMigration::EncryptIntegrationProperties, schema: 20220415124804 do
let(:integrations) do
table(:integrations) do |integrations|
integrations.send :attr_encrypted, :encrypted_properties_tmp,
diff --git a/spec/lib/gitlab/gfm/reference_rewriter_spec.rb b/spec/lib/gitlab/gfm/reference_rewriter_spec.rb
index 7d4a3655be6..8bb649e78e0 100644
--- a/spec/lib/gitlab/gfm/reference_rewriter_spec.rb
+++ b/spec/lib/gitlab/gfm/reference_rewriter_spec.rb
@@ -10,6 +10,7 @@ RSpec.describe Gitlab::Gfm::ReferenceRewriter do
let(:old_project) { create(:project, name: 'old-project', group: group) }
let(:old_project_ref) { old_project.to_reference_base(new_project) }
let(:text) { 'some text' }
+ let(:note) { create(:note, note: text, project: old_project) }
before do
old_project.add_reporter(user)
@@ -17,7 +18,7 @@ RSpec.describe Gitlab::Gfm::ReferenceRewriter do
describe '#rewrite' do
subject do
- described_class.new(text, old_project, user).rewrite(new_project)
+ described_class.new(note.note, note.note_html, old_project, user).rewrite(new_project)
end
context 'multiple issues and merge requests referenced' do
diff --git a/spec/lib/gitlab/gfm/uploads_rewriter_spec.rb b/spec/lib/gitlab/gfm/uploads_rewriter_spec.rb
index f878f02f410..763e6f1b5f4 100644
--- a/spec/lib/gitlab/gfm/uploads_rewriter_spec.rb
+++ b/spec/lib/gitlab/gfm/uploads_rewriter_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe Gitlab::Gfm::UploadsRewriter do
let(:user) { create(:user) }
let(:old_project) { create(:project) }
let(:new_project) { create(:project) }
- let(:rewriter) { described_class.new(text, old_project, user) }
+ let(:rewriter) { described_class.new(+text, nil, old_project, user) }
context 'text contains links to uploads' do
let(:image_uploader) do
@@ -22,13 +22,21 @@ RSpec.describe Gitlab::Gfm::UploadsRewriter do
"Text and #{image_uploader.markdown_link} and #{zip_uploader.markdown_link}"
end
+ def referenced_files(text, project)
+ referenced_files = text.scan(FileUploader::MARKDOWN_PATTERN).map do
+ UploaderFinder.new(project, $~[:secret], $~[:file]).execute
+ end
+
+ referenced_files.compact.select(&:exists?)
+ end
+
shared_examples "files are accessible" do
describe '#rewrite' do
let!(:new_text) { rewriter.rewrite(new_project) }
let(:old_files) { [image_uploader, zip_uploader] }
let(:new_files) do
- described_class.new(new_text, new_project, user).files
+ referenced_files(new_text, new_project)
end
let(:old_paths) { old_files.map(&:path) }
@@ -68,9 +76,9 @@ RSpec.describe Gitlab::Gfm::UploadsRewriter do
it 'does not rewrite plain links as embedded' do
embedded_link = image_uploader.markdown_link
plain_image_link = embedded_link.delete_prefix('!')
- text = "#{plain_image_link} and #{embedded_link}"
+ text = +"#{plain_image_link} and #{embedded_link}"
- moved_text = described_class.new(text, old_project, user).rewrite(new_project)
+ moved_text = described_class.new(text, nil, old_project, user).rewrite(new_project)
expect(moved_text.scan(/!\[.*?\]/).count).to eq(1)
expect(moved_text.scan(/\A\[.*?\]/).count).to eq(1)
@@ -97,11 +105,5 @@ RSpec.describe Gitlab::Gfm::UploadsRewriter do
it { is_expected.to eq true }
end
-
- describe '#files' do
- subject { rewriter.files }
-
- it { is_expected.to be_an(Array) }
- end
end
end
diff --git a/spec/lib/gitlab/jira_import/base_importer_spec.rb b/spec/lib/gitlab/jira_import/base_importer_spec.rb
index 479551095de..70a594b09af 100644
--- a/spec/lib/gitlab/jira_import/base_importer_spec.rb
+++ b/spec/lib/gitlab/jira_import/base_importer_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Gitlab::JiraImport::BaseImporter do
- include JiraServiceHelper
+ include JiraIntegrationHelpers
let(:project) { create(:project) }
diff --git a/spec/lib/gitlab/jira_import/issues_importer_spec.rb b/spec/lib/gitlab/jira_import/issues_importer_spec.rb
index aead5405bd1..565a9ad17e1 100644
--- a/spec/lib/gitlab/jira_import/issues_importer_spec.rb
+++ b/spec/lib/gitlab/jira_import/issues_importer_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Gitlab::JiraImport::IssuesImporter do
- include JiraServiceHelper
+ include JiraIntegrationHelpers
let_it_be(:user) { create(:user) }
let_it_be(:current_user) { create(:user) }
diff --git a/spec/lib/gitlab/jira_import/labels_importer_spec.rb b/spec/lib/gitlab/jira_import/labels_importer_spec.rb
index 71440590815..4fb5e363475 100644
--- a/spec/lib/gitlab/jira_import/labels_importer_spec.rb
+++ b/spec/lib/gitlab/jira_import/labels_importer_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Gitlab::JiraImport::LabelsImporter do
- include JiraServiceHelper
+ include JiraIntegrationHelpers
let_it_be(:user) { create(:user) }
let_it_be(:group) { create(:group) }
diff --git a/spec/lib/gitlab/jira_import_spec.rb b/spec/lib/gitlab/jira_import_spec.rb
index a7c73e79641..972b0ab6ed1 100644
--- a/spec/lib/gitlab/jira_import_spec.rb
+++ b/spec/lib/gitlab/jira_import_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe Gitlab::JiraImport do
let(:project_id) { 321 }
describe '.validate_project_settings!' do
- include JiraServiceHelper
+ include JiraIntegrationHelpers
let_it_be(:project, reload: true) { create(:project) }
diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb
index 644fee97613..61f008416ea 100644
--- a/spec/models/application_setting_spec.rb
+++ b/spec/models/application_setting_spec.rb
@@ -554,11 +554,45 @@ RSpec.describe ApplicationSetting do
it { is_expected.to allow_value(*KeyRestrictionValidator.supported_key_restrictions(type)).for(field) }
it { is_expected.not_to allow_value(128).for(field) }
end
+ end
+ end
- it_behaves_like 'key validations'
+ describe '#ensure_key_restrictions!' do
+ context 'with non-compliant FIPS settings' do
+ before do
+ setting.update_columns(
+ rsa_key_restriction: 1024,
+ dsa_key_restriction: 0,
+ ecdsa_key_restriction: 521,
+ ed25519_key_restriction: -1,
+ ecdsa_sk_key_restriction: 0,
+ ed25519_sk_key_restriction: 0
+ )
+ end
- context 'FIPS mode', :fips_mode do
- it_behaves_like 'key validations'
+ context 'in non-FIPS mode', fips_mode: false do
+ it 'keeps existing key restrictions' do
+ expect { setting.ensure_key_restrictions! }.not_to change { setting.valid? }
+ expect(setting).to be_valid
+ expect(setting.rsa_key_restriction).to eq(1024)
+ expect(setting.dsa_key_restriction).to eq(0)
+ expect(setting.ecdsa_key_restriction).to eq(521)
+ expect(setting.ed25519_key_restriction).to eq(-1)
+ expect(setting.ecdsa_sk_key_restriction).to eq(0)
+ expect(setting.ed25519_sk_key_restriction).to eq(0)
+ end
+ end
+
+ context 'in FIPS mode', :fips_mode do
+ it 'updates key restrictions to meet FIPS compliance' do
+ expect { setting.ensure_key_restrictions! }.to change { setting.valid? }.from(false).to(true)
+ expect(setting.rsa_key_restriction).to eq(3072)
+ expect(setting.dsa_key_restriction).to eq(-1)
+ expect(setting.ecdsa_key_restriction).to eq(521)
+ expect(setting.ed25519_key_restriction).to eq(-1)
+ expect(setting.ecdsa_sk_key_restriction).to eq(256)
+ expect(setting.ed25519_sk_key_restriction).to eq(256)
+ end
end
end
end
diff --git a/spec/models/concerns/cache_markdown_field_spec.rb b/spec/models/concerns/cache_markdown_field_spec.rb
index d46f22b2216..a00129b3fdf 100644
--- a/spec/models/concerns/cache_markdown_field_spec.rb
+++ b/spec/models/concerns/cache_markdown_field_spec.rb
@@ -404,6 +404,16 @@ RSpec.describe CacheMarkdownField, :clean_gitlab_redis_cache do
it 'returns false when there are no changes' do
expect(thing.attribute_invalidated?(:description_html)).to eq(false)
end
+
+ it 'returns false if skip_markdown_cache_validation is true' do
+ # invalidates the attribute
+ thing.cached_markdown_version += 1
+ thing.description = updated_markdown
+
+ thing.skip_markdown_cache_validation = true
+
+ expect(thing.attribute_invalidated?(:description_html)).to eq(false)
+ end
end
context 'when cache version is updated' do
diff --git a/spec/models/integration_spec.rb b/spec/models/integration_spec.rb
index 0d38e10c5e6..c4175518295 100644
--- a/spec/models/integration_spec.rb
+++ b/spec/models/integration_spec.rb
@@ -1205,4 +1205,46 @@ RSpec.describe Integration do
end
end
end
+
+ describe '#async_execute' do
+ let(:integration) { described_class.new(id: 123) }
+ let(:data) { { object_kind: 'push' } }
+ let(:supported_events) { %w[push] }
+
+ subject(:async_execute) { integration.async_execute(data) }
+
+ before do
+ allow(integration).to receive(:supported_events).and_return(supported_events)
+ end
+
+ it 'queues a Integrations::ExecuteWorker' do
+ expect(Integrations::ExecuteWorker).to receive(:perform_async).with(integration.id, data)
+ expect(ProjectServiceWorker).not_to receive(:perform_async)
+
+ async_execute
+ end
+
+ context 'when the event is not supported' do
+ let(:supported_events) { %w[issue] }
+
+ it 'does not queue a worker' do
+ expect(Integrations::ExecuteWorker).not_to receive(:perform_async)
+
+ async_execute
+ end
+ end
+
+ context 'when the FF :rename_integration_workers is disabled' do
+ before do
+ stub_feature_flags(rename_integrations_workers: false)
+ end
+
+ it 'queues a ProjectServiceWorker' do
+ expect(ProjectServiceWorker).to receive(:perform_async).with(integration.id, data)
+ expect(Integrations::ExecuteWorker).not_to receive(:perform_async)
+
+ async_execute
+ end
+ end
+ end
end
diff --git a/spec/requests/api/graphql/mutations/jira_import/import_users_spec.rb b/spec/requests/api/graphql/mutations/jira_import/import_users_spec.rb
index 45cc70f09fd..b438e1ba881 100644
--- a/spec/requests/api/graphql/mutations/jira_import/import_users_spec.rb
+++ b/spec/requests/api/graphql/mutations/jira_import/import_users_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe 'Importing Jira Users' do
- include JiraServiceHelper
+ include JiraIntegrationHelpers
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/jira_import/start_spec.rb b/spec/requests/api/graphql/mutations/jira_import/start_spec.rb
index b14305281af..1508ba31e37 100644
--- a/spec/requests/api/graphql/mutations/jira_import/start_spec.rb
+++ b/spec/requests/api/graphql/mutations/jira_import/start_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe 'Starting a Jira Import' do
- include JiraServiceHelper
+ include JiraIntegrationHelpers
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/services/bulk_create_integration_service_spec.rb b/spec/services/bulk_create_integration_service_spec.rb
index ddc95ff92d5..22bb1736f9f 100644
--- a/spec/services/bulk_create_integration_service_spec.rb
+++ b/spec/services/bulk_create_integration_service_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe BulkCreateIntegrationService do
- include JiraServiceHelper
+ include JiraIntegrationHelpers
before_all do
stub_jira_integration_test
diff --git a/spec/services/bulk_update_integration_service_spec.rb b/spec/services/bulk_update_integration_service_spec.rb
index 23e2a0ef0ff..e3e38aacaa2 100644
--- a/spec/services/bulk_update_integration_service_spec.rb
+++ b/spec/services/bulk_update_integration_service_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe BulkUpdateIntegrationService do
- include JiraServiceHelper
+ include JiraIntegrationHelpers
before_all do
stub_jira_integration_test
diff --git a/spec/services/git/branch_push_service_spec.rb b/spec/services/git/branch_push_service_spec.rb
index 57c130f76a4..befa9598964 100644
--- a/spec/services/git/branch_push_service_spec.rb
+++ b/spec/services/git/branch_push_service_spec.rb
@@ -410,7 +410,7 @@ RSpec.describe Git::BranchPushService, services: true do
end
context "for jira issue tracker" do
- include JiraServiceHelper
+ include JiraIntegrationHelpers
let(:jira_tracker) { project.create_jira_integration if project.jira_integration.nil? }
diff --git a/spec/services/integrations/propagate_service_spec.rb b/spec/services/integrations/propagate_service_spec.rb
index 7ae843f6aeb..c971c4a0ad0 100644
--- a/spec/services/integrations/propagate_service_spec.rb
+++ b/spec/services/integrations/propagate_service_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe Integrations::PropagateService do
describe '.propagate' do
- include JiraServiceHelper
+ include JiraIntegrationHelpers
before do
stub_jira_integration_test
diff --git a/spec/services/jira_import/start_import_service_spec.rb b/spec/services/jira_import/start_import_service_spec.rb
index e04e3314158..510f58f0e75 100644
--- a/spec/services/jira_import/start_import_service_spec.rb
+++ b/spec/services/jira_import/start_import_service_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe JiraImport::StartImportService do
- include JiraServiceHelper
+ include JiraIntegrationHelpers
let_it_be(:user) { create(:user) }
let_it_be(:project, reload: true) { create(:project) }
diff --git a/spec/services/jira_import/users_importer_spec.rb b/spec/services/jira_import/users_importer_spec.rb
index af408847260..ace9e0d5779 100644
--- a/spec/services/jira_import/users_importer_spec.rb
+++ b/spec/services/jira_import/users_importer_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe JiraImport::UsersImporter do
- include JiraServiceHelper
+ include JiraIntegrationHelpers
let_it_be(:user) { create(:user) }
let_it_be(:group) { create(:group) }
diff --git a/spec/services/markdown_content_rewriter_service_spec.rb b/spec/services/markdown_content_rewriter_service_spec.rb
index 37c8a210ba5..91a117536ca 100644
--- a/spec/services/markdown_content_rewriter_service_spec.rb
+++ b/spec/services/markdown_content_rewriter_service_spec.rb
@@ -8,38 +8,63 @@ RSpec.describe MarkdownContentRewriterService do
let_it_be(:target_parent) { create(:project, :public) }
let(:content) { 'My content' }
+ let(:issue) { create(:issue, project: source_parent, description: content)}
describe '#initialize' do
it 'raises an error if source_parent is not a Project' do
expect do
- described_class.new(user, content, create(:group), target_parent)
+ described_class.new(user, issue, :description, create(:group), target_parent)
end.to raise_error(ArgumentError, 'The rewriter classes require that `source_parent` is a `Project`')
end
+
+ it 'raises an error if field does not have cached markdown' do
+ expect do
+ described_class.new(user, issue, :author, source_parent, target_parent)
+ end.to raise_error(ArgumentError, 'The `field` attribute does not contain cached markdown')
+ end
end
describe '#execute' do
- subject { described_class.new(user, content, source_parent, target_parent).execute }
+ subject { described_class.new(user, issue, :description, source_parent, target_parent).execute }
- it 'calls the rewriter classes successfully', :aggregate_failures do
- [Gitlab::Gfm::ReferenceRewriter, Gitlab::Gfm::UploadsRewriter].each do |rewriter_class|
- service = double
-
- expect(service).to receive(:rewrite).with(target_parent)
- expect(rewriter_class).to receive(:new).and_return(service)
+ context 'when content does not need a rewrite' do
+ it 'returns original content and cached html' do
+ expect(subject).to eq({
+ 'description' => issue.description,
+ 'description_html' => issue.description_html,
+ 'skip_markdown_cache_validation' => true
+ })
end
+ end
+
+ context 'when content needs a rewrite' do
+ it 'calls the rewriter classes successfully', :aggregate_failures do
+ described_class::REWRITERS.each do |rewriter_class|
+ service = double
- subject
+ allow(service).to receive(:needs_rewrite?).and_return(true)
+
+ expect(service).to receive(:rewrite).with(target_parent)
+ expect(rewriter_class).to receive(:new).and_return(service)
+ end
+
+ subject
+ end
end
# Perform simple integration-style tests for each rewriter class.
# to prove they run correctly.
- context 'when content contains a reference' do
- let_it_be(:issue) { create(:issue, project: source_parent) }
+ context 'when content has references' do
+ let_it_be(:issue_to_reference) { create(:issue, project: source_parent) }
- let(:content) { "See ##{issue.iid}" }
+ let(:content) { "See ##{issue_to_reference.iid}" }
it 'rewrites content' do
- expect(subject).to eq("See #{source_parent.full_path}##{issue.iid}")
+ expect(subject).to eq({
+ 'description' => "See #{source_parent.full_path}##{issue_to_reference.iid}",
+ 'description_html' => nil,
+ 'skip_markdown_cache_validation' => false
+ })
end
end
@@ -50,9 +75,37 @@ RSpec.describe MarkdownContentRewriterService do
it 'rewrites content' do
new_content = subject
- expect(new_content).not_to eq(content)
- expect(new_content.length).to eq(content.length)
+ expect(new_content[:description]).not_to eq(content)
+ expect(new_content[:description].length).to eq(content.length)
+ expect(new_content[1]).to eq(nil)
end
end
end
+
+ describe '#safe_to_copy_markdown?' do
+ subject do
+ rewriter = described_class.new(user, issue, :description, source_parent, target_parent)
+ rewriter.safe_to_copy_markdown?
+ end
+
+ context 'when content has references' do
+ let(:milestone) { create(:milestone, project: source_parent) }
+ let(:content) { "Description that references #{milestone.to_reference}" }
+
+ it { is_expected.to eq(false) }
+ end
+
+ context 'when content has uploaded file references' do
+ let(:image_uploader) { build(:file_uploader, project: source_parent) }
+ let(:content) { "Text and #{image_uploader.markdown_link}" }
+
+ it { is_expected.to eq(false) }
+ end
+
+ context 'when content does not have references or uploads' do
+ let(:content) { "simples text with ```code```" }
+
+ it { is_expected.to eq(true) }
+ end
+ end
end
diff --git a/spec/services/members/approve_access_request_service_spec.rb b/spec/services/members/approve_access_request_service_spec.rb
index f7fbac612ee..d26bab7bb0a 100644
--- a/spec/services/members/approve_access_request_service_spec.rb
+++ b/spec/services/members/approve_access_request_service_spec.rb
@@ -9,36 +9,34 @@ RSpec.describe Members::ApproveAccessRequestService do
let(:access_requester_user) { create(:user) }
let(:access_requester) { source.requesters.find_by!(user_id: access_requester_user.id) }
let(:opts) { {} }
-
- shared_examples 'a service raising ActiveRecord::RecordNotFound' do
- it 'raises ActiveRecord::RecordNotFound' do
- expect { described_class.new(current_user).execute(access_requester, **opts) }.to raise_error(ActiveRecord::RecordNotFound)
- end
- end
+ let(:params) { {} }
+ let(:custom_access_level) { Gitlab::Access::MAINTAINER }
shared_examples 'a service raising Gitlab::Access::AccessDeniedError' do
it 'raises Gitlab::Access::AccessDeniedError' do
- expect { described_class.new(current_user).execute(access_requester, **opts) }.to raise_error(Gitlab::Access::AccessDeniedError)
+ expect { described_class.new(current_user, params).execute(access_requester, **opts) }.to raise_error(Gitlab::Access::AccessDeniedError)
end
end
shared_examples 'a service approving an access request' do
it 'succeeds' do
- expect { described_class.new(current_user).execute(access_requester, **opts) }.to change { source.requesters.count }.by(-1)
+ expect { described_class.new(current_user, params).execute(access_requester, **opts) }.to change { source.requesters.count }.by(-1)
end
it 'returns a <Source>Member' do
- member = described_class.new(current_user).execute(access_requester, **opts)
+ member = described_class.new(current_user, params).execute(access_requester, **opts)
expect(member).to be_a "#{source.class}Member".constantize
expect(member.requested_at).to be_nil
end
context 'with a custom access level' do
+ let(:params) { { access_level: custom_access_level } }
+
it 'returns a ProjectMember with the custom access level' do
- member = described_class.new(current_user, access_level: Gitlab::Access::MAINTAINER).execute(access_requester, **opts)
+ member = described_class.new(current_user, params).execute(access_requester, **opts)
- expect(member.access_level).to eq(Gitlab::Access::MAINTAINER)
+ expect(member.access_level).to eq(custom_access_level)
end
end
end
@@ -111,5 +109,38 @@ RSpec.describe Members::ApproveAccessRequestService do
let(:source) { group }
end
end
+
+ context 'in a project' do
+ let_it_be(:group_project) { create(:project, :public, group: create(:group, :public)) }
+
+ let(:source) { group_project }
+ let(:custom_access_level) { Gitlab::Access::OWNER }
+ let(:params) { { access_level: custom_access_level } }
+
+ before do
+ group_project.request_access(access_requester_user)
+ end
+
+ context 'maintainers' do
+ before do
+ group_project.add_maintainer(current_user)
+ end
+
+ context 'cannot approve the access request of a requester to give them OWNER permissions' do
+ it_behaves_like 'a service raising Gitlab::Access::AccessDeniedError'
+ end
+ end
+
+ context 'owners' do
+ before do
+ # so that `current_user` is considered an `OWNER` in the project via inheritance.
+ group_project.group.add_owner(current_user)
+ end
+
+ context 'can approve the access request of a requester to give them OWNER permissions' do
+ it_behaves_like 'a service approving an access request'
+ end
+ end
+ end
end
end
diff --git a/spec/services/merge_requests/merge_service_spec.rb b/spec/services/merge_requests/merge_service_spec.rb
index 3e2cccfb350..a2d73d8c9b1 100644
--- a/spec/services/merge_requests/merge_service_spec.rb
+++ b/spec/services/merge_requests/merge_service_spec.rb
@@ -161,7 +161,7 @@ RSpec.describe MergeRequests::MergeService do
end
context 'with Jira integration' do
- include JiraServiceHelper
+ include JiraIntegrationHelpers
let(:jira_tracker) { project.create_jira_integration }
let(:jira_issue) { ExternalIssue.new('JIRA-123', project) }
diff --git a/spec/services/notes/copy_service_spec.rb b/spec/services/notes/copy_service_spec.rb
index dd11fa15ea8..fd8802e6640 100644
--- a/spec/services/notes/copy_service_spec.rb
+++ b/spec/services/notes/copy_service_spec.rb
@@ -16,9 +16,8 @@ RSpec.describe Notes::CopyService do
let_it_be(:group) { create(:group) }
let_it_be(:from_project) { create(:project, :public, group: group) }
let_it_be(:to_project) { create(:project, :public, group: group) }
-
- let(:from_noteable) { create(:issue, project: from_project) }
- let(:to_noteable) { create(:issue, project: to_project) }
+ let_it_be(:from_noteable) { create(:issue, project: from_project) }
+ let_it_be(:to_noteable) { create(:issue, project: to_project) }
subject(:execute_service) { described_class.new(user, from_noteable, to_noteable).execute }
@@ -85,6 +84,15 @@ RSpec.describe Notes::CopyService do
expect(execute_service).to be_success
end
end
+
+ it 'copies rendered markdown from note_html' do
+ expect(Banzai::Renderer).not_to receive(:cacheless_render_field)
+
+ execute_service
+
+ new_note = to_noteable.notes.first
+ expect(new_note.note_html).to eq(notes.first.note_html)
+ end
end
context 'notes with mentions' do
@@ -119,6 +127,13 @@ RSpec.describe Notes::CopyService do
expect(new_note.author).to eq(note.author)
end
end
+
+ it 'does not copy rendered markdown from note_html' do
+ execute_service
+
+ new_note = to_noteable.notes.first
+ expect(new_note.note_html).not_to eq(note.note_html)
+ end
end
context 'notes with upload' do
@@ -137,6 +152,13 @@ RSpec.describe Notes::CopyService do
expect(note.note_html).not_to eq(new_note.note_html)
end
end
+
+ it 'does not copy rendered markdown from note_html' do
+ execute_service
+
+ new_note = to_noteable.notes.first
+ expect(new_note.note_html).not_to eq(note.note_html)
+ end
end
context 'discussion notes' do
diff --git a/spec/support/helpers/jira_service_helper.rb b/spec/support/helpers/jira_integration_helpers.rb
index 3cfd0de06e8..66940314589 100644
--- a/spec/support/helpers/jira_service_helper.rb
+++ b/spec/support/helpers/jira_integration_helpers.rb
@@ -1,8 +1,8 @@
# frozen_string_literal: true
-module JiraServiceHelper
- JIRA_URL = "http://jira.example.net"
- JIRA_API = JIRA_URL + "/rest/api/2"
+module JiraIntegrationHelpers
+ JIRA_URL = 'http://jira.example.net'
+ JIRA_API = "#{JIRA_URL}/rest/api/2"
def jira_integration_settings
url = JIRA_URL
@@ -17,6 +17,7 @@ module JiraServiceHelper
end
def jira_issue_comments
+ # rubocop: disable Layout/LineLength
"{\"startAt\":0,\"maxResults\":11,\"total\":11,
\"comments\":[{\"self\":\"http://0.0.0.0:4567/rest/api/2/issue/10002/comment/10609\",
\"id\":\"10609\",\"author\":{\"self\":\"http://0.0.0.0:4567/rest/api/2/user?username=gitlab\",
@@ -51,30 +52,31 @@ module JiraServiceHelper
\"updated\":\"2015-04-01T03:45:55.667+0200\"
}
]}"
+ # rubocop: enable Layout/LineLength
end
def jira_project_url
- JIRA_API + "/project"
+ "#{JIRA_API}/project"
end
def jira_api_comment_url(issue_id)
- JIRA_API + "/issue/#{issue_id}/comment"
+ "#{JIRA_API}/issue/#{issue_id}/comment"
end
def jira_api_remote_link_url(issue_id)
- JIRA_API + "/issue/#{issue_id}/remotelink"
+ "#{JIRA_API}/issue/#{issue_id}/remotelink"
end
def jira_api_transition_url(issue_id)
- JIRA_API + "/issue/#{issue_id}/transitions"
+ "#{JIRA_API}/issue/#{issue_id}/transitions"
end
def jira_api_test_url
- JIRA_API + "/myself"
+ "#{JIRA_API}/myself"
end
def jira_issue_url(issue_id)
- JIRA_API + "/issue/#{issue_id}"
+ "#{JIRA_API}/issue/#{issue_id}"
end
def stub_jira_integration_test
diff --git a/spec/support/shared_contexts/features/integrations/integrations_shared_context.rb b/spec/support/shared_contexts/features/integrations/integrations_shared_context.rb
index 893eae19482..a644e5d5b9c 100644
--- a/spec/support/shared_contexts/features/integrations/integrations_shared_context.rb
+++ b/spec/support/shared_contexts/features/integrations/integrations_shared_context.rb
@@ -2,7 +2,7 @@
Integration.available_integration_names.each do |integration|
RSpec.shared_context integration do
- include JiraServiceHelper if integration == 'jira'
+ include JiraIntegrationHelpers if integration == 'jira'
let(:dashed_integration) { integration.dasherize }
let(:integration_method) { Project.integration_association_name(integration) }
diff --git a/spec/support/shared_examples/models/application_setting_shared_examples.rb b/spec/support/shared_examples/models/application_setting_shared_examples.rb
index 74ec6474e80..6e7d04d3cba 100644
--- a/spec/support/shared_examples/models/application_setting_shared_examples.rb
+++ b/spec/support/shared_examples/models/application_setting_shared_examples.rb
@@ -238,8 +238,16 @@ RSpec.shared_examples 'application settings examples' do
end
describe '#allowed_key_types' do
- it 'includes all key types by default' do
- expect(setting.allowed_key_types).to contain_exactly(*Gitlab::SSHPublicKey.supported_types)
+ context 'in non-FIPS mode', fips_mode: false do
+ it 'includes all key types by default' do
+ expect(setting.allowed_key_types).to contain_exactly(*Gitlab::SSHPublicKey.supported_types)
+ end
+ end
+
+ context 'in FIPS mode', :fips_mode do
+ it 'excludes DSA from supported key types' do
+ expect(setting.allowed_key_types).to contain_exactly(*Gitlab::SSHPublicKey.supported_types - %i(dsa))
+ end
end
it 'excludes disabled key types' do
diff --git a/spec/support/shared_examples/services/alert_management_shared_examples.rb b/spec/support/shared_examples/services/alert_management_shared_examples.rb
index 23aee912d2d..f644f1a1687 100644
--- a/spec/support/shared_examples/services/alert_management_shared_examples.rb
+++ b/spec/support/shared_examples/services/alert_management_shared_examples.rb
@@ -32,7 +32,7 @@ RSpec.shared_context 'incident management settings enabled' do
end
before do
- allow(ProjectServiceWorker).to receive(:perform_async)
+ allow(Integrations::ExecuteWorker).to receive(:perform_async)
allow(service)
.to receive(:incident_management_setting)
.and_return(incident_management_setting)
diff --git a/spec/workers/deployments/hooks_worker_spec.rb b/spec/workers/deployments/hooks_worker_spec.rb
index a9240b45360..7c5f288fa57 100644
--- a/spec/workers/deployments/hooks_worker_spec.rb
+++ b/spec/workers/deployments/hooks_worker_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe Deployments::HooksWorker do
describe '#perform' do
before do
- allow(ProjectServiceWorker).to receive(:perform_async)
+ allow(Integrations::ExecuteWorker).to receive(:perform_async)
end
it 'logs deployment and project IDs as metadata' do
@@ -25,7 +25,7 @@ RSpec.describe Deployments::HooksWorker do
project = deployment.project
service = create(:integrations_slack, project: project, deployment_events: true)
- expect(ProjectServiceWorker).to receive(:perform_async).with(service.id, an_instance_of(Hash))
+ expect(Integrations::ExecuteWorker).to receive(:perform_async).with(service.id, an_instance_of(Hash))
worker.perform(deployment_id: deployment.id, status_changed_at: Time.current)
end
@@ -35,13 +35,13 @@ RSpec.describe Deployments::HooksWorker do
project = deployment.project
create(:integrations_slack, project: project, deployment_events: true, active: false)
- expect(ProjectServiceWorker).not_to receive(:perform_async)
+ expect(Integrations::ExecuteWorker).not_to receive(:perform_async)
worker.perform(deployment_id: deployment.id, status_changed_at: Time.current)
end
it 'does not execute if a deployment does not exist' do
- expect(ProjectServiceWorker).not_to receive(:perform_async)
+ expect(Integrations::ExecuteWorker).not_to receive(:perform_async)
worker.perform(deployment_id: non_existing_record_id, status_changed_at: Time.current)
end
diff --git a/spec/workers/every_sidekiq_worker_spec.rb b/spec/workers/every_sidekiq_worker_spec.rb
index 820076a597a..330afa6fbd4 100644
--- a/spec/workers/every_sidekiq_worker_spec.rb
+++ b/spec/workers/every_sidekiq_worker_spec.rb
@@ -305,6 +305,7 @@ RSpec.describe 'Every Sidekiq worker' do
'IncidentManagement::OncallRotations::PersistAllRotationsShiftsJob' => 3,
'IncidentManagement::OncallRotations::PersistShiftsJob' => 3,
'IncidentManagement::PagerDuty::ProcessIncidentWorker' => 3,
+ 'Integrations::ExecuteWorker' => 3,
'InvalidGpgSignatureUpdateWorker' => 3,
'IrkerWorker' => 3,
'IssuableExportCsvWorker' => 3,
diff --git a/spec/workers/gitlab/jira_import/stage/import_issues_worker_spec.rb b/spec/workers/gitlab/jira_import/stage/import_issues_worker_spec.rb
index 10702c17cb5..2b08a592164 100644
--- a/spec/workers/gitlab/jira_import/stage/import_issues_worker_spec.rb
+++ b/spec/workers/gitlab/jira_import/stage/import_issues_worker_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Gitlab::JiraImport::Stage::ImportIssuesWorker do
- include JiraServiceHelper
+ include JiraIntegrationHelpers
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, import_type: 'jira') }
diff --git a/spec/workers/gitlab/jira_import/stage/import_labels_worker_spec.rb b/spec/workers/gitlab/jira_import/stage/import_labels_worker_spec.rb
index 52c516b9ff9..d15f2caba19 100644
--- a/spec/workers/gitlab/jira_import/stage/import_labels_worker_spec.rb
+++ b/spec/workers/gitlab/jira_import/stage/import_labels_worker_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Gitlab::JiraImport::Stage::ImportLabelsWorker do
- include JiraServiceHelper
+ include JiraIntegrationHelpers
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, import_type: 'jira') }
diff --git a/spec/workers/project_service_worker_spec.rb b/spec/workers/integrations/execute_worker_spec.rb
index 55ec07ff79c..19600f35c8f 100644
--- a/spec/workers/project_service_worker_spec.rb
+++ b/spec/workers/integrations/execute_worker_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe ProjectServiceWorker, '#perform' do
+RSpec.describe Integrations::ExecuteWorker, '#perform' do
let_it_be(:integration) { create(:jira_integration) }
let(:worker) { described_class.new }
@@ -36,4 +36,26 @@ RSpec.describe ProjectServiceWorker, '#perform' do
end.not_to raise_error
end
end
+
+ context 'when using the old worker class' do
+ let(:described_class) { ProjectServiceWorker }
+
+ it 'uses the correct worker attributes', :aggregate_failures do
+ expect(described_class.sidekiq_options).to include('retry' => 3, 'dead' => false)
+ expect(described_class.get_data_consistency).to eq(:always)
+ expect(described_class.get_feature_category).to eq(:integrations)
+ expect(described_class.get_urgency).to eq(:low)
+ expect(described_class.worker_has_external_dependencies?).to be(true)
+ end
+
+ it 'executes integration with given data' do
+ data = { test: 'test' }
+
+ expect_next_found_instance_of(integration.class) do |integration|
+ expect(integration).to receive(:execute).with(data)
+ end
+
+ worker.perform(integration.id, data)
+ end
+ end
end