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:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-02-19 21:09:10 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-02-19 21:09:10 +0300
commit33795139ea8e72756bee3675b4e16387425e6ab1 (patch)
tree3ca568fca61482e57810ee30ad5ce4b964a82c4e
parentc7e385e282bcb8505589bce526e692b7bb819ffa (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/assets/javascripts/boards/components/boards_selector.vue18
-rw-r--r--app/assets/javascripts/boards/stores/boards_store.js2
-rw-r--r--app/assets/stylesheets/framework/buttons.scss7
-rw-r--r--app/models/concerns/milestone_eventable.rb9
-rw-r--r--app/models/concerns/resource_event_tools.rb31
-rw-r--r--app/models/issue.rb1
-rw-r--r--app/models/merge_request.rb1
-rw-r--r--app/models/milestone_note.rb49
-rw-r--r--app/models/resource_label_event.rb21
-rw-r--r--app/models/resource_milestone_event.rb30
-rw-r--r--app/services/issuable/clone/attributes_rewriter.rb18
-rw-r--r--app/services/issuable/common_system_notes_service.rb17
-rw-r--r--app/services/resource_events/change_milestone_service.rb50
-rw-r--r--app/services/resource_events/merge_into_notes_service.rb9
-rw-r--r--app/services/resource_events/synthetic_milestone_notes_builder_service.rb31
-rw-r--r--app/views/dashboard/todos/_todo.html.haml12
-rw-r--r--app/views/dashboard/todos/index.html.haml8
-rw-r--r--app/workers/admin_email_worker.rb2
-rw-r--r--app/workers/all_queues.yml180
-rw-r--r--app/workers/archive_trace_worker.rb2
-rw-r--r--app/workers/authorized_projects_worker.rb2
-rw-r--r--app/workers/auto_devops/disable_worker.rb2
-rw-r--r--app/workers/auto_merge_process_worker.rb2
-rw-r--r--app/workers/background_migration_worker.rb24
-rw-r--r--app/workers/build_coverage_worker.rb2
-rw-r--r--app/workers/build_finished_worker.rb2
-rw-r--r--app/workers/build_hooks_worker.rb2
-rw-r--r--app/workers/build_queue_worker.rb2
-rw-r--r--app/workers/build_success_worker.rb2
-rw-r--r--app/workers/build_trace_sections_worker.rb2
-rw-r--r--app/workers/chaos/cpu_spin_worker.rb2
-rw-r--r--app/workers/chaos/db_spin_worker.rb2
-rw-r--r--app/workers/chaos/kill_worker.rb2
-rw-r--r--app/workers/chaos/leak_mem_worker.rb2
-rw-r--r--app/workers/chaos/sleep_worker.rb2
-rw-r--r--app/workers/chat_notification_worker.rb2
-rw-r--r--app/workers/ci/archive_traces_cron_worker.rb2
-rw-r--r--app/workers/ci/build_prepare_worker.rb2
-rw-r--r--app/workers/ci/build_schedule_worker.rb2
-rw-r--r--app/workers/ci/build_trace_chunk_flush_worker.rb2
-rw-r--r--app/workers/ci/create_cross_project_pipeline_worker.rb2
-rw-r--r--app/workers/ci/pipeline_bridge_status_worker.rb2
-rw-r--r--app/workers/ci/resource_groups/assign_resource_from_resource_group_worker.rb2
-rw-r--r--app/workers/cleanup_container_repository_worker.rb2
-rw-r--r--app/workers/cluster_configure_istio_worker.rb2
-rw-r--r--app/workers/cluster_configure_worker.rb2
-rw-r--r--app/workers/cluster_install_app_worker.rb2
-rw-r--r--app/workers/cluster_patch_app_worker.rb2
-rw-r--r--app/workers/cluster_project_configure_worker.rb2
-rw-r--r--app/workers/cluster_provision_worker.rb2
-rw-r--r--app/workers/cluster_upgrade_app_worker.rb2
-rw-r--r--app/workers/cluster_wait_for_app_installation_worker.rb2
-rw-r--r--app/workers/cluster_wait_for_ingress_ip_address_worker.rb2
-rw-r--r--app/workers/clusters/applications/activate_service_worker.rb2
-rw-r--r--app/workers/clusters/applications/deactivate_service_worker.rb2
-rw-r--r--app/workers/clusters/applications/uninstall_worker.rb2
-rw-r--r--app/workers/clusters/applications/wait_for_uninstall_app_worker.rb2
-rw-r--r--app/workers/clusters/cleanup/app_worker.rb2
-rw-r--r--app/workers/clusters/cleanup/project_namespace_worker.rb2
-rw-r--r--app/workers/clusters/cleanup/service_account_worker.rb2
-rw-r--r--app/workers/concerns/worker_attributes.rb8
-rw-r--r--app/workers/container_expiration_policy_worker.rb2
-rw-r--r--app/workers/create_commit_signature_worker.rb2
-rw-r--r--app/workers/create_evidence_worker.rb2
-rw-r--r--app/workers/create_note_diff_file_worker.rb2
-rw-r--r--app/workers/create_pipeline_worker.rb2
-rw-r--r--app/workers/delete_container_repository_worker.rb2
-rw-r--r--app/workers/delete_diff_files_worker.rb2
-rw-r--r--app/workers/delete_merged_branches_worker.rb2
-rw-r--r--app/workers/delete_stored_files_worker.rb2
-rw-r--r--app/workers/delete_user_worker.rb2
-rw-r--r--app/workers/deployments/finished_worker.rb2
-rw-r--r--app/workers/deployments/forward_deployment_worker.rb2
-rw-r--r--app/workers/deployments/success_worker.rb2
-rw-r--r--app/workers/detect_repository_languages_worker.rb2
-rw-r--r--app/workers/email_receiver_worker.rb2
-rw-r--r--app/workers/emails_on_push_worker.rb2
-rw-r--r--app/workers/environments/auto_stop_cron_worker.rb2
-rw-r--r--app/workers/error_tracking_issue_link_worker.rb2
-rw-r--r--app/workers/expire_build_artifacts_worker.rb2
-rw-r--r--app/workers/expire_build_instance_artifacts_worker.rb2
-rw-r--r--app/workers/expire_job_cache_worker.rb1
-rw-r--r--app/workers/expire_pipeline_cache_worker.rb2
-rw-r--r--app/workers/file_hook_worker.rb2
-rw-r--r--app/workers/git_garbage_collect_worker.rb2
-rw-r--r--app/workers/gitlab/github_import/advance_stage_worker.rb2
-rw-r--r--app/workers/gitlab/github_import/import_diff_note_worker.rb2
-rw-r--r--app/workers/gitlab/github_import/import_issue_worker.rb2
-rw-r--r--app/workers/gitlab/github_import/import_lfs_object_worker.rb2
-rw-r--r--app/workers/gitlab/github_import/import_note_worker.rb2
-rw-r--r--app/workers/gitlab/github_import/import_pull_request_worker.rb2
-rw-r--r--app/workers/gitlab/github_import/refresh_import_jid_worker.rb2
-rw-r--r--app/workers/gitlab/github_import/stage/finish_import_worker.rb2
-rw-r--r--app/workers/gitlab/github_import/stage/import_base_data_worker.rb2
-rw-r--r--app/workers/gitlab/github_import/stage/import_issues_and_diff_notes_worker.rb2
-rw-r--r--app/workers/gitlab/github_import/stage/import_lfs_objects_worker.rb2
-rw-r--r--app/workers/gitlab/github_import/stage/import_notes_worker.rb2
-rw-r--r--app/workers/gitlab/github_import/stage/import_pull_requests_worker.rb2
-rw-r--r--app/workers/gitlab/github_import/stage/import_repository_worker.rb2
-rw-r--r--app/workers/gitlab/phabricator_import/base_worker.rb2
-rw-r--r--app/workers/gitlab/phabricator_import/import_tasks_worker.rb2
-rw-r--r--app/workers/gitlab_shell_worker.rb2
-rw-r--r--app/workers/gitlab_usage_ping_worker.rb2
-rw-r--r--app/workers/group_destroy_worker.rb2
-rw-r--r--app/workers/group_export_worker.rb2
-rw-r--r--app/workers/group_import_worker.rb2
-rw-r--r--app/workers/hashed_storage/base_worker.rb2
-rw-r--r--app/workers/hashed_storage/migrator_worker.rb2
-rw-r--r--app/workers/hashed_storage/project_migrate_worker.rb2
-rw-r--r--app/workers/hashed_storage/project_rollback_worker.rb2
-rw-r--r--app/workers/hashed_storage/rollbacker_worker.rb2
-rw-r--r--app/workers/import_export_project_cleanup_worker.rb2
-rw-r--r--app/workers/import_issues_csv_worker.rb2
-rw-r--r--app/workers/incident_management/process_alert_worker.rb2
-rw-r--r--app/workers/invalid_gpg_signature_update_worker.rb2
-rw-r--r--app/workers/irker_worker.rb2
-rw-r--r--app/workers/issue_due_scheduler_worker.rb2
-rw-r--r--app/workers/mail_scheduler/issue_due_worker.rb2
-rw-r--r--app/workers/mail_scheduler/notification_service_worker.rb2
-rw-r--r--app/workers/merge_request_mergeability_check_worker.rb2
-rw-r--r--app/workers/merge_worker.rb2
-rw-r--r--app/workers/migrate_external_diffs_worker.rb2
-rw-r--r--app/workers/namespaceless_project_destroy_worker.rb2
-rw-r--r--app/workers/namespaces/prune_aggregation_schedules_worker.rb2
-rw-r--r--app/workers/namespaces/root_statistics_worker.rb2
-rw-r--r--app/workers/namespaces/schedule_aggregation_worker.rb2
-rw-r--r--app/workers/new_issue_worker.rb2
-rw-r--r--app/workers/new_merge_request_worker.rb2
-rw-r--r--app/workers/new_note_worker.rb2
-rw-r--r--app/workers/new_release_worker.rb2
-rw-r--r--app/workers/object_pool/create_worker.rb2
-rw-r--r--app/workers/object_pool/destroy_worker.rb2
-rw-r--r--app/workers/object_pool/join_worker.rb2
-rw-r--r--app/workers/object_pool/schedule_join_worker.rb2
-rw-r--r--app/workers/object_storage/background_move_worker.rb2
-rw-r--r--app/workers/object_storage/migrate_uploads_worker.rb2
-rw-r--r--app/workers/pages_domain_removal_cron_worker.rb2
-rw-r--r--app/workers/pages_domain_ssl_renewal_cron_worker.rb2
-rw-r--r--app/workers/pages_domain_ssl_renewal_worker.rb2
-rw-r--r--app/workers/pages_domain_verification_cron_worker.rb2
-rw-r--r--app/workers/pages_domain_verification_worker.rb2
-rw-r--r--app/workers/pages_worker.rb2
-rw-r--r--app/workers/personal_access_tokens/expiring_worker.rb2
-rw-r--r--app/workers/pipeline_hooks_worker.rb2
-rw-r--r--app/workers/pipeline_metrics_worker.rb2
-rw-r--r--app/workers/pipeline_notification_worker.rb2
-rw-r--r--app/workers/pipeline_process_worker.rb2
-rw-r--r--app/workers/pipeline_schedule_worker.rb2
-rw-r--r--app/workers/pipeline_success_worker.rb2
-rw-r--r--app/workers/pipeline_update_worker.rb2
-rw-r--r--app/workers/post_receive.rb2
-rw-r--r--app/workers/process_commit_worker.rb2
-rw-r--r--app/workers/project_cache_worker.rb2
-rw-r--r--app/workers/project_daily_statistics_worker.rb2
-rw-r--r--app/workers/project_destroy_worker.rb2
-rw-r--r--app/workers/project_export_worker.rb2
-rw-r--r--app/workers/project_service_worker.rb2
-rw-r--r--app/workers/propagate_service_template_worker.rb2
-rw-r--r--app/workers/prune_old_events_worker.rb2
-rw-r--r--app/workers/prune_web_hook_logs_worker.rb2
-rw-r--r--app/workers/reactive_caching_worker.rb2
-rw-r--r--app/workers/rebase_worker.rb2
-rw-r--r--app/workers/remote_mirror_notification_worker.rb2
-rw-r--r--app/workers/remove_expired_group_links_worker.rb2
-rw-r--r--app/workers/remove_expired_members_worker.rb2
-rw-r--r--app/workers/remove_unreferenced_lfs_objects_worker.rb2
-rw-r--r--app/workers/repository_archive_cache_worker.rb2
-rw-r--r--app/workers/repository_check/batch_worker.rb2
-rw-r--r--app/workers/repository_check/clear_worker.rb2
-rw-r--r--app/workers/repository_check/dispatch_worker.rb2
-rw-r--r--app/workers/repository_check/single_repository_worker.rb2
-rw-r--r--app/workers/repository_cleanup_worker.rb2
-rw-r--r--app/workers/repository_fork_worker.rb2
-rw-r--r--app/workers/repository_import_worker.rb2
-rw-r--r--app/workers/repository_remove_remote_worker.rb2
-rw-r--r--app/workers/repository_update_remote_mirror_worker.rb2
-rw-r--r--app/workers/requests_profiles_worker.rb2
-rw-r--r--app/workers/run_pipeline_schedule_worker.rb2
-rw-r--r--app/workers/schedule_migrate_external_diffs_worker.rb2
-rw-r--r--app/workers/self_monitoring_project_create_worker.rb2
-rw-r--r--app/workers/self_monitoring_project_delete_worker.rb2
-rw-r--r--app/workers/stage_update_worker.rb2
-rw-r--r--app/workers/stuck_ci_jobs_worker.rb2
-rw-r--r--app/workers/stuck_import_jobs_worker.rb2
-rw-r--r--app/workers/stuck_merge_jobs_worker.rb2
-rw-r--r--app/workers/system_hook_push_worker.rb2
-rw-r--r--app/workers/todos_destroyer/confidential_issue_worker.rb2
-rw-r--r--app/workers/todos_destroyer/entity_leave_worker.rb2
-rw-r--r--app/workers/todos_destroyer/group_private_worker.rb2
-rw-r--r--app/workers/todos_destroyer/private_features_worker.rb2
-rw-r--r--app/workers/todos_destroyer/project_private_worker.rb2
-rw-r--r--app/workers/trending_projects_worker.rb2
-rw-r--r--app/workers/update_external_pull_requests_worker.rb2
-rw-r--r--app/workers/update_head_pipeline_for_merge_request_worker.rb2
-rw-r--r--app/workers/update_merge_requests_worker.rb2
-rw-r--r--app/workers/update_project_statistics_worker.rb2
-rw-r--r--app/workers/upload_checksum_worker.rb2
-rw-r--r--app/workers/wait_for_cluster_creation_worker.rb2
-rw-r--r--app/workers/web_hook_worker.rb2
-rw-r--r--changelogs/unreleased/38096-splitmr-write-resource-milestone-events-pd.yml5
-rw-r--r--changelogs/unreleased/ak-rescue-error.yml5
-rw-r--r--changelogs/unreleased/migrate-fa-spinner-in-views-dashboard-todos.yml5
-rw-r--r--doc/development/background_migrations.md11
-rw-r--r--lib/gitlab/database/migration_helpers.rb42
-rw-r--r--lib/gitlab/sidekiq_config/dummy_worker.rb1
-rw-r--r--lib/gitlab/sidekiq_config/worker.rb5
-rw-r--r--locale/gitlab.pot3
-rw-r--r--rubocop/cop/migration/schedule_async.rb54
-rw-r--r--rubocop/cop/scalability/idempotent_worker.rb59
-rw-r--r--rubocop/migration_helpers.rb4
-rw-r--r--spec/controllers/projects/milestones_controller_spec.rb4
-rw-r--r--spec/factories/resource_milestone_event.rb12
-rw-r--r--spec/lib/gitlab/database/migration_helpers_spec.rb56
-rw-r--r--spec/lib/gitlab/import_export/all_models.yml2
-rw-r--r--spec/lib/gitlab/sidekiq_config/worker_spec.rb9
-rw-r--r--spec/models/milestone_note_spec.rb18
-rw-r--r--spec/models/resource_milestone_event_spec.rb55
-rw-r--r--spec/rubocop/cop/migration/schedule_async_spec.rb152
-rw-r--r--spec/rubocop/cop/scalability/idempotent_worker_spec.rb38
-rw-r--r--spec/rubocop/migration_helpers_spec.rb56
-rw-r--r--spec/services/issuable/clone/attributes_rewriter_spec.rb42
-rw-r--r--spec/services/issuable/common_system_notes_service_spec.rb44
-rw-r--r--spec/services/issues/update_service_spec.rb8
-rw-r--r--spec/services/merge_requests/update_service_spec.rb8
-rw-r--r--spec/services/resource_events/change_milestone_service_spec.rb67
-rw-r--r--spec/spec_helper.rb1
-rw-r--r--spec/support/helpers/idempotent_worker_helper.rb15
-rw-r--r--spec/support/shared_examples/quick_actions/issue/move_quick_action_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/resource_events.rb104
-rw-r--r--spec/support/shared_examples/workers/idempotency_shared_examples.rb31
-rw-r--r--spec/workers/background_migration_worker_spec.rb10
-rw-r--r--spec/workers/expire_job_cache_worker_spec.rb30
232 files changed, 1564 insertions, 277 deletions
diff --git a/app/assets/javascripts/boards/components/boards_selector.vue b/app/assets/javascripts/boards/components/boards_selector.vue
index eeb0fbec1ed..5e8b80cd959 100644
--- a/app/assets/javascripts/boards/components/boards_selector.vue
+++ b/app/assets/javascripts/boards/components/boards_selector.vue
@@ -110,14 +110,6 @@ export default {
board.name.toLowerCase().includes(this.filterTerm.toLowerCase()),
);
},
- reload: {
- get() {
- return this.state.reload;
- },
- set(newValue) {
- this.state.reload = newValue;
- },
- },
board() {
return this.state.currentBoard;
},
@@ -142,16 +134,6 @@ export default {
this.scrollFadeInitialized = false;
this.$nextTick(this.setScrollFade);
},
- reload() {
- if (this.reload) {
- this.boards = [];
- this.recentBoards = [];
- this.loading = true;
- this.reload = false;
-
- this.loadBoards(false);
- }
- },
},
created() {
boardsStore.setCurrentBoard(this.currentBoard);
diff --git a/app/assets/javascripts/boards/stores/boards_store.js b/app/assets/javascripts/boards/stores/boards_store.js
index e5ce8b70a4f..f233228614f 100644
--- a/app/assets/javascripts/boards/stores/boards_store.js
+++ b/app/assets/javascripts/boards/stores/boards_store.js
@@ -30,7 +30,6 @@ const boardsStore = {
labels: [],
},
currentPage: '',
- reload: false,
endpoints: {},
},
detail: {
@@ -61,7 +60,6 @@ const boardsStore = {
};
},
showPage(page) {
- this.state.reload = false;
this.state.currentPage = page;
},
addList(listObj, defaultAvatar) {
diff --git a/app/assets/stylesheets/framework/buttons.scss b/app/assets/stylesheets/framework/buttons.scss
index 1b549c0a4f0..ecbc5fa9351 100644
--- a/app/assets/stylesheets/framework/buttons.scss
+++ b/app/assets/stylesheets/framework/buttons.scss
@@ -371,8 +371,11 @@
}
.btn-loading {
- &:not(.disabled) .fa {
- display: none;
+ &:not(.disabled) {
+ .fa,
+ .spinner {
+ display: none;
+ }
}
.fa {
diff --git a/app/models/concerns/milestone_eventable.rb b/app/models/concerns/milestone_eventable.rb
new file mode 100644
index 00000000000..17a02c9d3e4
--- /dev/null
+++ b/app/models/concerns/milestone_eventable.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+module MilestoneEventable
+ extend ActiveSupport::Concern
+
+ included do
+ has_many :resource_milestone_events
+ end
+end
diff --git a/app/models/concerns/resource_event_tools.rb b/app/models/concerns/resource_event_tools.rb
new file mode 100644
index 00000000000..7226b9573e1
--- /dev/null
+++ b/app/models/concerns/resource_event_tools.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+module ResourceEventTools
+ extend ActiveSupport::Concern
+
+ included do
+ belongs_to :user
+
+ validates :user, presence: { unless: :importing? }, on: :create
+
+ validate :exactly_one_issuable
+
+ scope :created_after, ->(time) { where('created_at > ?', time) }
+ end
+
+ def exactly_one_issuable
+ issuable_count = self.class.issuable_attrs.count { |attr| self["#{attr}_id"] }
+
+ return true if issuable_count == 1
+
+ # if none of issuable IDs is set, check explicitly if nested issuable
+ # object is set, this is used during project import
+ if issuable_count == 0 && importing?
+ issuable_count = self.class.issuable_attrs.count { |attr| self.public_send(attr) } # rubocop:disable GitlabSecurity/PublicSend
+
+ return true if issuable_count == 1
+ end
+
+ errors.add(:base, "Exactly one of #{self.class.issuable_attrs.join(', ')} is required")
+ end
+end
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 83f9e803d42..1c191064d1a 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -15,6 +15,7 @@ class Issue < ApplicationRecord
include ThrottledTouch
include LabelEventable
include IgnorableColumns
+ include MilestoneEventable
DueDateStruct = Struct.new(:title, :name).freeze
NoDueDate = DueDateStruct.new('No Due Date', '0').freeze
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index b469174fc63..5dda1bd8cc7 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -18,6 +18,7 @@ class MergeRequest < ApplicationRecord
include DeprecatedAssignee
include ShaAttribute
include IgnorableColumns
+ include MilestoneEventable
sha_attribute :squash_commit_sha
diff --git a/app/models/milestone_note.rb b/app/models/milestone_note.rb
new file mode 100644
index 00000000000..8ff0503502f
--- /dev/null
+++ b/app/models/milestone_note.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+class MilestoneNote < ::Note
+ attr_accessor :resource_parent, :event, :milestone
+
+ def self.from_event(event, resource: nil, resource_parent: nil)
+ resource ||= event.resource
+
+ attrs = {
+ system: true,
+ author: event.user,
+ created_at: event.created_at,
+ noteable: resource,
+ milestone: event.milestone,
+ event: event,
+ system_note_metadata: ::SystemNoteMetadata.new(action: 'milestone'),
+ resource_parent: resource_parent
+ }
+
+ if resource_parent.is_a?(Project)
+ attrs[:project_id] = resource_parent.id
+ end
+
+ MilestoneNote.new(attrs)
+ end
+
+ def note
+ @note ||= note_text
+ end
+
+ def note_html
+ @note_html ||= Banzai::Renderer.cacheless_render_field(self, :note, { group: group, project: project })
+ end
+
+ def project
+ resource_parent if resource_parent.is_a?(Project)
+ end
+
+ def group
+ resource_parent if resource_parent.is_a?(Group)
+ end
+
+ private
+
+ def note_text(html: false)
+ format = milestone&.group_milestone? ? :name : :iid
+ milestone.nil? ? 'removed milestone' : "changed milestone to #{milestone.to_reference(project, format: format)}"
+ end
+end
diff --git a/app/models/resource_label_event.rb b/app/models/resource_label_event.rb
index 98fc9e7bae8..59907f1b962 100644
--- a/app/models/resource_label_event.rb
+++ b/app/models/resource_label_event.rb
@@ -4,20 +4,17 @@ class ResourceLabelEvent < ApplicationRecord
include Importable
include Gitlab::Utils::StrongMemoize
include CacheMarkdownField
+ include ResourceEventTools
cache_markdown_field :reference
- belongs_to :user
belongs_to :issue
belongs_to :merge_request
belongs_to :label
- scope :created_after, ->(time) { where('created_at > ?', time) }
scope :inc_relations, -> { includes(:label, :user) }
- validates :user, presence: { unless: :importing? }, on: :create
validates :label, presence: { unless: :importing? }, on: :create
- validate :exactly_one_issuable
after_save :expire_etag_cache
after_destroy :expire_etag_cache
@@ -94,22 +91,6 @@ class ResourceLabelEvent < ApplicationRecord
end
end
- def exactly_one_issuable
- issuable_count = self.class.issuable_attrs.count { |attr| self["#{attr}_id"] }
-
- return true if issuable_count == 1
-
- # if none of issuable IDs is set, check explicitly if nested issuable
- # object is set, this is used during project import
- if issuable_count == 0 && importing?
- issuable_count = self.class.issuable_attrs.count { |attr| self.public_send(attr) } # rubocop:disable GitlabSecurity/PublicSend
-
- return true if issuable_count == 1
- end
-
- errors.add(:base, "Exactly one of #{self.class.issuable_attrs.join(', ')} is required")
- end
-
def expire_etag_cache
issuable.expire_note_etag_cache
end
diff --git a/app/models/resource_milestone_event.rb b/app/models/resource_milestone_event.rb
new file mode 100644
index 00000000000..ba43a1ee363
--- /dev/null
+++ b/app/models/resource_milestone_event.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+class ResourceMilestoneEvent < ApplicationRecord
+ include Gitlab::Utils::StrongMemoize
+ include Importable
+ include ResourceEventTools
+
+ belongs_to :issue
+ belongs_to :merge_request
+ belongs_to :milestone
+
+ scope :by_issue, ->(issue) { where(issue_id: issue.id) }
+ scope :by_merge_request, ->(merge_request) { where(merge_request_id: merge_request.id) }
+
+ enum action: {
+ add: 1,
+ remove: 2
+ }
+
+ # state is used for issue and merge request states.
+ enum state: Issue.available_states.merge(MergeRequest.available_states)
+
+ def self.issuable_attrs
+ %i(issue merge_request).freeze
+ end
+
+ def resource
+ issue || merge_request
+ end
+end
diff --git a/app/services/issuable/clone/attributes_rewriter.rb b/app/services/issuable/clone/attributes_rewriter.rb
index 2b436f6322c..135ab011d69 100644
--- a/app/services/issuable/clone/attributes_rewriter.rb
+++ b/app/services/issuable/clone/attributes_rewriter.rb
@@ -19,6 +19,7 @@ module Issuable
copy_resource_label_events
copy_resource_weight_events
+ copy_resource_milestone_events
end
private
@@ -65,6 +66,23 @@ module Issuable
end
end
+ def copy_resource_milestone_events
+ entity_key = new_entity.class.name.underscore.foreign_key
+
+ copy_events(ResourceMilestoneEvent.table_name, original_entity.resource_milestone_events) do |event|
+ matching_destination_milestone = matching_milestone(event.milestone.title)
+
+ if matching_destination_milestone.present?
+ event.attributes
+ .except('id', 'reference', 'reference_html')
+ .merge(entity_key => new_entity.id,
+ 'milestone_id' => matching_destination_milestone.id,
+ 'action' => ResourceMilestoneEvent.actions[event.action],
+ 'state' => ResourceMilestoneEvent.states[event.state])
+ end
+ end
+ end
+
def copy_events(table_name, events_to_copy)
events_to_copy.find_in_batches do |batch|
events = batch.map do |event|
diff --git a/app/services/issuable/common_system_notes_service.rb b/app/services/issuable/common_system_notes_service.rb
index 846b881e819..c53e19c922a 100644
--- a/app/services/issuable/common_system_notes_service.rb
+++ b/app/services/issuable/common_system_notes_service.rb
@@ -22,13 +22,17 @@ module Issuable
end
create_due_date_note if issuable.previous_changes.include?('due_date')
- create_milestone_note if issuable.previous_changes.include?('milestone_id')
+ create_milestone_note if has_milestone_changes?
create_labels_note(old_labels) if old_labels && issuable.labels != old_labels
end
end
private
+ def has_milestone_changes?
+ issuable.previous_changes.include?('milestone_id')
+ end
+
def handle_time_tracking_note
if issuable.previous_changes.include?('time_estimate')
create_time_estimate_note
@@ -95,7 +99,16 @@ module Issuable
end
def create_milestone_note
- SystemNoteService.change_milestone(issuable, issuable.project, current_user, issuable.milestone)
+ if milestone_changes_tracking_enabled?
+ # Creates a synthetic note
+ ResourceEvents::ChangeMilestoneService.new(resource: issuable, user: current_user).execute
+ else
+ SystemNoteService.change_milestone(issuable, issuable.project, current_user, issuable.milestone)
+ end
+ end
+
+ def milestone_changes_tracking_enabled?
+ ::Feature.enabled?(:track_resource_milestone_change_events, issuable.project)
end
def create_due_date_note
diff --git a/app/services/resource_events/change_milestone_service.rb b/app/services/resource_events/change_milestone_service.rb
new file mode 100644
index 00000000000..bad7d002c65
--- /dev/null
+++ b/app/services/resource_events/change_milestone_service.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+module ResourceEvents
+ class ChangeMilestoneService
+ attr_reader :resource, :user, :event_created_at, :resource_args
+
+ def initialize(resource:, user:, created_at: Time.now)
+ @resource = resource
+ @user = user
+ @event_created_at = created_at
+
+ @resource_args = {
+ user_id: user.id,
+ created_at: event_created_at
+ }
+ end
+
+ def execute
+ args = build_resource_args
+
+ action = if milestone.nil?
+ :remove
+ else
+ :add
+ end
+
+ record = args.merge(milestone_id: milestone&.id, action: ResourceMilestoneEvent.actions[action])
+
+ create_event(record)
+ end
+
+ private
+
+ def milestone
+ resource&.milestone
+ end
+
+ def create_event(record)
+ ResourceMilestoneEvent.create(record)
+
+ resource.expire_note_etag_cache
+ end
+
+ def build_resource_args
+ key = resource.class.name.underscore.foreign_key
+
+ resource_args.merge(key => resource.id, state: ResourceMilestoneEvent.states[resource.state])
+ end
+ end
+end
diff --git a/app/services/resource_events/merge_into_notes_service.rb b/app/services/resource_events/merge_into_notes_service.rb
index 47948fcff6e..4aa9bb80229 100644
--- a/app/services/resource_events/merge_into_notes_service.rb
+++ b/app/services/resource_events/merge_into_notes_service.rb
@@ -9,6 +9,11 @@ module ResourceEvents
class MergeIntoNotesService
include Gitlab::Utils::StrongMemoize
+ SYNTHETIC_NOTE_BUILDER_SERVICES = [
+ SyntheticLabelNotesBuilderService,
+ SyntheticMilestoneNotesBuilderService
+ ].freeze
+
attr_reader :resource, :current_user, :params
def initialize(resource, current_user, params = {})
@@ -24,7 +29,9 @@ module ResourceEvents
private
def synthetic_notes
- SyntheticLabelNotesBuilderService.new(resource, current_user, params).execute
+ SYNTHETIC_NOTE_BUILDER_SERVICES.flat_map do |service|
+ service.new(resource, current_user, params).execute
+ end
end
end
end
diff --git a/app/services/resource_events/synthetic_milestone_notes_builder_service.rb b/app/services/resource_events/synthetic_milestone_notes_builder_service.rb
new file mode 100644
index 00000000000..ad58417834e
--- /dev/null
+++ b/app/services/resource_events/synthetic_milestone_notes_builder_service.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+# We store events about resource milestone changes in a separate table,
+# but we still want to display notes about milestone changes
+# as classic system notes in UI. This service generates "synthetic" notes for
+# milestone event changes.
+
+module ResourceEvents
+ class SyntheticMilestoneNotesBuilderService < BaseSyntheticNotesBuilderService
+ private
+
+ def synthetic_notes
+ return [] unless tracking_enabled?
+
+ milestone_change_events.map do |event|
+ MilestoneNote.from_event(event, resource: resource, resource_parent: resource_parent)
+ end
+ end
+
+ def milestone_change_events
+ return [] unless resource.respond_to?(:resource_milestone_events)
+
+ events = resource.resource_milestone_events.includes(user: :status) # rubocop: disable CodeReuse/ActiveRecord
+ since_fetch_at(events)
+ end
+
+ def tracking_enabled?
+ ::Feature.enabled?(:track_resource_milestone_change_events, resource.project)
+ end
+ end
+end
diff --git a/app/views/dashboard/todos/_todo.html.haml b/app/views/dashboard/todos/_todo.html.haml
index fdb71d3a221..f5ffe8f2e36 100644
--- a/app/views/dashboard/todos/_todo.html.haml
+++ b/app/views/dashboard/todos/_todo.html.haml
@@ -48,14 +48,14 @@
- if todo.pending?
.todo-actions
- = link_to dashboard_todo_path(todo), method: :delete, class: 'btn btn-loading js-done-todo', data: { href: dashboard_todo_path(todo) } do
+ = link_to dashboard_todo_path(todo), method: :delete, class: 'btn btn-loading d-flex align-items-center js-done-todo', data: { href: dashboard_todo_path(todo) } do
Done
- = icon('spinner spin')
- = link_to restore_dashboard_todo_path(todo), method: :patch, class: 'btn btn-loading js-undo-todo hidden', data: { href: restore_dashboard_todo_path(todo) } do
+ %span.spinner.ml-1
+ = link_to restore_dashboard_todo_path(todo), method: :patch, class: 'btn btn-loading d-flex align-items-center js-undo-todo hidden', data: { href: restore_dashboard_todo_path(todo) } do
Undo
- = icon('spinner spin')
+ %span.spinner.ml-1
- else
.todo-actions
- = link_to restore_dashboard_todo_path(todo), method: :patch, class: 'btn btn-loading js-add-todo', data: { href: restore_dashboard_todo_path(todo) } do
+ = link_to restore_dashboard_todo_path(todo), method: :patch, class: 'btn btn-loading d-flex align-items-center js-add-todo', data: { href: restore_dashboard_todo_path(todo) } do
Add a To Do
- = icon('spinner spin')
+ %span.spinner.ml-1
diff --git a/app/views/dashboard/todos/index.html.haml b/app/views/dashboard/todos/index.html.haml
index 731e763f2be..cfc637592d3 100644
--- a/app/views/dashboard/todos/index.html.haml
+++ b/app/views/dashboard/todos/index.html.haml
@@ -26,12 +26,12 @@
.nav-controls
- if @todos.any?(&:pending?)
.append-right-default
- = link_to destroy_all_dashboard_todos_path(todos_filter_params), class: 'btn btn-loading js-todos-mark-all', method: :delete, data: { href: destroy_all_dashboard_todos_path(todos_filter_params) } do
+ = link_to destroy_all_dashboard_todos_path(todos_filter_params), class: 'btn btn-loading d-flex align-items-center js-todos-mark-all', method: :delete, data: { href: destroy_all_dashboard_todos_path(todos_filter_params) } do
Mark all as done
- = icon('spinner spin')
- = link_to bulk_restore_dashboard_todos_path, class: 'btn btn-loading js-todos-undo-all hidden', method: :patch , data: { href: bulk_restore_dashboard_todos_path(todos_filter_params) } do
+ %span.spinner.ml-1
+ = link_to bulk_restore_dashboard_todos_path, class: 'btn btn-loading d-flex align-items-center js-todos-undo-all hidden', method: :patch , data: { href: bulk_restore_dashboard_todos_path(todos_filter_params) } do
Undo mark all as done
- = icon('spinner spin')
+ %span.spinner.ml-1
.todos-filters
.issues-details-filters.row-content-block.second-block
diff --git a/app/workers/admin_email_worker.rb b/app/workers/admin_email_worker.rb
index 9388b1014ac..c84ac60d777 100644
--- a/app/workers/admin_email_worker.rb
+++ b/app/workers/admin_email_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class AdminEmailWorker
+class AdminEmailWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
# rubocop:disable Scalability/CronWorkerContext
# This worker does not perform work scoped to a context
diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml
index 459872965f8..e8682769720 100644
--- a/app/workers/all_queues.yml
+++ b/app/workers/all_queues.yml
@@ -9,1077 +9,1257 @@
:latency_sensitive:
:resource_boundary: :unknown
:weight: 2
+ :idempotent:
- :name: auto_merge:auto_merge_process
:feature_category: :continuous_delivery
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :cpu
:weight: 3
+ :idempotent:
- :name: chaos:chaos_cpu_spin
:feature_category: :chaos_engineering
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 2
+ :idempotent:
- :name: chaos:chaos_db_spin
:feature_category: :chaos_engineering
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 2
+ :idempotent:
- :name: chaos:chaos_kill
:feature_category: :chaos_engineering
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 2
+ :idempotent:
- :name: chaos:chaos_leak_mem
:feature_category: :chaos_engineering
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 2
+ :idempotent:
- :name: chaos:chaos_sleep
:feature_category: :chaos_engineering
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 2
+ :idempotent:
- :name: container_repository:cleanup_container_repository
:feature_category: :container_registry
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: container_repository:delete_container_repository
:feature_category: :container_registry
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: cronjob:admin_email
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: cronjob:ci_archive_traces_cron
:feature_category: :continuous_integration
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: cronjob:container_expiration_policy
:feature_category: :container_registry
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: cronjob:environments_auto_stop_cron
:feature_category: :continuous_delivery
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: cronjob:expire_build_artifacts
:feature_category: :continuous_integration
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: cronjob:gitlab_usage_ping
:feature_category: :collection
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: cronjob:import_export_project_cleanup
:feature_category: :importers
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: cronjob:issue_due_scheduler
:feature_category: :issue_tracking
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: cronjob:namespaces_prune_aggregation_schedules
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :cpu
:weight: 1
+ :idempotent:
- :name: cronjob:pages_domain_removal_cron
:feature_category: :pages
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :cpu
:weight: 1
+ :idempotent:
- :name: cronjob:pages_domain_ssl_renewal_cron
:feature_category: :pages
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: cronjob:pages_domain_verification_cron
:feature_category: :pages
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: cronjob:personal_access_tokens_expiring
:feature_category: :authentication_and_authorization
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: cronjob:pipeline_schedule
:feature_category: :continuous_integration
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :cpu
:weight: 1
+ :idempotent:
- :name: cronjob:prune_old_events
:feature_category: :users
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: cronjob:prune_web_hook_logs
:feature_category: :integrations
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: cronjob:remove_expired_group_links
:feature_category: :authentication_and_authorization
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: cronjob:remove_expired_members
:feature_category: :authentication_and_authorization
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :cpu
:weight: 1
+ :idempotent:
- :name: cronjob:remove_unreferenced_lfs_objects
:feature_category: :git_lfs
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: cronjob:repository_archive_cache
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: cronjob:repository_check_dispatch
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: cronjob:requests_profiles
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: cronjob:schedule_migrate_external_diffs
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: cronjob:stuck_ci_jobs
:feature_category: :continuous_integration
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :cpu
:weight: 1
+ :idempotent:
- :name: cronjob:stuck_import_jobs
:feature_category: :importers
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :cpu
:weight: 1
+ :idempotent:
- :name: cronjob:stuck_merge_jobs
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: cronjob:trending_projects
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: deployment:deployments_finished
:feature_category: :continuous_delivery
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :cpu
:weight: 3
+ :idempotent:
- :name: deployment:deployments_forward_deployment
:feature_category: :continuous_delivery
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 3
+ :idempotent:
- :name: deployment:deployments_success
:feature_category: :continuous_delivery
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :cpu
:weight: 3
+ :idempotent:
- :name: gcp_cluster:cluster_configure
:feature_category: :kubernetes_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: gcp_cluster:cluster_configure_istio
:feature_category: :kubernetes_management
:has_external_dependencies: true
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: gcp_cluster:cluster_install_app
:feature_category: :kubernetes_management
:has_external_dependencies: true
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: gcp_cluster:cluster_patch_app
:feature_category: :kubernetes_management
:has_external_dependencies: true
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: gcp_cluster:cluster_project_configure
:feature_category: :kubernetes_management
:has_external_dependencies: true
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: gcp_cluster:cluster_provision
:feature_category: :kubernetes_management
:has_external_dependencies: true
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: gcp_cluster:cluster_upgrade_app
:feature_category: :kubernetes_management
:has_external_dependencies: true
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: gcp_cluster:cluster_wait_for_app_installation
:feature_category: :kubernetes_management
:has_external_dependencies: true
:latency_sensitive:
:resource_boundary: :cpu
:weight: 1
+ :idempotent:
- :name: gcp_cluster:cluster_wait_for_ingress_ip_address
:feature_category: :kubernetes_management
:has_external_dependencies: true
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: gcp_cluster:clusters_applications_activate_service
:feature_category: :kubernetes_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: gcp_cluster:clusters_applications_deactivate_service
:feature_category: :kubernetes_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: gcp_cluster:clusters_applications_uninstall
:feature_category: :kubernetes_management
:has_external_dependencies: true
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: gcp_cluster:clusters_applications_wait_for_uninstall_app
:feature_category: :kubernetes_management
:has_external_dependencies: true
:latency_sensitive:
:resource_boundary: :cpu
:weight: 1
+ :idempotent:
- :name: gcp_cluster:clusters_cleanup_app
:feature_category: :kubernetes_management
:has_external_dependencies: true
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: gcp_cluster:clusters_cleanup_project_namespace
:feature_category: :kubernetes_management
:has_external_dependencies: true
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: gcp_cluster:clusters_cleanup_service_account
:feature_category: :kubernetes_management
:has_external_dependencies: true
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: gcp_cluster:wait_for_cluster_creation
:feature_category: :kubernetes_management
:has_external_dependencies: true
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: github_importer:github_import_import_diff_note
:feature_category: :importers
:has_external_dependencies: true
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: github_importer:github_import_import_issue
:feature_category: :importers
:has_external_dependencies: true
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: github_importer:github_import_import_lfs_object
:feature_category: :importers
:has_external_dependencies: true
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: github_importer:github_import_import_note
:feature_category: :importers
:has_external_dependencies: true
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: github_importer:github_import_import_pull_request
:feature_category: :importers
:has_external_dependencies: true
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: github_importer:github_import_refresh_import_jid
:feature_category: :importers
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: github_importer:github_import_stage_finish_import
:feature_category: :importers
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: github_importer:github_import_stage_import_base_data
:feature_category: :importers
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: github_importer:github_import_stage_import_issues_and_diff_notes
:feature_category: :importers
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: github_importer:github_import_stage_import_lfs_objects
:feature_category: :importers
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: github_importer:github_import_stage_import_notes
:feature_category: :importers
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: github_importer:github_import_stage_import_pull_requests
:feature_category: :importers
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: github_importer:github_import_stage_import_repository
:feature_category: :importers
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: hashed_storage:hashed_storage_migrator
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: hashed_storage:hashed_storage_project_migrate
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: hashed_storage:hashed_storage_project_rollback
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: hashed_storage:hashed_storage_rollbacker
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: incident_management:incident_management_process_alert
:feature_category: :incident_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 2
+ :idempotent:
- :name: mail_scheduler:mail_scheduler_issue_due
:feature_category: :issue_tracking
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 2
+ :idempotent:
- :name: mail_scheduler:mail_scheduler_notification_service
:feature_category: :issue_tracking
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :cpu
:weight: 2
+ :idempotent:
- :name: notifications:new_release
:feature_category: :release_orchestration
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 2
+ :idempotent:
- :name: object_pool:object_pool_create
:feature_category: :gitaly
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: object_pool:object_pool_destroy
:feature_category: :gitaly
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: object_pool:object_pool_join
:feature_category: :gitaly
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :cpu
:weight: 1
+ :idempotent:
- :name: object_pool:object_pool_schedule_join
:feature_category: :gitaly
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: object_storage:object_storage_background_move
:feature_category: :not_owned
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: object_storage:object_storage_migrate_uploads
:feature_category: :not_owned
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: pipeline_background:archive_trace
:feature_category: :continuous_integration
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: pipeline_background:ci_build_trace_chunk_flush
:feature_category: :continuous_integration
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: pipeline_cache:expire_job_cache
:feature_category: :continuous_integration
:has_external_dependencies:
:latency_sensitive: true
:resource_boundary: :unknown
:weight: 3
+ :idempotent: true
- :name: pipeline_cache:expire_pipeline_cache
:feature_category: :continuous_integration
:has_external_dependencies:
:latency_sensitive: true
:resource_boundary: :cpu
:weight: 3
+ :idempotent:
- :name: pipeline_creation:create_pipeline
:feature_category: :continuous_integration
:has_external_dependencies:
:latency_sensitive: true
:resource_boundary: :cpu
:weight: 4
+ :idempotent:
- :name: pipeline_creation:run_pipeline_schedule
:feature_category: :continuous_integration
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 4
+ :idempotent:
- :name: pipeline_default:build_coverage
:feature_category: :continuous_integration
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 3
+ :idempotent:
- :name: pipeline_default:build_trace_sections
:feature_category: :continuous_integration
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 3
+ :idempotent:
- :name: pipeline_default:ci_create_cross_project_pipeline
:feature_category: :continuous_integration
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :cpu
:weight: 3
+ :idempotent:
- :name: pipeline_default:ci_pipeline_bridge_status
:feature_category: :continuous_integration
:has_external_dependencies:
:latency_sensitive: true
:resource_boundary: :cpu
:weight: 3
+ :idempotent:
- :name: pipeline_default:pipeline_metrics
:feature_category: :continuous_integration
:has_external_dependencies:
:latency_sensitive: true
:resource_boundary: :unknown
:weight: 3
+ :idempotent:
- :name: pipeline_default:pipeline_notification
:feature_category: :continuous_integration
:has_external_dependencies:
:latency_sensitive: true
:resource_boundary: :cpu
:weight: 3
+ :idempotent:
- :name: pipeline_hooks:build_hooks
:feature_category: :continuous_integration
:has_external_dependencies:
:latency_sensitive: true
:resource_boundary: :unknown
:weight: 2
+ :idempotent:
- :name: pipeline_hooks:pipeline_hooks
:feature_category: :continuous_integration
:has_external_dependencies:
:latency_sensitive: true
:resource_boundary: :cpu
:weight: 2
+ :idempotent:
- :name: pipeline_processing:build_finished
:feature_category: :continuous_integration
:has_external_dependencies:
:latency_sensitive: true
:resource_boundary: :cpu
:weight: 5
+ :idempotent:
- :name: pipeline_processing:build_queue
:feature_category: :continuous_integration
:has_external_dependencies:
:latency_sensitive: true
:resource_boundary: :cpu
:weight: 5
+ :idempotent:
- :name: pipeline_processing:build_success
:feature_category: :continuous_integration
:has_external_dependencies:
:latency_sensitive: true
:resource_boundary: :unknown
:weight: 5
+ :idempotent:
- :name: pipeline_processing:ci_build_prepare
:feature_category: :continuous_integration
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 5
+ :idempotent:
- :name: pipeline_processing:ci_build_schedule
:feature_category: :continuous_integration
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :cpu
:weight: 5
+ :idempotent:
- :name: pipeline_processing:ci_resource_groups_assign_resource_from_resource_group
:feature_category: :continuous_delivery
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 5
+ :idempotent:
- :name: pipeline_processing:pipeline_process
:feature_category: :continuous_integration
:has_external_dependencies:
:latency_sensitive: true
:resource_boundary: :unknown
:weight: 5
+ :idempotent:
- :name: pipeline_processing:pipeline_success
:feature_category: :continuous_integration
:has_external_dependencies:
:latency_sensitive: true
:resource_boundary: :unknown
:weight: 5
+ :idempotent:
- :name: pipeline_processing:pipeline_update
:feature_category: :continuous_integration
:has_external_dependencies:
:latency_sensitive: true
:resource_boundary: :unknown
:weight: 5
+ :idempotent:
- :name: pipeline_processing:stage_update
:feature_category: :continuous_integration
:has_external_dependencies:
:latency_sensitive: true
:resource_boundary: :unknown
:weight: 5
+ :idempotent:
- :name: pipeline_processing:update_head_pipeline_for_merge_request
:feature_category: :continuous_integration
:has_external_dependencies:
:latency_sensitive: true
:resource_boundary: :cpu
:weight: 5
+ :idempotent:
- :name: repository_check:repository_check_batch
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: repository_check:repository_check_clear
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: repository_check:repository_check_single_repository
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: todos_destroyer:todos_destroyer_confidential_issue
:feature_category: :issue_tracking
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: todos_destroyer:todos_destroyer_entity_leave
:feature_category: :issue_tracking
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: todos_destroyer:todos_destroyer_group_private
:feature_category: :issue_tracking
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: todos_destroyer:todos_destroyer_private_features
:feature_category: :issue_tracking
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: todos_destroyer:todos_destroyer_project_private
:feature_category: :issue_tracking
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: update_namespace_statistics:namespaces_root_statistics
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: update_namespace_statistics:namespaces_schedule_aggregation
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: authorized_projects
:feature_category: :authentication_and_authorization
:has_external_dependencies:
:latency_sensitive: true
:resource_boundary: :unknown
:weight: 2
+ :idempotent:
- :name: background_migration
:feature_category: :not_owned
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: chat_notification
:feature_category: :chatops
:has_external_dependencies:
:latency_sensitive: true
:resource_boundary: :unknown
:weight: 2
+ :idempotent:
- :name: create_commit_signature
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 2
+ :idempotent:
- :name: create_evidence
:feature_category: :release_governance
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 2
+ :idempotent:
- :name: create_note_diff_file
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: default
:feature_category:
:has_external_dependencies:
:latency_sensitive:
:resource_boundary:
:weight: 1
+ :idempotent:
- :name: delete_diff_files
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: delete_merged_branches
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: delete_stored_files
:feature_category: :not_owned
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: delete_user
:feature_category: :authentication_and_authorization
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: detect_repository_languages
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: email_receiver
:feature_category: :issue_tracking
:has_external_dependencies:
:latency_sensitive: true
:resource_boundary: :unknown
:weight: 2
+ :idempotent:
- :name: emails_on_push
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive: true
:resource_boundary: :cpu
:weight: 2
+ :idempotent:
- :name: error_tracking_issue_link
:feature_category: :error_tracking
:has_external_dependencies: true
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: expire_build_instance_artifacts
:feature_category: :continuous_integration
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: file_hook
:feature_category: :integrations
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: git_garbage_collect
:feature_category: :gitaly
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: github_import_advance_stage
:feature_category: :importers
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: gitlab_shell
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive: true
:resource_boundary: :unknown
:weight: 2
+ :idempotent:
- :name: group_destroy
:feature_category: :subgroups
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: group_export
:feature_category: :importers
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: group_import
:feature_category: :importers
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: import_issues_csv
:feature_category: :issue_tracking
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :cpu
:weight: 2
+ :idempotent:
- :name: invalid_gpg_signature_update
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 2
+ :idempotent:
- :name: irker
:feature_category: :integrations
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: mailers
:feature_category:
:has_external_dependencies:
:latency_sensitive:
:resource_boundary:
:weight: 2
+ :idempotent:
- :name: merge
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive: true
:resource_boundary: :unknown
:weight: 5
+ :idempotent:
- :name: merge_request_mergeability_check
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: migrate_external_diffs
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: namespaceless_project_destroy
:feature_category: :authentication_and_authorization
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: new_issue
:feature_category: :issue_tracking
:has_external_dependencies:
:latency_sensitive: true
:resource_boundary: :cpu
:weight: 2
+ :idempotent:
- :name: new_merge_request
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive: true
:resource_boundary: :cpu
:weight: 2
+ :idempotent:
- :name: new_note
:feature_category: :issue_tracking
:has_external_dependencies:
:latency_sensitive: true
:resource_boundary: :cpu
:weight: 2
+ :idempotent:
- :name: pages
:feature_category: :pages
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: pages_domain_ssl_renewal
:feature_category: :pages
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: pages_domain_verification
:feature_category: :pages
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: phabricator_import_import_tasks
:feature_category: :importers
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: post_receive
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive: true
:resource_boundary: :cpu
:weight: 5
+ :idempotent:
- :name: process_commit
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive: true
:resource_boundary: :unknown
:weight: 3
+ :idempotent:
- :name: project_cache
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive: true
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: project_daily_statistics
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: project_destroy
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: project_export
:feature_category: :importers
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :memory
:weight: 1
+ :idempotent:
- :name: project_service
:feature_category: :integrations
:has_external_dependencies: true
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: propagate_service_template
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: reactive_caching
:feature_category: :not_owned
:has_external_dependencies:
:latency_sensitive: true
:resource_boundary: :cpu
:weight: 1
+ :idempotent:
- :name: rebase
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 2
+ :idempotent:
- :name: remote_mirror_notification
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 2
+ :idempotent:
- :name: repository_cleanup
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: repository_fork
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: repository_import
:feature_category: :importers
:has_external_dependencies: true
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: repository_remove_remote
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: repository_update_remote_mirror
:feature_category: :source_code_management
:has_external_dependencies: true
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: self_monitoring_project_create
:feature_category: :metrics
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 2
+ :idempotent:
- :name: self_monitoring_project_delete
:feature_category: :metrics
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 2
+ :idempotent:
- :name: system_hook_push
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: update_external_pull_requests
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 3
+ :idempotent:
- :name: update_merge_requests
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive: true
:resource_boundary: :cpu
:weight: 3
+ :idempotent:
- :name: update_project_statistics
:feature_category: :source_code_management
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: upload_checksum
:feature_category: :geo_replication
:has_external_dependencies:
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
- :name: web_hook
:feature_category: :integrations
:has_external_dependencies: true
:latency_sensitive:
:resource_boundary: :unknown
:weight: 1
+ :idempotent:
diff --git a/app/workers/archive_trace_worker.rb b/app/workers/archive_trace_worker.rb
index 66f9b8d9e80..3ddb5686bf2 100644
--- a/app/workers/archive_trace_worker.rb
+++ b/app/workers/archive_trace_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ArchiveTraceWorker
+class ArchiveTraceWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include PipelineBackgroundQueue
diff --git a/app/workers/authorized_projects_worker.rb b/app/workers/authorized_projects_worker.rb
index 1ab2fd6023f..cd7ce386433 100644
--- a/app/workers/authorized_projects_worker.rb
+++ b/app/workers/authorized_projects_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class AuthorizedProjectsWorker
+class AuthorizedProjectsWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
prepend WaitableWorker
diff --git a/app/workers/auto_devops/disable_worker.rb b/app/workers/auto_devops/disable_worker.rb
index 73ddc591505..bae08cf9e18 100644
--- a/app/workers/auto_devops/disable_worker.rb
+++ b/app/workers/auto_devops/disable_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module AutoDevops
- class DisableWorker
+ class DisableWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include AutoDevopsQueue
diff --git a/app/workers/auto_merge_process_worker.rb b/app/workers/auto_merge_process_worker.rb
index 1681fac3363..2599c76c900 100644
--- a/app/workers/auto_merge_process_worker.rb
+++ b/app/workers/auto_merge_process_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class AutoMergeProcessWorker
+class AutoMergeProcessWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
queue_namespace :auto_merge
diff --git a/app/workers/background_migration_worker.rb b/app/workers/background_migration_worker.rb
index 20e2cdd7f96..231c2bcd83b 100644
--- a/app/workers/background_migration_worker.rb
+++ b/app/workers/background_migration_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class BackgroundMigrationWorker
+class BackgroundMigrationWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category_not_owned!
@@ -22,17 +22,19 @@ class BackgroundMigrationWorker
# class_name - The class name of the background migration to run.
# arguments - The arguments to pass to the migration class.
def perform(class_name, arguments = [])
- should_perform, ttl = perform_and_ttl(class_name)
+ with_context(caller_id: class_name.to_s) do
+ should_perform, ttl = perform_and_ttl(class_name)
- if should_perform
- Gitlab::BackgroundMigration.perform(class_name, arguments)
- else
- # If the lease could not be obtained this means either another process is
- # running a migration of this class or we ran one recently. In this case
- # we'll reschedule the job in such a way that it is picked up again around
- # the time the lease expires.
- self.class
- .perform_in(ttl || self.class.minimum_interval, class_name, arguments)
+ if should_perform
+ Gitlab::BackgroundMigration.perform(class_name, arguments)
+ else
+ # If the lease could not be obtained this means either another process is
+ # running a migration of this class or we ran one recently. In this case
+ # we'll reschedule the job in such a way that it is picked up again around
+ # the time the lease expires.
+ self.class
+ .perform_in(ttl || self.class.minimum_interval, class_name, arguments)
+ end
end
end
diff --git a/app/workers/build_coverage_worker.rb b/app/workers/build_coverage_worker.rb
index 912c53e11f8..7d893024abc 100644
--- a/app/workers/build_coverage_worker.rb
+++ b/app/workers/build_coverage_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class BuildCoverageWorker
+class BuildCoverageWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include PipelineQueue
diff --git a/app/workers/build_finished_worker.rb b/app/workers/build_finished_worker.rb
index 77ce0923307..0e69aa07cc1 100644
--- a/app/workers/build_finished_worker.rb
+++ b/app/workers/build_finished_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class BuildFinishedWorker
+class BuildFinishedWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include PipelineQueue
diff --git a/app/workers/build_hooks_worker.rb b/app/workers/build_hooks_worker.rb
index fa55769e486..2662e991773 100644
--- a/app/workers/build_hooks_worker.rb
+++ b/app/workers/build_hooks_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class BuildHooksWorker
+class BuildHooksWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include PipelineQueue
diff --git a/app/workers/build_queue_worker.rb b/app/workers/build_queue_worker.rb
index 6f75f403e6e..16d347a0e5c 100644
--- a/app/workers/build_queue_worker.rb
+++ b/app/workers/build_queue_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class BuildQueueWorker
+class BuildQueueWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include PipelineQueue
diff --git a/app/workers/build_success_worker.rb b/app/workers/build_success_worker.rb
index b7dbd367fee..cb670b5bca7 100644
--- a/app/workers/build_success_worker.rb
+++ b/app/workers/build_success_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class BuildSuccessWorker
+class BuildSuccessWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include PipelineQueue
diff --git a/app/workers/build_trace_sections_worker.rb b/app/workers/build_trace_sections_worker.rb
index 0641130fd64..c25f77974e9 100644
--- a/app/workers/build_trace_sections_worker.rb
+++ b/app/workers/build_trace_sections_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class BuildTraceSectionsWorker
+class BuildTraceSectionsWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include PipelineQueue
diff --git a/app/workers/chaos/cpu_spin_worker.rb b/app/workers/chaos/cpu_spin_worker.rb
index 43a32c3274f..0b565e0d49c 100644
--- a/app/workers/chaos/cpu_spin_worker.rb
+++ b/app/workers/chaos/cpu_spin_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module Chaos
- class CpuSpinWorker
+ class CpuSpinWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ChaosQueue
diff --git a/app/workers/chaos/db_spin_worker.rb b/app/workers/chaos/db_spin_worker.rb
index 217ddabbcb6..099660d440c 100644
--- a/app/workers/chaos/db_spin_worker.rb
+++ b/app/workers/chaos/db_spin_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module Chaos
- class DbSpinWorker
+ class DbSpinWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ChaosQueue
diff --git a/app/workers/chaos/kill_worker.rb b/app/workers/chaos/kill_worker.rb
index 80f04db1be4..3dedd47a1f9 100644
--- a/app/workers/chaos/kill_worker.rb
+++ b/app/workers/chaos/kill_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module Chaos
- class KillWorker
+ class KillWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ChaosQueue
diff --git a/app/workers/chaos/leak_mem_worker.rb b/app/workers/chaos/leak_mem_worker.rb
index 0caa99e0de9..b77d1a20541 100644
--- a/app/workers/chaos/leak_mem_worker.rb
+++ b/app/workers/chaos/leak_mem_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module Chaos
- class LeakMemWorker
+ class LeakMemWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ChaosQueue
diff --git a/app/workers/chaos/sleep_worker.rb b/app/workers/chaos/sleep_worker.rb
index 7c724c4cb4e..6887258e961 100644
--- a/app/workers/chaos/sleep_worker.rb
+++ b/app/workers/chaos/sleep_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module Chaos
- class SleepWorker
+ class SleepWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ChaosQueue
diff --git a/app/workers/chat_notification_worker.rb b/app/workers/chat_notification_worker.rb
index f23c787559f..78d4206ec1a 100644
--- a/app/workers/chat_notification_worker.rb
+++ b/app/workers/chat_notification_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ChatNotificationWorker
+class ChatNotificationWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
TimeoutExceeded = Class.new(StandardError)
diff --git a/app/workers/ci/archive_traces_cron_worker.rb b/app/workers/ci/archive_traces_cron_worker.rb
index c73c7ba2dd8..0171c1d482d 100644
--- a/app/workers/ci/archive_traces_cron_worker.rb
+++ b/app/workers/ci/archive_traces_cron_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module Ci
- class ArchiveTracesCronWorker
+ class ArchiveTracesCronWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include CronjobQueue # rubocop:disable Scalability/CronWorkerContext
diff --git a/app/workers/ci/build_prepare_worker.rb b/app/workers/ci/build_prepare_worker.rb
index 20208c18d03..7f640633070 100644
--- a/app/workers/ci/build_prepare_worker.rb
+++ b/app/workers/ci/build_prepare_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module Ci
- class BuildPrepareWorker
+ class BuildPrepareWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include PipelineQueue
diff --git a/app/workers/ci/build_schedule_worker.rb b/app/workers/ci/build_schedule_worker.rb
index e34f16f46c2..9231b40978d 100644
--- a/app/workers/ci/build_schedule_worker.rb
+++ b/app/workers/ci/build_schedule_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module Ci
- class BuildScheduleWorker
+ class BuildScheduleWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include PipelineQueue
diff --git a/app/workers/ci/build_trace_chunk_flush_worker.rb b/app/workers/ci/build_trace_chunk_flush_worker.rb
index 23a11c28f9b..fe59ba896a4 100644
--- a/app/workers/ci/build_trace_chunk_flush_worker.rb
+++ b/app/workers/ci/build_trace_chunk_flush_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module Ci
- class BuildTraceChunkFlushWorker
+ class BuildTraceChunkFlushWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include PipelineBackgroundQueue
diff --git a/app/workers/ci/create_cross_project_pipeline_worker.rb b/app/workers/ci/create_cross_project_pipeline_worker.rb
index 91e9317713e..713d0092b32 100644
--- a/app/workers/ci/create_cross_project_pipeline_worker.rb
+++ b/app/workers/ci/create_cross_project_pipeline_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module Ci
- class CreateCrossProjectPipelineWorker
+ class CreateCrossProjectPipelineWorker # rubocop:disable Scalability/IdempotentWorker
include ::ApplicationWorker
include ::PipelineQueue
diff --git a/app/workers/ci/pipeline_bridge_status_worker.rb b/app/workers/ci/pipeline_bridge_status_worker.rb
index f196573deaa..e4e9d8480c2 100644
--- a/app/workers/ci/pipeline_bridge_status_worker.rb
+++ b/app/workers/ci/pipeline_bridge_status_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module Ci
- class PipelineBridgeStatusWorker
+ class PipelineBridgeStatusWorker # rubocop:disable Scalability/IdempotentWorker
include ::ApplicationWorker
include ::PipelineQueue
diff --git a/app/workers/ci/resource_groups/assign_resource_from_resource_group_worker.rb b/app/workers/ci/resource_groups/assign_resource_from_resource_group_worker.rb
index 62233d19516..8063e34a1b8 100644
--- a/app/workers/ci/resource_groups/assign_resource_from_resource_group_worker.rb
+++ b/app/workers/ci/resource_groups/assign_resource_from_resource_group_worker.rb
@@ -2,7 +2,7 @@
module Ci
module ResourceGroups
- class AssignResourceFromResourceGroupWorker
+ class AssignResourceFromResourceGroupWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include PipelineQueue
diff --git a/app/workers/cleanup_container_repository_worker.rb b/app/workers/cleanup_container_repository_worker.rb
index 83397a1dda2..c3fac453e73 100644
--- a/app/workers/cleanup_container_repository_worker.rb
+++ b/app/workers/cleanup_container_repository_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class CleanupContainerRepositoryWorker
+class CleanupContainerRepositoryWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
queue_namespace :container_repository
diff --git a/app/workers/cluster_configure_istio_worker.rb b/app/workers/cluster_configure_istio_worker.rb
index dfdd408f286..ec6bdfbd6b6 100644
--- a/app/workers/cluster_configure_istio_worker.rb
+++ b/app/workers/cluster_configure_istio_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ClusterConfigureIstioWorker
+class ClusterConfigureIstioWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ClusterQueue
diff --git a/app/workers/cluster_configure_worker.rb b/app/workers/cluster_configure_worker.rb
index e7a4797e68e..f9364ab7144 100644
--- a/app/workers/cluster_configure_worker.rb
+++ b/app/workers/cluster_configure_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ClusterConfigureWorker
+class ClusterConfigureWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ClusterQueue
diff --git a/app/workers/cluster_install_app_worker.rb b/app/workers/cluster_install_app_worker.rb
index 0e075b295dd..002932a0fa5 100644
--- a/app/workers/cluster_install_app_worker.rb
+++ b/app/workers/cluster_install_app_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ClusterInstallAppWorker
+class ClusterInstallAppWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ClusterQueue
include ClusterApplications
diff --git a/app/workers/cluster_patch_app_worker.rb b/app/workers/cluster_patch_app_worker.rb
index 3f95a764567..f75004aa3e5 100644
--- a/app/workers/cluster_patch_app_worker.rb
+++ b/app/workers/cluster_patch_app_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ClusterPatchAppWorker
+class ClusterPatchAppWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ClusterQueue
include ClusterApplications
diff --git a/app/workers/cluster_project_configure_worker.rb b/app/workers/cluster_project_configure_worker.rb
index 614029c2b5c..b68df01dc7a 100644
--- a/app/workers/cluster_project_configure_worker.rb
+++ b/app/workers/cluster_project_configure_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ClusterProjectConfigureWorker
+class ClusterProjectConfigureWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ClusterQueue
diff --git a/app/workers/cluster_provision_worker.rb b/app/workers/cluster_provision_worker.rb
index c34284319dd..cb750f3021e 100644
--- a/app/workers/cluster_provision_worker.rb
+++ b/app/workers/cluster_provision_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ClusterProvisionWorker
+class ClusterProvisionWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ClusterQueue
diff --git a/app/workers/cluster_upgrade_app_worker.rb b/app/workers/cluster_upgrade_app_worker.rb
index cd06f0a2224..99f48415f08 100644
--- a/app/workers/cluster_upgrade_app_worker.rb
+++ b/app/workers/cluster_upgrade_app_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ClusterUpgradeAppWorker
+class ClusterUpgradeAppWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ClusterQueue
include ClusterApplications
diff --git a/app/workers/cluster_wait_for_app_installation_worker.rb b/app/workers/cluster_wait_for_app_installation_worker.rb
index 7155dc6f835..e098c3b86b5 100644
--- a/app/workers/cluster_wait_for_app_installation_worker.rb
+++ b/app/workers/cluster_wait_for_app_installation_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ClusterWaitForAppInstallationWorker
+class ClusterWaitForAppInstallationWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ClusterQueue
include ClusterApplications
diff --git a/app/workers/cluster_wait_for_ingress_ip_address_worker.rb b/app/workers/cluster_wait_for_ingress_ip_address_worker.rb
index 14b1651cc72..c7336ee515d 100644
--- a/app/workers/cluster_wait_for_ingress_ip_address_worker.rb
+++ b/app/workers/cluster_wait_for_ingress_ip_address_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ClusterWaitForIngressIpAddressWorker
+class ClusterWaitForIngressIpAddressWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ClusterQueue
include ClusterApplications
diff --git a/app/workers/clusters/applications/activate_service_worker.rb b/app/workers/clusters/applications/activate_service_worker.rb
index 4f285d55162..abd7f8eaea4 100644
--- a/app/workers/clusters/applications/activate_service_worker.rb
+++ b/app/workers/clusters/applications/activate_service_worker.rb
@@ -2,7 +2,7 @@
module Clusters
module Applications
- class ActivateServiceWorker
+ class ActivateServiceWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ClusterQueue
diff --git a/app/workers/clusters/applications/deactivate_service_worker.rb b/app/workers/clusters/applications/deactivate_service_worker.rb
index 2c560cc998c..fecbb6dde45 100644
--- a/app/workers/clusters/applications/deactivate_service_worker.rb
+++ b/app/workers/clusters/applications/deactivate_service_worker.rb
@@ -2,7 +2,7 @@
module Clusters
module Applications
- class DeactivateServiceWorker
+ class DeactivateServiceWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ClusterQueue
diff --git a/app/workers/clusters/applications/uninstall_worker.rb b/app/workers/clusters/applications/uninstall_worker.rb
index 6180998c8d9..977a25e8442 100644
--- a/app/workers/clusters/applications/uninstall_worker.rb
+++ b/app/workers/clusters/applications/uninstall_worker.rb
@@ -2,7 +2,7 @@
module Clusters
module Applications
- class UninstallWorker
+ class UninstallWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ClusterQueue
include ClusterApplications
diff --git a/app/workers/clusters/applications/wait_for_uninstall_app_worker.rb b/app/workers/clusters/applications/wait_for_uninstall_app_worker.rb
index 7907aa8dfff..a486cfa90b7 100644
--- a/app/workers/clusters/applications/wait_for_uninstall_app_worker.rb
+++ b/app/workers/clusters/applications/wait_for_uninstall_app_worker.rb
@@ -2,7 +2,7 @@
module Clusters
module Applications
- class WaitForUninstallAppWorker
+ class WaitForUninstallAppWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ClusterQueue
include ClusterApplications
diff --git a/app/workers/clusters/cleanup/app_worker.rb b/app/workers/clusters/cleanup/app_worker.rb
index 8b2fddd3164..1d01cec174b 100644
--- a/app/workers/clusters/cleanup/app_worker.rb
+++ b/app/workers/clusters/cleanup/app_worker.rb
@@ -2,7 +2,7 @@
module Clusters
module Cleanup
- class AppWorker
+ class AppWorker # rubocop:disable Scalability/IdempotentWorker
include ClusterCleanupMethods
def perform(cluster_id, execution_count = 0)
diff --git a/app/workers/clusters/cleanup/project_namespace_worker.rb b/app/workers/clusters/cleanup/project_namespace_worker.rb
index 8a7fbf0fde7..a7a951f2937 100644
--- a/app/workers/clusters/cleanup/project_namespace_worker.rb
+++ b/app/workers/clusters/cleanup/project_namespace_worker.rb
@@ -2,7 +2,7 @@
module Clusters
module Cleanup
- class ProjectNamespaceWorker
+ class ProjectNamespaceWorker # rubocop:disable Scalability/IdempotentWorker
include ClusterCleanupMethods
def perform(cluster_id, execution_count = 0)
diff --git a/app/workers/clusters/cleanup/service_account_worker.rb b/app/workers/clusters/cleanup/service_account_worker.rb
index 95de56d8ebe..a829d68fb20 100644
--- a/app/workers/clusters/cleanup/service_account_worker.rb
+++ b/app/workers/clusters/cleanup/service_account_worker.rb
@@ -2,7 +2,7 @@
module Clusters
module Cleanup
- class ServiceAccountWorker
+ class ServiceAccountWorker # rubocop:disable Scalability/IdempotentWorker
include ClusterCleanupMethods
def perform(cluster_id)
diff --git a/app/workers/concerns/worker_attributes.rb b/app/workers/concerns/worker_attributes.rb
index babdb46bb85..55feba673c4 100644
--- a/app/workers/concerns/worker_attributes.rb
+++ b/app/workers/concerns/worker_attributes.rb
@@ -89,6 +89,14 @@ module WorkerAttributes
worker_attributes[:resource_boundary] || :unknown
end
+ def idempotent!
+ worker_attributes[:idempotent] = true
+ end
+
+ def idempotent?
+ worker_attributes[:idempotent]
+ end
+
def weight(value)
worker_attributes[:weight] = value
end
diff --git a/app/workers/container_expiration_policy_worker.rb b/app/workers/container_expiration_policy_worker.rb
index e07a6546e2d..e1544be5aed 100644
--- a/app/workers/container_expiration_policy_worker.rb
+++ b/app/workers/container_expiration_policy_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ContainerExpirationPolicyWorker
+class ContainerExpirationPolicyWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include CronjobQueue
diff --git a/app/workers/create_commit_signature_worker.rb b/app/workers/create_commit_signature_worker.rb
index 027fea3e402..3da21c56eff 100644
--- a/app/workers/create_commit_signature_worker.rb
+++ b/app/workers/create_commit_signature_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class CreateCommitSignatureWorker
+class CreateCommitSignatureWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category :source_code_management
diff --git a/app/workers/create_evidence_worker.rb b/app/workers/create_evidence_worker.rb
index e6fbf59d702..46f211cf3e1 100644
--- a/app/workers/create_evidence_worker.rb
+++ b/app/workers/create_evidence_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class CreateEvidenceWorker
+class CreateEvidenceWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category :release_governance
diff --git a/app/workers/create_note_diff_file_worker.rb b/app/workers/create_note_diff_file_worker.rb
index ca200bd17b4..8a1709f04e1 100644
--- a/app/workers/create_note_diff_file_worker.rb
+++ b/app/workers/create_note_diff_file_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class CreateNoteDiffFileWorker
+class CreateNoteDiffFileWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category :source_code_management
diff --git a/app/workers/create_pipeline_worker.rb b/app/workers/create_pipeline_worker.rb
index a75cc643038..ac00fcc5d57 100644
--- a/app/workers/create_pipeline_worker.rb
+++ b/app/workers/create_pipeline_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class CreatePipelineWorker
+class CreatePipelineWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include PipelineQueue
diff --git a/app/workers/delete_container_repository_worker.rb b/app/workers/delete_container_repository_worker.rb
index e70b4fb0a58..dbfc273a5ce 100644
--- a/app/workers/delete_container_repository_worker.rb
+++ b/app/workers/delete_container_repository_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class DeleteContainerRepositoryWorker
+class DeleteContainerRepositoryWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ExclusiveLeaseGuard
diff --git a/app/workers/delete_diff_files_worker.rb b/app/workers/delete_diff_files_worker.rb
index e0c1724f1f7..a6759a9d7c4 100644
--- a/app/workers/delete_diff_files_worker.rb
+++ b/app/workers/delete_diff_files_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class DeleteDiffFilesWorker
+class DeleteDiffFilesWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category :source_code_management
diff --git a/app/workers/delete_merged_branches_worker.rb b/app/workers/delete_merged_branches_worker.rb
index f3d86233c1b..ab3d42e5384 100644
--- a/app/workers/delete_merged_branches_worker.rb
+++ b/app/workers/delete_merged_branches_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class DeleteMergedBranchesWorker
+class DeleteMergedBranchesWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category :source_code_management
diff --git a/app/workers/delete_stored_files_worker.rb b/app/workers/delete_stored_files_worker.rb
index e1e2f66f573..463f26fdd5a 100644
--- a/app/workers/delete_stored_files_worker.rb
+++ b/app/workers/delete_stored_files_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class DeleteStoredFilesWorker
+class DeleteStoredFilesWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category_not_owned!
diff --git a/app/workers/delete_user_worker.rb b/app/workers/delete_user_worker.rb
index 0e49e787d8a..d3b87c133d3 100644
--- a/app/workers/delete_user_worker.rb
+++ b/app/workers/delete_user_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class DeleteUserWorker
+class DeleteUserWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category :authentication_and_authorization
diff --git a/app/workers/deployments/finished_worker.rb b/app/workers/deployments/finished_worker.rb
index 6196b032f63..0be420af718 100644
--- a/app/workers/deployments/finished_worker.rb
+++ b/app/workers/deployments/finished_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module Deployments
- class FinishedWorker
+ class FinishedWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
queue_namespace :deployment
diff --git a/app/workers/deployments/forward_deployment_worker.rb b/app/workers/deployments/forward_deployment_worker.rb
index a25b8ca0478..a6f246dbbbd 100644
--- a/app/workers/deployments/forward_deployment_worker.rb
+++ b/app/workers/deployments/forward_deployment_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module Deployments
- class ForwardDeploymentWorker
+ class ForwardDeploymentWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
queue_namespace :deployment
diff --git a/app/workers/deployments/success_worker.rb b/app/workers/deployments/success_worker.rb
index 4a29f1aef52..17f790d2f6f 100644
--- a/app/workers/deployments/success_worker.rb
+++ b/app/workers/deployments/success_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module Deployments
- class SuccessWorker
+ class SuccessWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
queue_namespace :deployment
diff --git a/app/workers/detect_repository_languages_worker.rb b/app/workers/detect_repository_languages_worker.rb
index 954d0f9336b..ef66287a692 100644
--- a/app/workers/detect_repository_languages_worker.rb
+++ b/app/workers/detect_repository_languages_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class DetectRepositoryLanguagesWorker
+class DetectRepositoryLanguagesWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ExceptionBacktrace
include ExclusiveLeaseGuard
diff --git a/app/workers/email_receiver_worker.rb b/app/workers/email_receiver_worker.rb
index c2b1e642604..37398b18aef 100644
--- a/app/workers/email_receiver_worker.rb
+++ b/app/workers/email_receiver_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class EmailReceiverWorker
+class EmailReceiverWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category :issue_tracking
diff --git a/app/workers/emails_on_push_worker.rb b/app/workers/emails_on_push_worker.rb
index be66e2b1188..2c546bc3c20 100644
--- a/app/workers/emails_on_push_worker.rb
+++ b/app/workers/emails_on_push_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class EmailsOnPushWorker
+class EmailsOnPushWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
attr_reader :email, :skip_premailer
diff --git a/app/workers/environments/auto_stop_cron_worker.rb b/app/workers/environments/auto_stop_cron_worker.rb
index fdc9490453c..de5e10a0976 100644
--- a/app/workers/environments/auto_stop_cron_worker.rb
+++ b/app/workers/environments/auto_stop_cron_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module Environments
- class AutoStopCronWorker
+ class AutoStopCronWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include CronjobQueue # rubocop:disable Scalability/CronWorkerContext
diff --git a/app/workers/error_tracking_issue_link_worker.rb b/app/workers/error_tracking_issue_link_worker.rb
index b306ecc154b..d59abaf8683 100644
--- a/app/workers/error_tracking_issue_link_worker.rb
+++ b/app/workers/error_tracking_issue_link_worker.rb
@@ -5,7 +5,7 @@
# If a link to a different GitLab issue exists, a new link
# will still be created, but will not be visible in Sentry
# until the prior link is deleted.
-class ErrorTrackingIssueLinkWorker
+class ErrorTrackingIssueLinkWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ExclusiveLeaseGuard
include Gitlab::Utils::StrongMemoize
diff --git a/app/workers/expire_build_artifacts_worker.rb b/app/workers/expire_build_artifacts_worker.rb
index 07f516a3390..12372961250 100644
--- a/app/workers/expire_build_artifacts_worker.rb
+++ b/app/workers/expire_build_artifacts_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ExpireBuildArtifactsWorker
+class ExpireBuildArtifactsWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
# rubocop:disable Scalability/CronWorkerContext
# This worker does not perform work scoped to a context
diff --git a/app/workers/expire_build_instance_artifacts_worker.rb b/app/workers/expire_build_instance_artifacts_worker.rb
index db5240d5c8e..48fd086f88f 100644
--- a/app/workers/expire_build_instance_artifacts_worker.rb
+++ b/app/workers/expire_build_instance_artifacts_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ExpireBuildInstanceArtifactsWorker
+class ExpireBuildInstanceArtifactsWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category :continuous_integration
diff --git a/app/workers/expire_job_cache_worker.rb b/app/workers/expire_job_cache_worker.rb
index 0363429587e..1cd5fa5d1c5 100644
--- a/app/workers/expire_job_cache_worker.rb
+++ b/app/workers/expire_job_cache_worker.rb
@@ -6,6 +6,7 @@ class ExpireJobCacheWorker
queue_namespace :pipeline_cache
latency_sensitive_worker!
+ idempotent!
# rubocop: disable CodeReuse/ActiveRecord
def perform(job_id)
diff --git a/app/workers/expire_pipeline_cache_worker.rb b/app/workers/expire_pipeline_cache_worker.rb
index 1d204e0a19e..d92141c70cc 100644
--- a/app/workers/expire_pipeline_cache_worker.rb
+++ b/app/workers/expire_pipeline_cache_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ExpirePipelineCacheWorker
+class ExpirePipelineCacheWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include PipelineQueue
diff --git a/app/workers/file_hook_worker.rb b/app/workers/file_hook_worker.rb
index 24fc2d75d24..f8cdea54a17 100644
--- a/app/workers/file_hook_worker.rb
+++ b/app/workers/file_hook_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class FileHookWorker
+class FileHookWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
sidekiq_options retry: false
diff --git a/app/workers/git_garbage_collect_worker.rb b/app/workers/git_garbage_collect_worker.rb
index ad119917774..37ca3af517f 100644
--- a/app/workers/git_garbage_collect_worker.rb
+++ b/app/workers/git_garbage_collect_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class GitGarbageCollectWorker
+class GitGarbageCollectWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
sidekiq_options retry: false
diff --git a/app/workers/gitlab/github_import/advance_stage_worker.rb b/app/workers/gitlab/github_import/advance_stage_worker.rb
index 44e69e48694..8c379be2ae4 100644
--- a/app/workers/gitlab/github_import/advance_stage_worker.rb
+++ b/app/workers/gitlab/github_import/advance_stage_worker.rb
@@ -6,7 +6,7 @@ module Gitlab
# number of jobs to complete, without blocking a thread. Once all jobs have
# been completed this worker will advance the import process to the next
# stage.
- class AdvanceStageWorker
+ class AdvanceStageWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
sidekiq_options dead: false
diff --git a/app/workers/gitlab/github_import/import_diff_note_worker.rb b/app/workers/gitlab/github_import/import_diff_note_worker.rb
index ef2a74c51c5..25fb0375692 100644
--- a/app/workers/gitlab/github_import/import_diff_note_worker.rb
+++ b/app/workers/gitlab/github_import/import_diff_note_worker.rb
@@ -2,7 +2,7 @@
module Gitlab
module GithubImport
- class ImportDiffNoteWorker
+ class ImportDiffNoteWorker # rubocop:disable Scalability/IdempotentWorker
include ObjectImporter
def representation_class
diff --git a/app/workers/gitlab/github_import/import_issue_worker.rb b/app/workers/gitlab/github_import/import_issue_worker.rb
index 1b081ae5966..d9c496e3eb3 100644
--- a/app/workers/gitlab/github_import/import_issue_worker.rb
+++ b/app/workers/gitlab/github_import/import_issue_worker.rb
@@ -2,7 +2,7 @@
module Gitlab
module GithubImport
- class ImportIssueWorker
+ class ImportIssueWorker # rubocop:disable Scalability/IdempotentWorker
include ObjectImporter
def representation_class
diff --git a/app/workers/gitlab/github_import/import_lfs_object_worker.rb b/app/workers/gitlab/github_import/import_lfs_object_worker.rb
index 520c5cb091a..78f78fdb160 100644
--- a/app/workers/gitlab/github_import/import_lfs_object_worker.rb
+++ b/app/workers/gitlab/github_import/import_lfs_object_worker.rb
@@ -2,7 +2,7 @@
module Gitlab
module GithubImport
- class ImportLfsObjectWorker
+ class ImportLfsObjectWorker # rubocop:disable Scalability/IdempotentWorker
include ObjectImporter
def representation_class
diff --git a/app/workers/gitlab/github_import/import_note_worker.rb b/app/workers/gitlab/github_import/import_note_worker.rb
index d2b4c36a5b9..d0f97a15afd 100644
--- a/app/workers/gitlab/github_import/import_note_worker.rb
+++ b/app/workers/gitlab/github_import/import_note_worker.rb
@@ -2,7 +2,7 @@
module Gitlab
module GithubImport
- class ImportNoteWorker
+ class ImportNoteWorker # rubocop:disable Scalability/IdempotentWorker
include ObjectImporter
def representation_class
diff --git a/app/workers/gitlab/github_import/import_pull_request_worker.rb b/app/workers/gitlab/github_import/import_pull_request_worker.rb
index 62a6da152a3..ec806ad170b 100644
--- a/app/workers/gitlab/github_import/import_pull_request_worker.rb
+++ b/app/workers/gitlab/github_import/import_pull_request_worker.rb
@@ -2,7 +2,7 @@
module Gitlab
module GithubImport
- class ImportPullRequestWorker
+ class ImportPullRequestWorker # rubocop:disable Scalability/IdempotentWorker
include ObjectImporter
def representation_class
diff --git a/app/workers/gitlab/github_import/refresh_import_jid_worker.rb b/app/workers/gitlab/github_import/refresh_import_jid_worker.rb
index 76723e4a61f..0ddd893d0d1 100644
--- a/app/workers/gitlab/github_import/refresh_import_jid_worker.rb
+++ b/app/workers/gitlab/github_import/refresh_import_jid_worker.rb
@@ -2,7 +2,7 @@
module Gitlab
module GithubImport
- class RefreshImportJidWorker
+ class RefreshImportJidWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include GithubImport::Queue
diff --git a/app/workers/gitlab/github_import/stage/finish_import_worker.rb b/app/workers/gitlab/github_import/stage/finish_import_worker.rb
index ee64f62637e..73699a74a4a 100644
--- a/app/workers/gitlab/github_import/stage/finish_import_worker.rb
+++ b/app/workers/gitlab/github_import/stage/finish_import_worker.rb
@@ -3,7 +3,7 @@
module Gitlab
module GithubImport
module Stage
- class FinishImportWorker
+ class FinishImportWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include GithubImport::Queue
include StageMethods
diff --git a/app/workers/gitlab/github_import/stage/import_base_data_worker.rb b/app/workers/gitlab/github_import/stage/import_base_data_worker.rb
index ccfed2ae187..11c2a2ac9b4 100644
--- a/app/workers/gitlab/github_import/stage/import_base_data_worker.rb
+++ b/app/workers/gitlab/github_import/stage/import_base_data_worker.rb
@@ -3,7 +3,7 @@
module Gitlab
module GithubImport
module Stage
- class ImportBaseDataWorker
+ class ImportBaseDataWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include GithubImport::Queue
include StageMethods
diff --git a/app/workers/gitlab/github_import/stage/import_issues_and_diff_notes_worker.rb b/app/workers/gitlab/github_import/stage/import_issues_and_diff_notes_worker.rb
index 7007754ff2e..68b6e159fa4 100644
--- a/app/workers/gitlab/github_import/stage/import_issues_and_diff_notes_worker.rb
+++ b/app/workers/gitlab/github_import/stage/import_issues_and_diff_notes_worker.rb
@@ -3,7 +3,7 @@
module Gitlab
module GithubImport
module Stage
- class ImportIssuesAndDiffNotesWorker
+ class ImportIssuesAndDiffNotesWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include GithubImport::Queue
include StageMethods
diff --git a/app/workers/gitlab/github_import/stage/import_lfs_objects_worker.rb b/app/workers/gitlab/github_import/stage/import_lfs_objects_worker.rb
index 29257603a9d..a19df399969 100644
--- a/app/workers/gitlab/github_import/stage/import_lfs_objects_worker.rb
+++ b/app/workers/gitlab/github_import/stage/import_lfs_objects_worker.rb
@@ -3,7 +3,7 @@
module Gitlab
module GithubImport
module Stage
- class ImportLfsObjectsWorker
+ class ImportLfsObjectsWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include GithubImport::Queue
include StageMethods
diff --git a/app/workers/gitlab/github_import/stage/import_notes_worker.rb b/app/workers/gitlab/github_import/stage/import_notes_worker.rb
index ccf0013180d..49b9821cd45 100644
--- a/app/workers/gitlab/github_import/stage/import_notes_worker.rb
+++ b/app/workers/gitlab/github_import/stage/import_notes_worker.rb
@@ -3,7 +3,7 @@
module Gitlab
module GithubImport
module Stage
- class ImportNotesWorker
+ class ImportNotesWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include GithubImport::Queue
include StageMethods
diff --git a/app/workers/gitlab/github_import/stage/import_pull_requests_worker.rb b/app/workers/gitlab/github_import/stage/import_pull_requests_worker.rb
index 37a7a7f4ba0..3299db5653b 100644
--- a/app/workers/gitlab/github_import/stage/import_pull_requests_worker.rb
+++ b/app/workers/gitlab/github_import/stage/import_pull_requests_worker.rb
@@ -3,7 +3,7 @@
module Gitlab
module GithubImport
module Stage
- class ImportPullRequestsWorker
+ class ImportPullRequestsWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include GithubImport::Queue
include StageMethods
diff --git a/app/workers/gitlab/github_import/stage/import_repository_worker.rb b/app/workers/gitlab/github_import/stage/import_repository_worker.rb
index b5e30470070..cb9ef1cd198 100644
--- a/app/workers/gitlab/github_import/stage/import_repository_worker.rb
+++ b/app/workers/gitlab/github_import/stage/import_repository_worker.rb
@@ -3,7 +3,7 @@
module Gitlab
module GithubImport
module Stage
- class ImportRepositoryWorker
+ class ImportRepositoryWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include GithubImport::Queue
include StageMethods
diff --git a/app/workers/gitlab/phabricator_import/base_worker.rb b/app/workers/gitlab/phabricator_import/base_worker.rb
index faae71d4627..82ef9e825f9 100644
--- a/app/workers/gitlab/phabricator_import/base_worker.rb
+++ b/app/workers/gitlab/phabricator_import/base_worker.rb
@@ -18,7 +18,7 @@
# - It marks the import as finished when all remaining jobs are done
module Gitlab
module PhabricatorImport
- class BaseWorker
+ class BaseWorker # rubocop:disable Scalability/IdempotentWorker
include WorkerAttributes
include Gitlab::ExclusiveLeaseHelpers
diff --git a/app/workers/gitlab/phabricator_import/import_tasks_worker.rb b/app/workers/gitlab/phabricator_import/import_tasks_worker.rb
index b5d9e80797b..1b1d7b35dd5 100644
--- a/app/workers/gitlab/phabricator_import/import_tasks_worker.rb
+++ b/app/workers/gitlab/phabricator_import/import_tasks_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module Gitlab
module PhabricatorImport
- class ImportTasksWorker < BaseWorker
+ class ImportTasksWorker < BaseWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ProjectImportOptions # This marks the project as failed after too many tries
diff --git a/app/workers/gitlab_shell_worker.rb b/app/workers/gitlab_shell_worker.rb
index bd2225e6d7c..f9b5a7d99ed 100644
--- a/app/workers/gitlab_shell_worker.rb
+++ b/app/workers/gitlab_shell_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class GitlabShellWorker
+class GitlabShellWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include Gitlab::ShellAdapter
diff --git a/app/workers/gitlab_usage_ping_worker.rb b/app/workers/gitlab_usage_ping_worker.rb
index 002542e26f4..9f0cf1728dd 100644
--- a/app/workers/gitlab_usage_ping_worker.rb
+++ b/app/workers/gitlab_usage_ping_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class GitlabUsagePingWorker
+class GitlabUsagePingWorker # rubocop:disable Scalability/IdempotentWorker
LEASE_TIMEOUT = 86400
include ApplicationWorker
diff --git a/app/workers/group_destroy_worker.rb b/app/workers/group_destroy_worker.rb
index fc751f8b612..d80a2dad7d9 100644
--- a/app/workers/group_destroy_worker.rb
+++ b/app/workers/group_destroy_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class GroupDestroyWorker
+class GroupDestroyWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ExceptionBacktrace
diff --git a/app/workers/group_export_worker.rb b/app/workers/group_export_worker.rb
index a2d34e8c8bf..3e0390429d6 100644
--- a/app/workers/group_export_worker.rb
+++ b/app/workers/group_export_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class GroupExportWorker
+class GroupExportWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ExceptionBacktrace
diff --git a/app/workers/group_import_worker.rb b/app/workers/group_import_worker.rb
index f283eab5814..b6fc5afc28c 100644
--- a/app/workers/group_import_worker.rb
+++ b/app/workers/group_import_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class GroupImportWorker
+class GroupImportWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ExceptionBacktrace
diff --git a/app/workers/hashed_storage/base_worker.rb b/app/workers/hashed_storage/base_worker.rb
index 1ab2108f6bb..372440996d9 100644
--- a/app/workers/hashed_storage/base_worker.rb
+++ b/app/workers/hashed_storage/base_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module HashedStorage
- class BaseWorker
+ class BaseWorker # rubocop:disable Scalability/IdempotentWorker
include ExclusiveLeaseGuard
include WorkerAttributes
diff --git a/app/workers/hashed_storage/migrator_worker.rb b/app/workers/hashed_storage/migrator_worker.rb
index 72a3faec5f4..5cbdfcb0602 100644
--- a/app/workers/hashed_storage/migrator_worker.rb
+++ b/app/workers/hashed_storage/migrator_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module HashedStorage
- class MigratorWorker
+ class MigratorWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
queue_namespace :hashed_storage
diff --git a/app/workers/hashed_storage/project_migrate_worker.rb b/app/workers/hashed_storage/project_migrate_worker.rb
index 0174467923d..3ce60ce7eb6 100644
--- a/app/workers/hashed_storage/project_migrate_worker.rb
+++ b/app/workers/hashed_storage/project_migrate_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module HashedStorage
- class ProjectMigrateWorker < BaseWorker
+ class ProjectMigrateWorker < BaseWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
queue_namespace :hashed_storage
diff --git a/app/workers/hashed_storage/project_rollback_worker.rb b/app/workers/hashed_storage/project_rollback_worker.rb
index 55e1d7ab23e..17b3cca83e1 100644
--- a/app/workers/hashed_storage/project_rollback_worker.rb
+++ b/app/workers/hashed_storage/project_rollback_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module HashedStorage
- class ProjectRollbackWorker < BaseWorker
+ class ProjectRollbackWorker < BaseWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
queue_namespace :hashed_storage
diff --git a/app/workers/hashed_storage/rollbacker_worker.rb b/app/workers/hashed_storage/rollbacker_worker.rb
index 8babdcfb96d..a220d3b2226 100644
--- a/app/workers/hashed_storage/rollbacker_worker.rb
+++ b/app/workers/hashed_storage/rollbacker_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module HashedStorage
- class RollbackerWorker
+ class RollbackerWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
queue_namespace :hashed_storage
diff --git a/app/workers/import_export_project_cleanup_worker.rb b/app/workers/import_export_project_cleanup_worker.rb
index ae236fa1fcd..dd345434d08 100644
--- a/app/workers/import_export_project_cleanup_worker.rb
+++ b/app/workers/import_export_project_cleanup_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ImportExportProjectCleanupWorker
+class ImportExportProjectCleanupWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
# rubocop:disable Scalability/CronWorkerContext
# This worker does not perform work scoped to a context
diff --git a/app/workers/import_issues_csv_worker.rb b/app/workers/import_issues_csv_worker.rb
index 7c5584146ca..c7b5f8cd0a7 100644
--- a/app/workers/import_issues_csv_worker.rb
+++ b/app/workers/import_issues_csv_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ImportIssuesCsvWorker
+class ImportIssuesCsvWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category :issue_tracking
diff --git a/app/workers/incident_management/process_alert_worker.rb b/app/workers/incident_management/process_alert_worker.rb
index f3d5bc5c66b..8d4294cc231 100644
--- a/app/workers/incident_management/process_alert_worker.rb
+++ b/app/workers/incident_management/process_alert_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module IncidentManagement
- class ProcessAlertWorker
+ class ProcessAlertWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
queue_namespace :incident_management
diff --git a/app/workers/invalid_gpg_signature_update_worker.rb b/app/workers/invalid_gpg_signature_update_worker.rb
index e1c2eefbf0f..1fd959c8763 100644
--- a/app/workers/invalid_gpg_signature_update_worker.rb
+++ b/app/workers/invalid_gpg_signature_update_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class InvalidGpgSignatureUpdateWorker
+class InvalidGpgSignatureUpdateWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category :source_code_management
diff --git a/app/workers/irker_worker.rb b/app/workers/irker_worker.rb
index a133ed6ed1b..91ab0d69ad1 100644
--- a/app/workers/irker_worker.rb
+++ b/app/workers/irker_worker.rb
@@ -3,7 +3,7 @@
require 'json'
require 'socket'
-class IrkerWorker
+class IrkerWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category :integrations
diff --git a/app/workers/issue_due_scheduler_worker.rb b/app/workers/issue_due_scheduler_worker.rb
index 59027907284..d735295d046 100644
--- a/app/workers/issue_due_scheduler_worker.rb
+++ b/app/workers/issue_due_scheduler_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class IssueDueSchedulerWorker
+class IssueDueSchedulerWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include CronjobQueue # rubocop:disable Scalability/CronWorkerContext
diff --git a/app/workers/mail_scheduler/issue_due_worker.rb b/app/workers/mail_scheduler/issue_due_worker.rb
index 6df816de71f..309d3e13477 100644
--- a/app/workers/mail_scheduler/issue_due_worker.rb
+++ b/app/workers/mail_scheduler/issue_due_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module MailScheduler
- class IssueDueWorker
+ class IssueDueWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include MailSchedulerQueue
diff --git a/app/workers/mail_scheduler/notification_service_worker.rb b/app/workers/mail_scheduler/notification_service_worker.rb
index ec659e39b24..691af2a724d 100644
--- a/app/workers/mail_scheduler/notification_service_worker.rb
+++ b/app/workers/mail_scheduler/notification_service_worker.rb
@@ -3,7 +3,7 @@
require 'active_job/arguments'
module MailScheduler
- class NotificationServiceWorker
+ class NotificationServiceWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include MailSchedulerQueue
diff --git a/app/workers/merge_request_mergeability_check_worker.rb b/app/workers/merge_request_mergeability_check_worker.rb
index ed35284b66c..a26c1a886f6 100644
--- a/app/workers/merge_request_mergeability_check_worker.rb
+++ b/app/workers/merge_request_mergeability_check_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class MergeRequestMergeabilityCheckWorker
+class MergeRequestMergeabilityCheckWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category :source_code_management
diff --git a/app/workers/merge_worker.rb b/app/workers/merge_worker.rb
index 48bc205113f..a7b926e143f 100644
--- a/app/workers/merge_worker.rb
+++ b/app/workers/merge_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class MergeWorker
+class MergeWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category :source_code_management
diff --git a/app/workers/migrate_external_diffs_worker.rb b/app/workers/migrate_external_diffs_worker.rb
index d248e2b5500..0a95f40aa8f 100644
--- a/app/workers/migrate_external_diffs_worker.rb
+++ b/app/workers/migrate_external_diffs_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class MigrateExternalDiffsWorker
+class MigrateExternalDiffsWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category :source_code_management
diff --git a/app/workers/namespaceless_project_destroy_worker.rb b/app/workers/namespaceless_project_destroy_worker.rb
index 113afc268f2..1c8054d8fbd 100644
--- a/app/workers/namespaceless_project_destroy_worker.rb
+++ b/app/workers/namespaceless_project_destroy_worker.rb
@@ -6,7 +6,7 @@
# used to belong to. Projects in this state should be rare.
# The worker will reject doing anything for projects that *do* have a
# namespace. For those use ProjectDestroyWorker instead.
-class NamespacelessProjectDestroyWorker
+class NamespacelessProjectDestroyWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ExceptionBacktrace
diff --git a/app/workers/namespaces/prune_aggregation_schedules_worker.rb b/app/workers/namespaces/prune_aggregation_schedules_worker.rb
index aeb5aa37a10..b94c8b7b4ba 100644
--- a/app/workers/namespaces/prune_aggregation_schedules_worker.rb
+++ b/app/workers/namespaces/prune_aggregation_schedules_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module Namespaces
- class PruneAggregationSchedulesWorker
+ class PruneAggregationSchedulesWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include CronjobQueue # rubocop:disable Scalability/CronWorkerContext
diff --git a/app/workers/namespaces/root_statistics_worker.rb b/app/workers/namespaces/root_statistics_worker.rb
index fd772c8cff6..5fceeb8e03d 100644
--- a/app/workers/namespaces/root_statistics_worker.rb
+++ b/app/workers/namespaces/root_statistics_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module Namespaces
- class RootStatisticsWorker
+ class RootStatisticsWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
queue_namespace :update_namespace_statistics
diff --git a/app/workers/namespaces/schedule_aggregation_worker.rb b/app/workers/namespaces/schedule_aggregation_worker.rb
index 87e135fbf21..60210e2f5a7 100644
--- a/app/workers/namespaces/schedule_aggregation_worker.rb
+++ b/app/workers/namespaces/schedule_aggregation_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module Namespaces
- class ScheduleAggregationWorker
+ class ScheduleAggregationWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
queue_namespace :update_namespace_statistics
diff --git a/app/workers/new_issue_worker.rb b/app/workers/new_issue_worker.rb
index d696165b447..ded5104c708 100644
--- a/app/workers/new_issue_worker.rb
+++ b/app/workers/new_issue_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class NewIssueWorker
+class NewIssueWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include NewIssuable
diff --git a/app/workers/new_merge_request_worker.rb b/app/workers/new_merge_request_worker.rb
index e31ddae1f13..3b101435f7a 100644
--- a/app/workers/new_merge_request_worker.rb
+++ b/app/workers/new_merge_request_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class NewMergeRequestWorker
+class NewMergeRequestWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include NewIssuable
diff --git a/app/workers/new_note_worker.rb b/app/workers/new_note_worker.rb
index b446e376007..af1cef432eb 100644
--- a/app/workers/new_note_worker.rb
+++ b/app/workers/new_note_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class NewNoteWorker
+class NewNoteWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category :issue_tracking
diff --git a/app/workers/new_release_worker.rb b/app/workers/new_release_worker.rb
index edfdb2d7aff..3c19e5f3d2b 100644
--- a/app/workers/new_release_worker.rb
+++ b/app/workers/new_release_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class NewReleaseWorker
+class NewReleaseWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
queue_namespace :notifications
diff --git a/app/workers/object_pool/create_worker.rb b/app/workers/object_pool/create_worker.rb
index 135b99886dc..cf87ad95077 100644
--- a/app/workers/object_pool/create_worker.rb
+++ b/app/workers/object_pool/create_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module ObjectPool
- class CreateWorker
+ class CreateWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ObjectPoolQueue
include ExclusiveLeaseGuard
diff --git a/app/workers/object_pool/destroy_worker.rb b/app/workers/object_pool/destroy_worker.rb
index ca00d467d9b..d42cee59d03 100644
--- a/app/workers/object_pool/destroy_worker.rb
+++ b/app/workers/object_pool/destroy_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module ObjectPool
- class DestroyWorker
+ class DestroyWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ObjectPoolQueue
diff --git a/app/workers/object_pool/join_worker.rb b/app/workers/object_pool/join_worker.rb
index ddd002eabb8..f1008d3be83 100644
--- a/app/workers/object_pool/join_worker.rb
+++ b/app/workers/object_pool/join_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module ObjectPool
- class JoinWorker
+ class JoinWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ObjectPoolQueue
diff --git a/app/workers/object_pool/schedule_join_worker.rb b/app/workers/object_pool/schedule_join_worker.rb
index 647a8b72435..c00bb2967f2 100644
--- a/app/workers/object_pool/schedule_join_worker.rb
+++ b/app/workers/object_pool/schedule_join_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module ObjectPool
- class ScheduleJoinWorker
+ class ScheduleJoinWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ObjectPoolQueue
diff --git a/app/workers/object_storage/background_move_worker.rb b/app/workers/object_storage/background_move_worker.rb
index 55f8e1c3ede..7b0a7c7ec58 100644
--- a/app/workers/object_storage/background_move_worker.rb
+++ b/app/workers/object_storage/background_move_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module ObjectStorage
- class BackgroundMoveWorker
+ class BackgroundMoveWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ObjectStorageQueue
diff --git a/app/workers/object_storage/migrate_uploads_worker.rb b/app/workers/object_storage/migrate_uploads_worker.rb
index 01e6fdb2d3e..d9d21f2cb7e 100644
--- a/app/workers/object_storage/migrate_uploads_worker.rb
+++ b/app/workers/object_storage/migrate_uploads_worker.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
+# rubocop:disable Scalability/IdempotentWorker
module ObjectStorage
class MigrateUploadsWorker
include ApplicationWorker
@@ -137,3 +138,4 @@ module ObjectStorage
end
end
end
+# rubocop:enable Scalability/IdempotentWorker
diff --git a/app/workers/pages_domain_removal_cron_worker.rb b/app/workers/pages_domain_removal_cron_worker.rb
index 1c96dd6ad8c..cb24441d2f7 100644
--- a/app/workers/pages_domain_removal_cron_worker.rb
+++ b/app/workers/pages_domain_removal_cron_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class PagesDomainRemovalCronWorker
+class PagesDomainRemovalCronWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include CronjobQueue
diff --git a/app/workers/pages_domain_ssl_renewal_cron_worker.rb b/app/workers/pages_domain_ssl_renewal_cron_worker.rb
index c1201b935d1..fe6d516d3cf 100644
--- a/app/workers/pages_domain_ssl_renewal_cron_worker.rb
+++ b/app/workers/pages_domain_ssl_renewal_cron_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class PagesDomainSslRenewalCronWorker
+class PagesDomainSslRenewalCronWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include CronjobQueue
diff --git a/app/workers/pages_domain_ssl_renewal_worker.rb b/app/workers/pages_domain_ssl_renewal_worker.rb
index 4db7d22ef7e..561fd59d471 100644
--- a/app/workers/pages_domain_ssl_renewal_worker.rb
+++ b/app/workers/pages_domain_ssl_renewal_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class PagesDomainSslRenewalWorker
+class PagesDomainSslRenewalWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category :pages
diff --git a/app/workers/pages_domain_verification_cron_worker.rb b/app/workers/pages_domain_verification_cron_worker.rb
index b06aa65a8e5..a30f0b981d8 100644
--- a/app/workers/pages_domain_verification_cron_worker.rb
+++ b/app/workers/pages_domain_verification_cron_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class PagesDomainVerificationCronWorker
+class PagesDomainVerificationCronWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include CronjobQueue
diff --git a/app/workers/pages_domain_verification_worker.rb b/app/workers/pages_domain_verification_worker.rb
index b0888036498..1b4d9d3994c 100644
--- a/app/workers/pages_domain_verification_worker.rb
+++ b/app/workers/pages_domain_verification_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class PagesDomainVerificationWorker
+class PagesDomainVerificationWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category :pages
diff --git a/app/workers/pages_worker.rb b/app/workers/pages_worker.rb
index 484d9053849..875f17282f9 100644
--- a/app/workers/pages_worker.rb
+++ b/app/workers/pages_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class PagesWorker
+class PagesWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
sidekiq_options retry: 3
diff --git a/app/workers/personal_access_tokens/expiring_worker.rb b/app/workers/personal_access_tokens/expiring_worker.rb
index 84f7ce9d5d7..86240f827fc 100644
--- a/app/workers/personal_access_tokens/expiring_worker.rb
+++ b/app/workers/personal_access_tokens/expiring_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module PersonalAccessTokens
- class ExpiringWorker
+ class ExpiringWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include CronjobQueue
diff --git a/app/workers/pipeline_hooks_worker.rb b/app/workers/pipeline_hooks_worker.rb
index 04abc9c88fd..3fa0c5ab9af 100644
--- a/app/workers/pipeline_hooks_worker.rb
+++ b/app/workers/pipeline_hooks_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class PipelineHooksWorker
+class PipelineHooksWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include PipelineQueue
diff --git a/app/workers/pipeline_metrics_worker.rb b/app/workers/pipeline_metrics_worker.rb
index 3830522aaa1..65a5a94ed8a 100644
--- a/app/workers/pipeline_metrics_worker.rb
+++ b/app/workers/pipeline_metrics_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class PipelineMetricsWorker
+class PipelineMetricsWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include PipelineQueue
diff --git a/app/workers/pipeline_notification_worker.rb b/app/workers/pipeline_notification_worker.rb
index 62ecbc8a047..e9081cc416f 100644
--- a/app/workers/pipeline_notification_worker.rb
+++ b/app/workers/pipeline_notification_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class PipelineNotificationWorker
+class PipelineNotificationWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include PipelineQueue
diff --git a/app/workers/pipeline_process_worker.rb b/app/workers/pipeline_process_worker.rb
index 200f3619332..2f8ab0d6202 100644
--- a/app/workers/pipeline_process_worker.rb
+++ b/app/workers/pipeline_process_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class PipelineProcessWorker
+class PipelineProcessWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include PipelineQueue
diff --git a/app/workers/pipeline_schedule_worker.rb b/app/workers/pipeline_schedule_worker.rb
index 8b326b9dbb6..d81b978f9b0 100644
--- a/app/workers/pipeline_schedule_worker.rb
+++ b/app/workers/pipeline_schedule_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class PipelineScheduleWorker
+class PipelineScheduleWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include CronjobQueue
diff --git a/app/workers/pipeline_success_worker.rb b/app/workers/pipeline_success_worker.rb
index 5c24f00e0c3..3b4ab461ae7 100644
--- a/app/workers/pipeline_success_worker.rb
+++ b/app/workers/pipeline_success_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class PipelineSuccessWorker
+class PipelineSuccessWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include PipelineQueue
diff --git a/app/workers/pipeline_update_worker.rb b/app/workers/pipeline_update_worker.rb
index 0321ea5a6ce..b170781202a 100644
--- a/app/workers/pipeline_update_worker.rb
+++ b/app/workers/pipeline_update_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class PipelineUpdateWorker
+class PipelineUpdateWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include PipelineQueue
diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb
index d5038f1152b..f0fd3c9a808 100644
--- a/app/workers/post_receive.rb
+++ b/app/workers/post_receive.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class PostReceive
+class PostReceive # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category :source_code_management
diff --git a/app/workers/process_commit_worker.rb b/app/workers/process_commit_worker.rb
index ca2896946c9..d604ac12e8a 100644
--- a/app/workers/process_commit_worker.rb
+++ b/app/workers/process_commit_worker.rb
@@ -7,7 +7,7 @@
# result of this the workload of this worker should be kept to a bare minimum.
# Consider using an extra worker if you need to add any extra (and potentially
# slow) processing of commits.
-class ProcessCommitWorker
+class ProcessCommitWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category :source_code_management
diff --git a/app/workers/project_cache_worker.rb b/app/workers/project_cache_worker.rb
index ae1d57aa124..fc79a988c8b 100644
--- a/app/workers/project_cache_worker.rb
+++ b/app/workers/project_cache_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
# Worker for updating any project specific caches.
-class ProjectCacheWorker
+class ProjectCacheWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
latency_sensitive_worker!
diff --git a/app/workers/project_daily_statistics_worker.rb b/app/workers/project_daily_statistics_worker.rb
index 19c2fd67763..c60bee0ffdc 100644
--- a/app/workers/project_daily_statistics_worker.rb
+++ b/app/workers/project_daily_statistics_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ProjectDailyStatisticsWorker
+class ProjectDailyStatisticsWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category :source_code_management
diff --git a/app/workers/project_destroy_worker.rb b/app/workers/project_destroy_worker.rb
index 1d20837faa2..b3e7996f4a4 100644
--- a/app/workers/project_destroy_worker.rb
+++ b/app/workers/project_destroy_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ProjectDestroyWorker
+class ProjectDestroyWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ExceptionBacktrace
diff --git a/app/workers/project_export_worker.rb b/app/workers/project_export_worker.rb
index 4d2cc3cd32d..eefba6d25c7 100644
--- a/app/workers/project_export_worker.rb
+++ b/app/workers/project_export_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ProjectExportWorker
+class ProjectExportWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ExceptionBacktrace
diff --git a/app/workers/project_service_worker.rb b/app/workers/project_service_worker.rb
index 38a2a7414a5..84c3a3e52d0 100644
--- a/app/workers/project_service_worker.rb
+++ b/app/workers/project_service_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ProjectServiceWorker
+class ProjectServiceWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
sidekiq_options dead: false
diff --git a/app/workers/propagate_service_template_worker.rb b/app/workers/propagate_service_template_worker.rb
index 73a2b453207..f3a6bda1821 100644
--- a/app/workers/propagate_service_template_worker.rb
+++ b/app/workers/propagate_service_template_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
# Worker for updating any project specific caches.
-class PropagateServiceTemplateWorker
+class PropagateServiceTemplateWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category :source_code_management
diff --git a/app/workers/prune_old_events_worker.rb b/app/workers/prune_old_events_worker.rb
index 541a17c0fcf..330de4c7cba 100644
--- a/app/workers/prune_old_events_worker.rb
+++ b/app/workers/prune_old_events_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class PruneOldEventsWorker
+class PruneOldEventsWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
# rubocop:disable Scalability/CronWorkerContext
# This worker does not perform work scoped to a context
diff --git a/app/workers/prune_web_hook_logs_worker.rb b/app/workers/prune_web_hook_logs_worker.rb
index dd4f16a69da..a8e81a24ecd 100644
--- a/app/workers/prune_web_hook_logs_worker.rb
+++ b/app/workers/prune_web_hook_logs_worker.rb
@@ -2,7 +2,7 @@
# Worker that deletes a fixed number of outdated rows from the "web_hook_logs"
# table.
-class PruneWebHookLogsWorker
+class PruneWebHookLogsWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
# rubocop:disable Scalability/CronWorkerContext
# This worker does not perform work scoped to a context
diff --git a/app/workers/reactive_caching_worker.rb b/app/workers/reactive_caching_worker.rb
index 6f82ad83137..bcaeaec5709 100644
--- a/app/workers/reactive_caching_worker.rb
+++ b/app/workers/reactive_caching_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ReactiveCachingWorker
+class ReactiveCachingWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category_not_owned!
diff --git a/app/workers/rebase_worker.rb b/app/workers/rebase_worker.rb
index ddf5c31a1c2..2e13af5e0aa 100644
--- a/app/workers/rebase_worker.rb
+++ b/app/workers/rebase_worker.rb
@@ -2,7 +2,7 @@
# The RebaseWorker must be wrapped in important concurrency code, so should only
# be scheduled via MergeRequest#rebase_async
-class RebaseWorker
+class RebaseWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category :source_code_management
diff --git a/app/workers/remote_mirror_notification_worker.rb b/app/workers/remote_mirror_notification_worker.rb
index 706131d4e4b..33f5002014d 100644
--- a/app/workers/remote_mirror_notification_worker.rb
+++ b/app/workers/remote_mirror_notification_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class RemoteMirrorNotificationWorker
+class RemoteMirrorNotificationWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category :source_code_management
diff --git a/app/workers/remove_expired_group_links_worker.rb b/app/workers/remove_expired_group_links_worker.rb
index db35dfb3ca8..8226f22837c 100644
--- a/app/workers/remove_expired_group_links_worker.rb
+++ b/app/workers/remove_expired_group_links_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class RemoveExpiredGroupLinksWorker
+class RemoveExpiredGroupLinksWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include CronjobQueue # rubocop:disable Scalability/CronWorkerContext
diff --git a/app/workers/remove_expired_members_worker.rb b/app/workers/remove_expired_members_worker.rb
index 278adee98e9..f56a6cd9fa2 100644
--- a/app/workers/remove_expired_members_worker.rb
+++ b/app/workers/remove_expired_members_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class RemoveExpiredMembersWorker
+class RemoveExpiredMembersWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include CronjobQueue # rubocop:disable Scalability/CronWorkerContext
diff --git a/app/workers/remove_unreferenced_lfs_objects_worker.rb b/app/workers/remove_unreferenced_lfs_objects_worker.rb
index 5e3998f3915..76ab23ebbd5 100644
--- a/app/workers/remove_unreferenced_lfs_objects_worker.rb
+++ b/app/workers/remove_unreferenced_lfs_objects_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class RemoveUnreferencedLfsObjectsWorker
+class RemoveUnreferencedLfsObjectsWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
# rubocop:disable Scalability/CronWorkerContext
# This worker does not perform work scoped to a context
diff --git a/app/workers/repository_archive_cache_worker.rb b/app/workers/repository_archive_cache_worker.rb
index 76e08a80c15..84f61a60953 100644
--- a/app/workers/repository_archive_cache_worker.rb
+++ b/app/workers/repository_archive_cache_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class RepositoryArchiveCacheWorker
+class RepositoryArchiveCacheWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
# rubocop:disable Scalability/CronWorkerContext
# This worker does not perform work scoped to a context
diff --git a/app/workers/repository_check/batch_worker.rb b/app/workers/repository_check/batch_worker.rb
index 4091c30f498..3e5e6a25228 100644
--- a/app/workers/repository_check/batch_worker.rb
+++ b/app/workers/repository_check/batch_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module RepositoryCheck
- class BatchWorker
+ class BatchWorker # rubocop:disable Scalability/IdempotentWorker
prepend_if_ee('::EE::RepositoryCheck::BatchWorker') # rubocop: disable Cop/InjectEnterpriseEditionModule
include ApplicationWorker
diff --git a/app/workers/repository_check/clear_worker.rb b/app/workers/repository_check/clear_worker.rb
index 01964c69fb2..1689b9bf251 100644
--- a/app/workers/repository_check/clear_worker.rb
+++ b/app/workers/repository_check/clear_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module RepositoryCheck
- class ClearWorker
+ class ClearWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include RepositoryCheckQueue
diff --git a/app/workers/repository_check/dispatch_worker.rb b/app/workers/repository_check/dispatch_worker.rb
index f68be8832eb..d7a145011fa 100644
--- a/app/workers/repository_check/dispatch_worker.rb
+++ b/app/workers/repository_check/dispatch_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module RepositoryCheck
- class DispatchWorker
+ class DispatchWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
# rubocop:disable Scalability/CronWorkerContext
# This worker does not perform work scoped to a context
diff --git a/app/workers/repository_check/single_repository_worker.rb b/app/workers/repository_check/single_repository_worker.rb
index cadb1de356c..b25a20b3eff 100644
--- a/app/workers/repository_check/single_repository_worker.rb
+++ b/app/workers/repository_check/single_repository_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module RepositoryCheck
- class SingleRepositoryWorker
+ class SingleRepositoryWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include RepositoryCheckQueue
diff --git a/app/workers/repository_cleanup_worker.rb b/app/workers/repository_cleanup_worker.rb
index dd2cbd42d1f..33b7223dd95 100644
--- a/app/workers/repository_cleanup_worker.rb
+++ b/app/workers/repository_cleanup_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class RepositoryCleanupWorker
+class RepositoryCleanupWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
sidekiq_options retry: 3
diff --git a/app/workers/repository_fork_worker.rb b/app/workers/repository_fork_worker.rb
index ba141f808a7..4b90239dcb8 100644
--- a/app/workers/repository_fork_worker.rb
+++ b/app/workers/repository_fork_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class RepositoryForkWorker
+class RepositoryForkWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include Gitlab::ShellAdapter
include ProjectStartImport
diff --git a/app/workers/repository_import_worker.rb b/app/workers/repository_import_worker.rb
index 15677fb0a95..9f17ef467e3 100644
--- a/app/workers/repository_import_worker.rb
+++ b/app/workers/repository_import_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class RepositoryImportWorker
+class RepositoryImportWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ExceptionBacktrace
include ProjectStartImport
diff --git a/app/workers/repository_remove_remote_worker.rb b/app/workers/repository_remove_remote_worker.rb
index 3e55ebc77ed..23a9ec1e202 100644
--- a/app/workers/repository_remove_remote_worker.rb
+++ b/app/workers/repository_remove_remote_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class RepositoryRemoveRemoteWorker
+class RepositoryRemoveRemoteWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ExclusiveLeaseGuard
diff --git a/app/workers/repository_update_remote_mirror_worker.rb b/app/workers/repository_update_remote_mirror_worker.rb
index d1dec4cb732..cfff2382f04 100644
--- a/app/workers/repository_update_remote_mirror_worker.rb
+++ b/app/workers/repository_update_remote_mirror_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class RepositoryUpdateRemoteMirrorWorker
+class RepositoryUpdateRemoteMirrorWorker # rubocop:disable Scalability/IdempotentWorker
UpdateError = Class.new(StandardError)
include ApplicationWorker
diff --git a/app/workers/requests_profiles_worker.rb b/app/workers/requests_profiles_worker.rb
index b711cb99082..106f04d9409 100644
--- a/app/workers/requests_profiles_worker.rb
+++ b/app/workers/requests_profiles_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class RequestsProfilesWorker
+class RequestsProfilesWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
# rubocop:disable Scalability/CronWorkerContext
# This worker does not perform work scoped to a context
diff --git a/app/workers/run_pipeline_schedule_worker.rb b/app/workers/run_pipeline_schedule_worker.rb
index f8f8a2fe7ae..7d76cbed77f 100644
--- a/app/workers/run_pipeline_schedule_worker.rb
+++ b/app/workers/run_pipeline_schedule_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class RunPipelineScheduleWorker
+class RunPipelineScheduleWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include PipelineQueue
diff --git a/app/workers/schedule_migrate_external_diffs_worker.rb b/app/workers/schedule_migrate_external_diffs_worker.rb
index 0e3c62cf282..4e7b60c4ab7 100644
--- a/app/workers/schedule_migrate_external_diffs_worker.rb
+++ b/app/workers/schedule_migrate_external_diffs_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ScheduleMigrateExternalDiffsWorker
+class ScheduleMigrateExternalDiffsWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
# rubocop:disable Scalability/CronWorkerContext:
# This schedules the `MigrateExternalDiffsWorker`
diff --git a/app/workers/self_monitoring_project_create_worker.rb b/app/workers/self_monitoring_project_create_worker.rb
index 429ac8aacc4..8177efb1683 100644
--- a/app/workers/self_monitoring_project_create_worker.rb
+++ b/app/workers/self_monitoring_project_create_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class SelfMonitoringProjectCreateWorker
+class SelfMonitoringProjectCreateWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ExclusiveLeaseGuard
include SelfMonitoringProjectWorker
diff --git a/app/workers/self_monitoring_project_delete_worker.rb b/app/workers/self_monitoring_project_delete_worker.rb
index 07a7d3f6c45..4fa05d71de5 100644
--- a/app/workers/self_monitoring_project_delete_worker.rb
+++ b/app/workers/self_monitoring_project_delete_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class SelfMonitoringProjectDeleteWorker
+class SelfMonitoringProjectDeleteWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ExclusiveLeaseGuard
include SelfMonitoringProjectWorker
diff --git a/app/workers/stage_update_worker.rb b/app/workers/stage_update_worker.rb
index a96c4c6dda2..a5097d61927 100644
--- a/app/workers/stage_update_worker.rb
+++ b/app/workers/stage_update_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class StageUpdateWorker
+class StageUpdateWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include PipelineQueue
diff --git a/app/workers/stuck_ci_jobs_worker.rb b/app/workers/stuck_ci_jobs_worker.rb
index 6e4ffa36854..b3b1ed66efc 100644
--- a/app/workers/stuck_ci_jobs_worker.rb
+++ b/app/workers/stuck_ci_jobs_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class StuckCiJobsWorker
+class StuckCiJobsWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include CronjobQueue
diff --git a/app/workers/stuck_import_jobs_worker.rb b/app/workers/stuck_import_jobs_worker.rb
index c9675417aa4..6a48b78b22c 100644
--- a/app/workers/stuck_import_jobs_worker.rb
+++ b/app/workers/stuck_import_jobs_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class StuckImportJobsWorker
+class StuckImportJobsWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
# rubocop:disable Scalability/CronWorkerContext
# This worker updates several import states inline and does not schedule
diff --git a/app/workers/stuck_merge_jobs_worker.rb b/app/workers/stuck_merge_jobs_worker.rb
index 9214ae038a8..e0209b8237a 100644
--- a/app/workers/stuck_merge_jobs_worker.rb
+++ b/app/workers/stuck_merge_jobs_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class StuckMergeJobsWorker
+class StuckMergeJobsWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include CronjobQueue # rubocop:disable Scalability/CronWorkerContext
diff --git a/app/workers/system_hook_push_worker.rb b/app/workers/system_hook_push_worker.rb
index fc6237f359a..ff1f2baf058 100644
--- a/app/workers/system_hook_push_worker.rb
+++ b/app/workers/system_hook_push_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class SystemHookPushWorker
+class SystemHookPushWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category :source_code_management
diff --git a/app/workers/todos_destroyer/confidential_issue_worker.rb b/app/workers/todos_destroyer/confidential_issue_worker.rb
index 240a5f98ad5..b29d4168162 100644
--- a/app/workers/todos_destroyer/confidential_issue_worker.rb
+++ b/app/workers/todos_destroyer/confidential_issue_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module TodosDestroyer
- class ConfidentialIssueWorker
+ class ConfidentialIssueWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include TodosDestroyerQueue
diff --git a/app/workers/todos_destroyer/entity_leave_worker.rb b/app/workers/todos_destroyer/entity_leave_worker.rb
index 7db3f6c84b4..558cc32d158 100644
--- a/app/workers/todos_destroyer/entity_leave_worker.rb
+++ b/app/workers/todos_destroyer/entity_leave_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module TodosDestroyer
- class EntityLeaveWorker
+ class EntityLeaveWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include TodosDestroyerQueue
diff --git a/app/workers/todos_destroyer/group_private_worker.rb b/app/workers/todos_destroyer/group_private_worker.rb
index 21ec4abe478..a1943bee2ec 100644
--- a/app/workers/todos_destroyer/group_private_worker.rb
+++ b/app/workers/todos_destroyer/group_private_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module TodosDestroyer
- class GroupPrivateWorker
+ class GroupPrivateWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include TodosDestroyerQueue
diff --git a/app/workers/todos_destroyer/private_features_worker.rb b/app/workers/todos_destroyer/private_features_worker.rb
index 1e68f0fd5ae..6e55467234a 100644
--- a/app/workers/todos_destroyer/private_features_worker.rb
+++ b/app/workers/todos_destroyer/private_features_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module TodosDestroyer
- class PrivateFeaturesWorker
+ class PrivateFeaturesWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include TodosDestroyerQueue
diff --git a/app/workers/todos_destroyer/project_private_worker.rb b/app/workers/todos_destroyer/project_private_worker.rb
index 064e001530c..2a06edc666e 100644
--- a/app/workers/todos_destroyer/project_private_worker.rb
+++ b/app/workers/todos_destroyer/project_private_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module TodosDestroyer
- class ProjectPrivateWorker
+ class ProjectPrivateWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include TodosDestroyerQueue
diff --git a/app/workers/trending_projects_worker.rb b/app/workers/trending_projects_worker.rb
index 208d8b3b9b5..ee7724e0fa8 100644
--- a/app/workers/trending_projects_worker.rb
+++ b/app/workers/trending_projects_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class TrendingProjectsWorker
+class TrendingProjectsWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
# rubocop:disable Scalability/CronWorkerContext
# This worker does not perform work scoped to a context
diff --git a/app/workers/update_external_pull_requests_worker.rb b/app/workers/update_external_pull_requests_worker.rb
index e363b33f1b9..b459d26e487 100644
--- a/app/workers/update_external_pull_requests_worker.rb
+++ b/app/workers/update_external_pull_requests_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class UpdateExternalPullRequestsWorker
+class UpdateExternalPullRequestsWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category :source_code_management
diff --git a/app/workers/update_head_pipeline_for_merge_request_worker.rb b/app/workers/update_head_pipeline_for_merge_request_worker.rb
index e069b16eb90..47f0d1e0545 100644
--- a/app/workers/update_head_pipeline_for_merge_request_worker.rb
+++ b/app/workers/update_head_pipeline_for_merge_request_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class UpdateHeadPipelineForMergeRequestWorker
+class UpdateHeadPipelineForMergeRequestWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include PipelineQueue
diff --git a/app/workers/update_merge_requests_worker.rb b/app/workers/update_merge_requests_worker.rb
index ec9739e8a11..195b455f0aa 100644
--- a/app/workers/update_merge_requests_worker.rb
+++ b/app/workers/update_merge_requests_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class UpdateMergeRequestsWorker
+class UpdateMergeRequestsWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category :source_code_management
diff --git a/app/workers/update_project_statistics_worker.rb b/app/workers/update_project_statistics_worker.rb
index e36cebf6f4f..336877d9f57 100644
--- a/app/workers/update_project_statistics_worker.rb
+++ b/app/workers/update_project_statistics_worker.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
# Worker for updating project statistics.
-class UpdateProjectStatisticsWorker
+class UpdateProjectStatisticsWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category :source_code_management
diff --git a/app/workers/upload_checksum_worker.rb b/app/workers/upload_checksum_worker.rb
index d35367145b8..dc2511f718c 100644
--- a/app/workers/upload_checksum_worker.rb
+++ b/app/workers/upload_checksum_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class UploadChecksumWorker
+class UploadChecksumWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category :geo_replication
diff --git a/app/workers/wait_for_cluster_creation_worker.rb b/app/workers/wait_for_cluster_creation_worker.rb
index 621125c8503..2e3feb1a4d1 100644
--- a/app/workers/wait_for_cluster_creation_worker.rb
+++ b/app/workers/wait_for_cluster_creation_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class WaitForClusterCreationWorker
+class WaitForClusterCreationWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
include ClusterQueue
diff --git a/app/workers/web_hook_worker.rb b/app/workers/web_hook_worker.rb
index c3fa3162c14..6e1e7e7d62e 100644
--- a/app/workers/web_hook_worker.rb
+++ b/app/workers/web_hook_worker.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class WebHookWorker
+class WebHookWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category :integrations
diff --git a/changelogs/unreleased/38096-splitmr-write-resource-milestone-events-pd.yml b/changelogs/unreleased/38096-splitmr-write-resource-milestone-events-pd.yml
new file mode 100644
index 00000000000..def579b44e8
--- /dev/null
+++ b/changelogs/unreleased/38096-splitmr-write-resource-milestone-events-pd.yml
@@ -0,0 +1,5 @@
+---
+title: Add possibility to track milestone changes on issues and merge requests
+merge_request: 24780
+author:
+type: added
diff --git a/changelogs/unreleased/ak-rescue-error.yml b/changelogs/unreleased/ak-rescue-error.yml
new file mode 100644
index 00000000000..2815477d758
--- /dev/null
+++ b/changelogs/unreleased/ak-rescue-error.yml
@@ -0,0 +1,5 @@
+---
+title: Rescue elasticsearch server error in pod logs
+merge_request: 25367
+author:
+type: fixed
diff --git a/changelogs/unreleased/migrate-fa-spinner-in-views-dashboard-todos.yml b/changelogs/unreleased/migrate-fa-spinner-in-views-dashboard-todos.yml
new file mode 100644
index 00000000000..7007400ede6
--- /dev/null
+++ b/changelogs/unreleased/migrate-fa-spinner-in-views-dashboard-todos.yml
@@ -0,0 +1,5 @@
+---
+title: Use new loading spinner in Todos dashboard buttons
+merge_request: 25142
+author: Tsegaselassie Tadesse
+type: other
diff --git a/doc/development/background_migrations.md b/doc/development/background_migrations.md
index dfe2312c2fa..9dbfde98766 100644
--- a/doc/development/background_migrations.md
+++ b/doc/development/background_migrations.md
@@ -72,20 +72,21 @@ migration classes must be defined in the namespace
## Scheduling
-Scheduling a background migration should be done in a post-deployment migration.
+Scheduling a background migration should be done in a post-deployment
+migration that includes `Gitlab::Database::MigrationHelpers`
To do so, simply use the following code while
replacing the class name and arguments with whatever values are necessary for
your migration:
```ruby
-BackgroundMigrationWorker.perform_async('BackgroundMigrationClassName', [arg1, arg2, ...])
+migrate_async('BackgroundMigrationClassName', [arg1, arg2, ...])
```
Usually it's better to enqueue jobs in bulk, for this you can use
-`BackgroundMigrationWorker.bulk_perform_async`:
+`bulk_migrate_async`:
```ruby
-BackgroundMigrationWorker.bulk_perform_async(
+bulk_migrate_async(
[['BackgroundMigrationClassName', [1]],
['BackgroundMigrationClassName', [2]]]
)
@@ -105,7 +106,7 @@ If you would like to schedule jobs in bulk with a delay, you can use
jobs = [['BackgroundMigrationClassName', [1]],
['BackgroundMigrationClassName', [2]]]
-BackgroundMigrationWorker.bulk_perform_in(5.minutes, jobs)
+bulk_migrate_in(5.minutes, jobs)
```
### Rescheduling background migrations
diff --git a/lib/gitlab/database/migration_helpers.rb b/lib/gitlab/database/migration_helpers.rb
index 3b6684b861c..6317e034cfb 100644
--- a/lib/gitlab/database/migration_helpers.rb
+++ b/lib/gitlab/database/migration_helpers.rb
@@ -688,7 +688,7 @@ module Gitlab
start_id, end_id = batch.pluck('MIN(id), MAX(id)').first
max_index = index
- BackgroundMigrationWorker.perform_in(
+ migrate_in(
index * interval,
'CopyColumn',
[table, column, temp_column, start_id, end_id]
@@ -697,7 +697,7 @@ module Gitlab
# Schedule the renaming of the column to happen (initially) 1 hour after
# the last batch finished.
- BackgroundMigrationWorker.perform_in(
+ migrate_in(
(max_index * interval) + 1.hour,
'CleanupConcurrentTypeChange',
[table, column, temp_column]
@@ -779,7 +779,7 @@ module Gitlab
start_id, end_id = batch.pluck('MIN(id), MAX(id)').first
max_index = index
- BackgroundMigrationWorker.perform_in(
+ migrate_in(
index * interval,
'CopyColumn',
[table, old_column, new_column, start_id, end_id]
@@ -788,7 +788,7 @@ module Gitlab
# Schedule the renaming of the column to happen (initially) 1 hour after
# the last batch finished.
- BackgroundMigrationWorker.perform_in(
+ migrate_in(
(max_index * interval) + 1.hour,
'CleanupConcurrentRename',
[table, old_column, new_column]
@@ -1024,14 +1024,14 @@ into similar problems in the future (e.g. when new tables are created).
# We push multiple jobs at a time to reduce the time spent in
# Sidekiq/Redis operations. We're using this buffer based approach so we
# don't need to run additional queries for every range.
- BackgroundMigrationWorker.bulk_perform_async(jobs)
+ bulk_migrate_async(jobs)
jobs.clear
end
jobs << [job_class_name, [start_id, end_id]]
end
- BackgroundMigrationWorker.bulk_perform_async(jobs) unless jobs.empty?
+ bulk_migrate_async(jobs) unless jobs.empty?
end
# Queues background migration jobs for an entire table, batched by ID range.
@@ -1074,7 +1074,7 @@ into similar problems in the future (e.g. when new tables are created).
# `BackgroundMigrationWorker.bulk_perform_in` schedules all jobs for
# the same time, which is not helpful in most cases where we wish to
# spread the work over time.
- BackgroundMigrationWorker.perform_in(delay_interval * index, job_class_name, [start_id, end_id])
+ migrate_in(delay_interval * index, job_class_name, [start_id, end_id])
end
end
@@ -1133,6 +1133,30 @@ into similar problems in the future (e.g. when new tables are created).
execute(sql)
end
+ def migrate_async(*args)
+ with_migration_context do
+ BackgroundMigrationWorker.perform_async(*args)
+ end
+ end
+
+ def migrate_in(*args)
+ with_migration_context do
+ BackgroundMigrationWorker.perform_in(*args)
+ end
+ end
+
+ def bulk_migrate_in(*args)
+ with_migration_context do
+ BackgroundMigrationWorker.bulk_perform_in(*args)
+ end
+ end
+
+ def bulk_migrate_async(*args)
+ with_migration_context do
+ BackgroundMigrationWorker.bulk_perform_async(*args)
+ end
+ end
+
private
def tables_match?(target_table, foreign_key_table)
@@ -1191,6 +1215,10 @@ into similar problems in the future (e.g. when new tables are created).
your migration class
ERROR
end
+
+ def with_migration_context(&block)
+ Gitlab::ApplicationContext.with_context(caller_id: self.class.to_s, &block)
+ end
end
end
end
diff --git a/lib/gitlab/sidekiq_config/dummy_worker.rb b/lib/gitlab/sidekiq_config/dummy_worker.rb
index 858ff0db0c9..c2c8354b662 100644
--- a/lib/gitlab/sidekiq_config/dummy_worker.rb
+++ b/lib/gitlab/sidekiq_config/dummy_worker.rb
@@ -11,6 +11,7 @@ module Gitlab
has_external_dependencies: :worker_has_external_dependencies?,
latency_sensitive: :latency_sensitive_worker?,
resource_boundary: :get_worker_resource_boundary,
+ idempotent: :idempotent?,
weight: :get_weight
}.freeze
diff --git a/lib/gitlab/sidekiq_config/worker.rb b/lib/gitlab/sidekiq_config/worker.rb
index 6cbe327e6b2..4046ef54383 100644
--- a/lib/gitlab/sidekiq_config/worker.rb
+++ b/lib/gitlab/sidekiq_config/worker.rb
@@ -7,7 +7,7 @@ module Gitlab
attr_reader :klass
delegate :feature_category_not_owned?, :get_feature_category,
- :get_weight, :get_worker_resource_boundary,
+ :get_weight, :get_worker_resource_boundary, :idempotent?,
:latency_sensitive_worker?, :queue, :queue_namespace,
:worker_has_external_dependencies?,
to: :klass
@@ -51,7 +51,8 @@ module Gitlab
has_external_dependencies: worker_has_external_dependencies?,
latency_sensitive: latency_sensitive_worker?,
resource_boundary: get_worker_resource_boundary,
- weight: get_weight
+ weight: get_weight,
+ idempotent: idempotent?
}
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index e0209671160..e8418b34f2d 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -7044,6 +7044,9 @@ msgstr ""
msgid "Elasticsearch integration. Elasticsearch AWS IAM."
msgstr ""
+msgid "Elasticsearch returned status code: %{status_code}"
+msgstr ""
+
msgid "Elastic|None. Select namespaces to index."
msgstr ""
diff --git a/rubocop/cop/migration/schedule_async.rb b/rubocop/cop/migration/schedule_async.rb
new file mode 100644
index 00000000000..f296628c3d6
--- /dev/null
+++ b/rubocop/cop/migration/schedule_async.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+require_relative '../../migration_helpers'
+
+module RuboCop
+ module Cop
+ module Migration
+ class ScheduleAsync < RuboCop::Cop::Cop
+ include MigrationHelpers
+
+ ENFORCED_SINCE = 2020_02_12_00_00_00
+
+ MSG = <<~MSG
+ Don't call the background migration worker directly, use the `#migrate_async`,
+ `#migrate_in`, `#bulk_migrate_async` or `#bulk_migrate_in` migration helpers
+ instead.
+ MSG
+
+ def_node_matcher :calls_background_migration_worker?, <<~PATTERN
+ (send (const nil? :BackgroundMigrationWorker) {:perform_async :perform_in :bulk_perform_async :bulk_perform_in} ... )
+ PATTERN
+
+ def on_send(node)
+ return unless in_migration?(node)
+ return if version(node) < ENFORCED_SINCE
+
+ add_offense(node, location: :expression) if calls_background_migration_worker?(node)
+ end
+
+ def autocorrect(node)
+ # This gets rid of the receiver `BackgroundMigrationWorker` and
+ # replaces `perform` with `schedule`
+ schedule_method = method_name(node).to_s.sub('perform', 'migrate')
+ arguments = arguments(node).map(&:source).join(', ')
+
+ replacement = "#{schedule_method}(#{arguments})"
+ lambda do |corrector|
+ corrector.replace(node.source_range, replacement)
+ end
+ end
+
+ private
+
+ def method_name(node)
+ node.children.second
+ end
+
+ def arguments(node)
+ node.children[2..-1]
+ end
+ end
+ end
+ end
+end
diff --git a/rubocop/cop/scalability/idempotent_worker.rb b/rubocop/cop/scalability/idempotent_worker.rb
new file mode 100644
index 00000000000..a38b457b7c7
--- /dev/null
+++ b/rubocop/cop/scalability/idempotent_worker.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+
+require_relative '../../code_reuse_helpers.rb'
+
+module RuboCop
+ module Cop
+ module Scalability
+ # This cop checks for the `idempotent!` call in the worker scope.
+ #
+ # @example
+ #
+ # # bad
+ # class TroubleMakerWorker
+ # def perform
+ # end
+ # end
+ #
+ # # good
+ # class NiceWorker
+ # idempotent!
+ #
+ # def perform
+ # end
+ # end
+ #
+ class IdempotentWorker < RuboCop::Cop::Cop
+ include CodeReuseHelpers
+
+ HELP_LINK = 'https://github.com/mperham/sidekiq/wiki/Best-Practices#2-make-your-job-idempotent-and-transactional'
+
+ MSG = <<~MSG
+ Avoid adding not idempotent workers.
+
+ A worker is considered idempotent if:
+
+ 1. It can safely run multiple times with the same arguments
+ 2. The application side-effects are expected to happen once (or side-effects of a second run are not impactful)
+ 3. It can safely be skipped if another job with the same arguments is already in the queue
+
+ If all the above is true, make sure to mark it as so by calling the `idempotent!`
+ method in the worker scope.
+
+ See #{HELP_LINK}
+ MSG
+
+ def_node_search :idempotent?, <<~PATTERN
+ (send nil? :idempotent!)
+ PATTERN
+
+ def on_class(node)
+ return unless in_worker?(node)
+ return if idempotent?(node)
+
+ add_offense(node, location: :expression)
+ end
+ end
+ end
+ end
+end
diff --git a/rubocop/migration_helpers.rb b/rubocop/migration_helpers.rb
index 577f768da67..767cacaecaf 100644
--- a/rubocop/migration_helpers.rb
+++ b/rubocop/migration_helpers.rb
@@ -10,6 +10,10 @@ module RuboCop
dirname(node).end_with?('db/post_migrate', 'db/geo/post_migrate')
end
+ def version(node)
+ File.basename(node.location.expression.source_buffer.name).split('_').first.to_i
+ end
+
private
def dirname(node)
diff --git a/spec/controllers/projects/milestones_controller_spec.rb b/spec/controllers/projects/milestones_controller_spec.rb
index 6b698c6da66..ee61ef73b45 100644
--- a/spec/controllers/projects/milestones_controller_spec.rb
+++ b/spec/controllers/projects/milestones_controller_spec.rb
@@ -135,6 +135,10 @@ describe Projects::MilestonesController do
end
describe "#destroy" do
+ before do
+ stub_feature_flags(track_resource_milestone_change_events: false)
+ end
+
it "removes milestone" do
expect(issue.milestone_id).to eq(milestone.id)
diff --git a/spec/factories/resource_milestone_event.rb b/spec/factories/resource_milestone_event.rb
new file mode 100644
index 00000000000..86c54f2be68
--- /dev/null
+++ b/spec/factories/resource_milestone_event.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :resource_milestone_event do
+ issue { merge_request.nil? ? create(:issue) : nil }
+ merge_request { nil }
+ milestone
+ action { :add }
+ state { :opened }
+ user { issue&.author || merge_request&.author || create(:user) }
+ end
+end
diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb
index 4cf2553b90d..bb5475130cf 100644
--- a/spec/lib/gitlab/database/migration_helpers_spec.rb
+++ b/spec/lib/gitlab/database/migration_helpers_spec.rb
@@ -1893,4 +1893,60 @@ describe Gitlab::Database::MigrationHelpers do
end
end
end
+
+ describe '#migrate_async' do
+ it 'calls BackgroundMigrationWorker.perform_async' do
+ expect(BackgroundMigrationWorker).to receive(:perform_async).with("Class", "hello", "world")
+
+ model.migrate_async("Class", "hello", "world")
+ end
+
+ it 'pushes a context with the current class name as caller_id' do
+ expect(Gitlab::ApplicationContext).to receive(:with_context).with(caller_id: model.class.to_s)
+
+ model.migrate_async('Class', 'hello', 'world')
+ end
+ end
+
+ describe '#migrate_in' do
+ it 'calls BackgroundMigrationWorker.perform_in' do
+ expect(BackgroundMigrationWorker).to receive(:perform_in).with(10.minutes, 'Class', 'Hello', 'World')
+
+ model.migrate_in(10.minutes, 'Class', 'Hello', 'World')
+ end
+
+ it 'pushes a context with the current class name as caller_id' do
+ expect(Gitlab::ApplicationContext).to receive(:with_context).with(caller_id: model.class.to_s)
+
+ model.migrate_in(10.minutes, 'Class', 'Hello', 'World')
+ end
+ end
+
+ describe '#bulk_migrate_async' do
+ it 'calls BackgroundMigrationWorker.bulk_perform_async' do
+ expect(BackgroundMigrationWorker).to receive(:bulk_perform_async).with([%w(Class hello world)])
+
+ model.bulk_migrate_async([%w(Class hello world)])
+ end
+
+ it 'pushes a context with the current class name as caller_id' do
+ expect(Gitlab::ApplicationContext).to receive(:with_context).with(caller_id: model.class.to_s)
+
+ model.bulk_migrate_async([%w(Class hello world)])
+ end
+ end
+
+ describe '#bulk_migrate_in' do
+ it 'calls BackgroundMigrationWorker.bulk_perform_in_' do
+ expect(BackgroundMigrationWorker).to receive(:bulk_perform_in).with(10.minutes, [%w(Class hello world)])
+
+ model.bulk_migrate_in(10.minutes, [%w(Class hello world)])
+ end
+
+ it 'pushes a context with the current class name as caller_id' do
+ expect(Gitlab::ApplicationContext).to receive(:with_context).with(caller_id: model.class.to_s)
+
+ model.bulk_migrate_in(10.minutes, [%w(Class hello world)])
+ end
+ end
end
diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml
index 4dadb310029..6c9a4bbfc71 100644
--- a/spec/lib/gitlab/import_export/all_models.yml
+++ b/spec/lib/gitlab/import_export/all_models.yml
@@ -9,6 +9,7 @@ issues:
- notes
- resource_label_events
- resource_weight_events
+- resource_milestone_events
- sentry_issue
- label_links
- labels
@@ -109,6 +110,7 @@ merge_requests:
- milestone
- notes
- resource_label_events
+- resource_milestone_events
- label_links
- labels
- last_edited_by
diff --git a/spec/lib/gitlab/sidekiq_config/worker_spec.rb b/spec/lib/gitlab/sidekiq_config/worker_spec.rb
index 38edd0f5eeb..fcdce8f9432 100644
--- a/spec/lib/gitlab/sidekiq_config/worker_spec.rb
+++ b/spec/lib/gitlab/sidekiq_config/worker_spec.rb
@@ -12,7 +12,8 @@ describe Gitlab::SidekiqConfig::Worker do
get_weight: attributes[:weight],
get_worker_resource_boundary: attributes[:resource_boundary],
latency_sensitive_worker?: attributes[:latency_sensitive],
- worker_has_external_dependencies?: attributes[:has_external_dependencies]
+ worker_has_external_dependencies?: attributes[:has_external_dependencies],
+ idempotent?: attributes[:idempotent]
)
described_class.new(inner_worker, ee: false)
@@ -89,7 +90,8 @@ describe Gitlab::SidekiqConfig::Worker do
has_external_dependencies: false,
latency_sensitive: false,
resource_boundary: :memory,
- weight: 2
+ weight: 2,
+ idempotent: true
}
attributes_b = {
@@ -97,7 +99,8 @@ describe Gitlab::SidekiqConfig::Worker do
has_external_dependencies: true,
latency_sensitive: true,
resource_boundary: :unknown,
- weight: 1
+ weight: 3,
+ idempotent: false
}
worker_a = create_worker(queue: 'a', **attributes_a)
diff --git a/spec/models/milestone_note_spec.rb b/spec/models/milestone_note_spec.rb
new file mode 100644
index 00000000000..9e77ef91bb2
--- /dev/null
+++ b/spec/models/milestone_note_spec.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe MilestoneNote do
+ describe '.from_event' do
+ let(:author) { create(:user) }
+ let(:project) { create(:project, :repository) }
+ let(:noteable) { create(:issue, author: author, project: project) }
+ let(:event) { create(:resource_milestone_event, issue: noteable) }
+
+ subject { described_class.from_event(event, resource: noteable, resource_parent: project) }
+
+ it_behaves_like 'a system note', exclude_project: true do
+ let(:action) { 'milestone' }
+ end
+ end
+end
diff --git a/spec/models/resource_milestone_event_spec.rb b/spec/models/resource_milestone_event_spec.rb
new file mode 100644
index 00000000000..1b0181e3fd2
--- /dev/null
+++ b/spec/models/resource_milestone_event_spec.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe ResourceMilestoneEvent, type: :model do
+ it_behaves_like 'a resource event'
+ it_behaves_like 'a resource event for issues'
+ it_behaves_like 'a resource event for merge requests'
+
+ it_behaves_like 'having unique enum values'
+
+ describe 'associations' do
+ it { is_expected.to belong_to(:milestone) }
+ end
+
+ describe 'validations' do
+ context 'when issue and merge_request are both nil' do
+ subject { build(described_class.name.underscore.to_sym, issue: nil, merge_request: nil) }
+
+ it { is_expected.not_to be_valid }
+ end
+
+ context 'when issue and merge_request are both set' do
+ subject { build(described_class.name.underscore.to_sym, issue: build(:issue), merge_request: build(:merge_request)) }
+
+ it { is_expected.not_to be_valid }
+ end
+
+ context 'when issue is set' do
+ subject { create(described_class.name.underscore.to_sym, issue: create(:issue), merge_request: nil) }
+
+ it { is_expected.to be_valid }
+ end
+
+ context 'when merge_request is set' do
+ subject { create(described_class.name.underscore.to_sym, issue: nil, merge_request: create(:merge_request)) }
+
+ it { is_expected.to be_valid }
+ end
+ end
+
+ describe 'states' do
+ [Issue, MergeRequest].each do |klass|
+ klass.available_states.each do |state|
+ it "supports state #{state.first} for #{klass.name.underscore}" do
+ model = create(klass.name.underscore, state: state[0])
+ key = model.class.name.underscore
+ event = build(described_class.name.underscore.to_sym, key => model, state: model.state)
+
+ expect(event.state).to eq(state[0])
+ end
+ end
+ end
+ end
+end
diff --git a/spec/rubocop/cop/migration/schedule_async_spec.rb b/spec/rubocop/cop/migration/schedule_async_spec.rb
new file mode 100644
index 00000000000..3453f1c51cc
--- /dev/null
+++ b/spec/rubocop/cop/migration/schedule_async_spec.rb
@@ -0,0 +1,152 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+
+require 'rubocop'
+require 'rubocop/rspec/support'
+
+require_relative '../../../../rubocop/cop/migration/schedule_async'
+
+describe RuboCop::Cop::Migration::ScheduleAsync do
+ include CopHelper
+
+ let(:cop) { described_class.new }
+ let(:source) do
+ <<~SOURCE
+ def up
+ BackgroundMigrationWorker.perform_async(ClazzName, "Bar", "Baz")
+ end
+ SOURCE
+ end
+
+ shared_examples 'a disabled cop' do
+ it 'does not register any offenses' do
+ inspect_source(source)
+
+ expect(cop.offenses).to be_empty
+ end
+ end
+
+ context 'outside of a migration' do
+ it_behaves_like 'a disabled cop'
+ end
+
+ context 'in a migration' do
+ before do
+ allow(cop).to receive(:in_migration?).and_return(true)
+ end
+
+ context 'in an old migration' do
+ before do
+ allow(cop).to receive(:version).and_return(described_class::ENFORCED_SINCE - 5)
+ end
+
+ it_behaves_like 'a disabled cop'
+ end
+
+ context 'that is recent' do
+ before do
+ allow(cop).to receive(:version).and_return(described_class::ENFORCED_SINCE + 5)
+ end
+
+ context 'BackgroundMigrationWorker.perform_async' do
+ it 'adds an offence when calling `BackgroundMigrationWorker.peform_async`' do
+ inspect_source(source)
+
+ expect(cop.offenses.size).to eq(1)
+ end
+
+ it 'autocorrects to the right version' do
+ correct_source = <<~CORRECT
+ def up
+ migrate_async(ClazzName, "Bar", "Baz")
+ end
+ CORRECT
+
+ expect(autocorrect_source(source)).to eq(correct_source)
+ end
+ end
+
+ context 'BackgroundMigrationWorker.perform_in' do
+ let(:source) do
+ <<~SOURCE
+ def up
+ BackgroundMigrationWorker
+ .perform_in(delay, ClazzName, "Bar", "Baz")
+ end
+ SOURCE
+ end
+
+ it 'adds an offence' do
+ inspect_source(source)
+
+ expect(cop.offenses.size).to eq(1)
+ end
+
+ it 'autocorrects to the right version' do
+ correct_source = <<~CORRECT
+ def up
+ migrate_in(delay, ClazzName, "Bar", "Baz")
+ end
+ CORRECT
+
+ expect(autocorrect_source(source)).to eq(correct_source)
+ end
+ end
+
+ context 'BackgroundMigrationWorker.bulk_perform_async' do
+ let(:source) do
+ <<~SOURCE
+ def up
+ BackgroundMigrationWorker
+ .bulk_perform_async(jobs)
+ end
+ SOURCE
+ end
+
+ it 'adds an offence' do
+ inspect_source(source)
+
+ expect(cop.offenses.size).to eq(1)
+ end
+
+ it 'autocorrects to the right version' do
+ correct_source = <<~CORRECT
+ def up
+ bulk_migrate_async(jobs)
+ end
+ CORRECT
+
+ expect(autocorrect_source(source)).to eq(correct_source)
+ end
+ end
+
+ context 'BackgroundMigrationWorker.bulk_perform_in' do
+ let(:source) do
+ <<~SOURCE
+ def up
+ BackgroundMigrationWorker
+ .bulk_perform_in(5.minutes, jobs)
+ end
+ SOURCE
+ end
+
+ it 'adds an offence' do
+ inspect_source(source)
+
+ expect(cop.offenses.size).to eq(1)
+ end
+
+ it 'autocorrects to the right version' do
+ correct_source = <<~CORRECT
+ def up
+ bulk_migrate_in(5.minutes, jobs)
+ end
+ CORRECT
+
+ expect(autocorrect_source(source)).to eq(correct_source)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/rubocop/cop/scalability/idempotent_worker_spec.rb b/spec/rubocop/cop/scalability/idempotent_worker_spec.rb
new file mode 100644
index 00000000000..7abd602f8bc
--- /dev/null
+++ b/spec/rubocop/cop/scalability/idempotent_worker_spec.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+require 'rubocop'
+require_relative '../../../support/helpers/expect_offense'
+require_relative '../../../../rubocop/cop/scalability/idempotent_worker'
+
+describe RuboCop::Cop::Scalability::IdempotentWorker do
+ include CopHelper
+ include ExpectOffense
+
+ subject(:cop) { described_class.new }
+
+ before do
+ allow(cop)
+ .to receive(:in_worker?)
+ .and_return(true)
+ end
+
+ it 'adds an offense when not defining idempotent method' do
+ inspect_source(<<~CODE.strip_indent)
+ class SomeWorker
+ end
+ CODE
+
+ expect(cop.offenses.size).to eq(1)
+ end
+
+ it 'adds an offense when not defining idempotent method' do
+ inspect_source(<<~CODE.strip_indent)
+ class SomeWorker
+ idempotent!
+ end
+ CODE
+
+ expect(cop.offenses.size).to be_zero
+ end
+end
diff --git a/spec/rubocop/migration_helpers_spec.rb b/spec/rubocop/migration_helpers_spec.rb
new file mode 100644
index 00000000000..73ced8c58da
--- /dev/null
+++ b/spec/rubocop/migration_helpers_spec.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+require 'rubocop'
+require 'rspec-parameterized'
+
+require_relative '../../rubocop/migration_helpers'
+
+describe RuboCop::MigrationHelpers do
+ using RSpec::Parameterized::TableSyntax
+
+ subject(:fake_cop) { Class.new { include RuboCop::MigrationHelpers }.new }
+
+ let(:node) { double(:node) }
+
+ before do
+ allow(node).to receive_message_chain('location.expression.source_buffer.name')
+ .and_return(name)
+ end
+
+ describe '#in_migration?' do
+ where(:name, :expected) do
+ '/gitlab/db/migrate/20200210184420_create_operations_scopes_table.rb' | true
+ '/gitlab/db/post_migrate/20200210184420_create_operations_scopes_table.rb' | true
+ '/gitlab/db/geo/migrate/20200210184420_create_operations_scopes_table.rb' | true
+ '/gitlab/db/geo/post_migrate/20200210184420_create_operations_scopes_table.rb' | true
+ '/gitlab/db/elsewhere/20200210184420_create_operations_scopes_table.rb' | false
+ end
+
+ with_them do
+ it { expect(fake_cop.in_migration?(node)).to eq(expected) }
+ end
+ end
+
+ describe '#in_post_deployment_migration?' do
+ where(:name, :expected) do
+ '/gitlab/db/migrate/20200210184420_create_operations_scopes_table.rb' | false
+ '/gitlab/db/post_migrate/20200210184420_create_operations_scopes_table.rb' | true
+ '/gitlab/db/geo/migrate/20200210184420_create_operations_scopes_table.rb' | false
+ '/gitlab/db/geo/post_migrate/20200210184420_create_operations_scopes_table.rb' | true
+ '/gitlab/db/elsewhere/20200210184420_create_operations_scopes_table.rb' | false
+ end
+
+ with_them do
+ it { expect(fake_cop.in_post_deployment_migration?(node)).to eq(expected) }
+ end
+ end
+
+ describe "#version" do
+ let(:name) do
+ '/path/to/gitlab/db/migrate/20200210184420_create_operations_scopes_table.rb'
+ end
+
+ it { expect(fake_cop.version(node)).to eq(20200210184420) }
+ end
+end
diff --git a/spec/services/issuable/clone/attributes_rewriter_spec.rb b/spec/services/issuable/clone/attributes_rewriter_spec.rb
index 20bda6984bd..6bc0df8260b 100644
--- a/spec/services/issuable/clone/attributes_rewriter_spec.rb
+++ b/spec/services/issuable/clone/attributes_rewriter_spec.rb
@@ -75,5 +75,47 @@ describe Issuable::Clone::AttributesRewriter do
expect(new_issue.reload.milestone).to eq(milestone)
end
+
+ context 'with existing milestone events' do
+ let!(:milestone1_project1) { create(:milestone, title: 'milestone1', project: project1) }
+ let!(:milestone2_project1) { create(:milestone, title: 'milestone2', project: project1) }
+ let!(:milestone3_project1) { create(:milestone, title: 'milestone3', project: project1) }
+
+ let!(:milestone1_project2) { create(:milestone, title: 'milestone1', project: project2) }
+ let!(:milestone2_project2) { create(:milestone, title: 'milestone2', project: project2) }
+
+ before do
+ original_issue.update(milestone: milestone2_project1)
+
+ create_event(milestone1_project1)
+ create_event(milestone2_project1)
+ create_event(milestone1_project1, 'remove')
+ create_event(milestone3_project1)
+ end
+
+ it 'copies existing resource milestone events' do
+ subject.execute
+
+ new_issue_milestone_events = new_issue.reload.resource_milestone_events
+ expect(new_issue_milestone_events.count).to eq(3)
+
+ expect_milestone_event(new_issue_milestone_events.first, milestone: milestone1_project2, action: 'add', state: 'opened')
+ expect_milestone_event(new_issue_milestone_events.second, milestone: milestone2_project2, action: 'add', state: 'opened')
+ expect_milestone_event(new_issue_milestone_events.third, milestone: milestone1_project2, action: 'remove', state: 'opened')
+ end
+
+ def create_event(milestone, action = 'add')
+ create(:resource_milestone_event, issue: original_issue, milestone: milestone, action: action)
+ end
+
+ def expect_milestone_event(event, expected_attrs)
+ expect(event.milestone_id).to eq(expected_attrs[:milestone].id)
+ expect(event.action).to eq(expected_attrs[:action])
+ expect(event.state).to eq(expected_attrs[:state])
+
+ expect(event.reference).to be_nil
+ expect(event.reference_html).to be_nil
+ end
+ end
end
end
diff --git a/spec/services/issuable/common_system_notes_service_spec.rb b/spec/services/issuable/common_system_notes_service_spec.rb
index 7e40ac9ff4d..771e7ca42c9 100644
--- a/spec/services/issuable/common_system_notes_service_spec.rb
+++ b/spec/services/issuable/common_system_notes_service_spec.rb
@@ -3,8 +3,9 @@
require 'spec_helper'
describe Issuable::CommonSystemNotesService do
- let(:user) { create(:user) }
- let(:project) { create(:project) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:user) { create(:user) }
+
let(:issuable) { create(:issue, project: project) }
context 'on issuable update' do
@@ -35,6 +36,8 @@ describe Issuable::CommonSystemNotesService do
before do
milestone = create(:milestone, project: project)
issuable.milestone_id = milestone.id
+
+ stub_feature_flags(track_resource_milestone_change_events: false)
end
it_behaves_like 'system note creation', {}, 'changed milestone'
@@ -97,12 +100,39 @@ describe Issuable::CommonSystemNotesService do
expect(event.user_id).to eq user.id
end
- it 'creates a system note for milestone set' do
- issuable.milestone = create(:milestone, project: project)
- issuable.save
+ context 'when milestone change event tracking is disabled' do
+ before do
+ stub_feature_flags(track_resource_milestone_change_events: false)
- expect { subject }.to change { issuable.notes.count }.from(0).to(1)
- expect(issuable.notes.last.note).to match('changed milestone')
+ issuable.milestone = create(:milestone, project: project)
+ issuable.save
+ end
+
+ it 'creates a system note for milestone set' do
+ expect { subject }.to change { issuable.notes.count }.from(0).to(1)
+ expect(issuable.notes.last.note).to match('changed milestone')
+ end
+
+ it 'does not create a milestone change event' do
+ expect { subject }.not_to change { ResourceMilestoneEvent.count }
+ end
+ end
+
+ context 'when milestone change event tracking is enabled' do
+ let_it_be(:milestone) { create(:milestone, project: project) }
+ let_it_be(:issuable) { create(:issue, project: project, milestone: milestone) }
+
+ before do
+ stub_feature_flags(track_resource_milestone_change_events: true)
+ end
+
+ it 'does not create a system note for milestone set' do
+ expect { subject }.not_to change { issuable.notes.count }
+ end
+
+ it 'creates a milestone change event' do
+ expect { subject }.to change { ResourceMilestoneEvent.count }.from(0).to(1)
+ end
end
it 'creates a system note for due_date set' do
diff --git a/spec/services/issues/update_service_spec.rb b/spec/services/issues/update_service_spec.rb
index 888a63980f6..5da77dd914c 100644
--- a/spec/services/issues/update_service_spec.rb
+++ b/spec/services/issues/update_service_spec.rb
@@ -385,6 +385,10 @@ describe Issues::UpdateService, :mailer do
end
context 'when the milestone is removed' do
+ before do
+ stub_feature_flags(track_resource_milestone_change_events: false)
+ end
+
let!(:non_subscriber) { create(:user) }
let!(:subscriber) do
@@ -411,6 +415,10 @@ describe Issues::UpdateService, :mailer do
end
context 'when the milestone is changed' do
+ before do
+ stub_feature_flags(track_resource_milestone_change_events: false)
+ end
+
let!(:non_subscriber) { create(:user) }
let!(:subscriber) do
diff --git a/spec/services/merge_requests/update_service_spec.rb b/spec/services/merge_requests/update_service_spec.rb
index f295f3c4a81..dd5d90b2d07 100644
--- a/spec/services/merge_requests/update_service_spec.rb
+++ b/spec/services/merge_requests/update_service_spec.rb
@@ -367,6 +367,10 @@ describe MergeRequests::UpdateService, :mailer do
end
context 'when the milestone is removed' do
+ before do
+ stub_feature_flags(track_resource_milestone_change_events: false)
+ end
+
let!(:non_subscriber) { create(:user) }
let!(:subscriber) do
@@ -393,6 +397,10 @@ describe MergeRequests::UpdateService, :mailer do
end
context 'when the milestone is changed' do
+ before do
+ stub_feature_flags(track_resource_milestone_change_events: false)
+ end
+
let!(:non_subscriber) { create(:user) }
let!(:subscriber) do
diff --git a/spec/services/resource_events/change_milestone_service_spec.rb b/spec/services/resource_events/change_milestone_service_spec.rb
new file mode 100644
index 00000000000..c6b4f8e1b7e
--- /dev/null
+++ b/spec/services/resource_events/change_milestone_service_spec.rb
@@ -0,0 +1,67 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe ResourceEvents::ChangeMilestoneService do
+ shared_examples 'milestone events creator' do
+ let_it_be(:user) { create(:user) }
+
+ let_it_be(:milestone) { create(:milestone) }
+
+ context 'when milestone is present' do
+ before do
+ resource.milestone = milestone
+ end
+
+ let(:service) { described_class.new(resource: resource, user: user, created_at: created_at_time) }
+
+ it 'creates the expected event record' do
+ expect { service.execute }.to change { ResourceMilestoneEvent.count }.from(0).to(1)
+
+ events = ResourceMilestoneEvent.all
+
+ expect(events.size).to eq(1)
+ expect_event_record(events.first, action: 'add', milestone: milestone, state: 'opened')
+ end
+ end
+
+ context 'when milestones is not present' do
+ before do
+ resource.milestone = nil
+ end
+
+ let(:service) { described_class.new(resource: resource, user: user, created_at: created_at_time) }
+
+ it 'creates the expected event records' do
+ expect { service.execute }.to change { ResourceMilestoneEvent.count }.from(0).to(1)
+
+ expect_event_record(ResourceMilestoneEvent.first, action: 'remove', milestone: nil, state: 'opened')
+ end
+ end
+
+ def expect_event_record(event, expected_attrs)
+ expect(event.action).to eq(expected_attrs[:action])
+ expect(event.state).to eq(expected_attrs[:state])
+ expect(event.user).to eq(user)
+ expect(event.issue).to eq(resource) if resource.is_a?(Issue)
+ expect(event.issue).to be_nil unless resource.is_a?(Issue)
+ expect(event.merge_request).to eq(resource) if resource.is_a?(MergeRequest)
+ expect(event.merge_request).to be_nil unless resource.is_a?(MergeRequest)
+ expect(event.milestone).to eq(expected_attrs[:milestone])
+ expect(event.created_at).to eq(created_at_time)
+ end
+ end
+
+ let_it_be(:merge_request) { create(:merge_request) }
+ let_it_be(:issue) { create(:issue) }
+
+ let!(:created_at_time) { Time.utc(2019, 12, 30) }
+
+ it_behaves_like 'milestone events creator' do
+ let(:resource) { issue }
+ end
+
+ it_behaves_like 'milestone events creator' do
+ let(:resource) { merge_request }
+ end
+end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 35bf6846ab3..b862fc4bbd9 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -119,6 +119,7 @@ RSpec.configure do |config|
config.include PolicyHelpers, type: :policy
config.include MemoryUsageHelper
config.include ExpectRequestWithStatus, type: :request
+ config.include IdempotentWorkerHelper, type: :worker
config.include RailsHelpers
if ENV['CI'] || ENV['RETRIES']
diff --git a/spec/support/helpers/idempotent_worker_helper.rb b/spec/support/helpers/idempotent_worker_helper.rb
new file mode 100644
index 00000000000..b80758d10bd
--- /dev/null
+++ b/spec/support/helpers/idempotent_worker_helper.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module IdempotentWorkerHelper
+ WORKER_EXEC_TIMES = 2
+
+ def perform_multiple(args = [], worker: described_class.new, exec_times: WORKER_EXEC_TIMES)
+ Sidekiq::Testing.inline! do
+ job_args = args.nil? ? [nil] : Array.wrap(args)
+
+ expect(worker).to receive(:perform).exactly(exec_times).and_call_original
+
+ exec_times.times { worker.perform(*job_args) }
+ end
+ end
+end
diff --git a/spec/support/shared_examples/quick_actions/issue/move_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/issue/move_quick_action_shared_examples.rb
index 897a962fc56..32c46753006 100644
--- a/spec/support/shared_examples/quick_actions/issue/move_quick_action_shared_examples.rb
+++ b/spec/support/shared_examples/quick_actions/issue/move_quick_action_shared_examples.rb
@@ -50,6 +50,8 @@ RSpec.shared_examples 'move quick action' do
let(:bug) { create(:label, project: project, title: 'bug') }
let(:wontfix) { create(:label, project: project, title: 'wontfix') }
+ let!(:target_milestone) { create(:milestone, title: '1.0', project: target_project) }
+
before do
target_project.add_maintainer(user)
end
diff --git a/spec/support/shared_examples/resource_events.rb b/spec/support/shared_examples/resource_events.rb
new file mode 100644
index 00000000000..d7e7349ad6c
--- /dev/null
+++ b/spec/support/shared_examples/resource_events.rb
@@ -0,0 +1,104 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+shared_examples 'a resource event' do
+ let_it_be(:user1) { create(:user) }
+ let_it_be(:user2) { create(:user) }
+
+ let_it_be(:issue1) { create(:issue, author: user1) }
+ let_it_be(:issue2) { create(:issue, author: user1) }
+ let_it_be(:issue3) { create(:issue, author: user2) }
+
+ describe 'validations' do
+ it { is_expected.not_to allow_value(nil).for(:user) }
+ end
+
+ describe 'associations' do
+ it { is_expected.to belong_to(:user) }
+ end
+
+ describe '.created_after' do
+ let!(:created_at1) { 1.day.ago }
+ let!(:created_at2) { 2.days.ago }
+ let!(:created_at3) { 3.days.ago }
+
+ let!(:event1) { create(described_class.name.underscore.to_sym, issue: issue1, created_at: created_at1) }
+ let!(:event2) { create(described_class.name.underscore.to_sym, issue: issue2, created_at: created_at2) }
+ let!(:event3) { create(described_class.name.underscore.to_sym, issue: issue2, created_at: created_at3) }
+
+ it 'returns the expected events' do
+ events = described_class.created_after(created_at3)
+
+ expect(events).to contain_exactly(event1, event2)
+ end
+
+ it 'returns no events if time is after last record time' do
+ events = described_class.created_after(1.minute.ago)
+
+ expect(events).to be_empty
+ end
+ end
+end
+
+shared_examples 'a resource event for issues' do
+ let_it_be(:user1) { create(:user) }
+ let_it_be(:user2) { create(:user) }
+
+ let_it_be(:issue1) { create(:issue, author: user1) }
+ let_it_be(:issue2) { create(:issue, author: user1) }
+ let_it_be(:issue3) { create(:issue, author: user2) }
+
+ describe 'associations' do
+ it { is_expected.to belong_to(:issue) }
+ end
+
+ describe '.by_issue' do
+ let_it_be(:event1) { create(described_class.name.underscore.to_sym, issue: issue1) }
+ let_it_be(:event2) { create(described_class.name.underscore.to_sym, issue: issue2) }
+ let_it_be(:event3) { create(described_class.name.underscore.to_sym, issue: issue1) }
+
+ it 'returns the expected records for an issue with events' do
+ events = described_class.by_issue(issue1)
+
+ expect(events).to contain_exactly(event1, event3)
+ end
+
+ it 'returns the expected records for an issue with no events' do
+ events = described_class.by_issue(issue3)
+
+ expect(events).to be_empty
+ end
+ end
+end
+
+shared_examples 'a resource event for merge requests' do
+ let_it_be(:user1) { create(:user) }
+ let_it_be(:user2) { create(:user) }
+
+ let_it_be(:merge_request1) { create(:merge_request, author: user1) }
+ let_it_be(:merge_request2) { create(:merge_request, author: user1) }
+ let_it_be(:merge_request3) { create(:merge_request, author: user2) }
+
+ describe 'associations' do
+ it { is_expected.to belong_to(:merge_request) }
+ end
+
+ describe '.by_merge_request' do
+ let_it_be(:event1) { create(described_class.name.underscore.to_sym, merge_request: merge_request1) }
+ let_it_be(:event2) { create(described_class.name.underscore.to_sym, merge_request: merge_request2) }
+ let_it_be(:event3) { create(described_class.name.underscore.to_sym, merge_request: merge_request1) }
+
+ it 'returns the expected records for an issue with events' do
+ events = described_class.by_merge_request(merge_request1)
+
+ expect(events).to contain_exactly(event1, event3)
+ end
+
+ it 'returns the expected records for an issue with no events' do
+ events = described_class.by_merge_request(merge_request3)
+
+ expect(events).to be_empty
+ end
+ end
+end
diff --git a/spec/support/shared_examples/workers/idempotency_shared_examples.rb b/spec/support/shared_examples/workers/idempotency_shared_examples.rb
new file mode 100644
index 00000000000..19be1fe2c9d
--- /dev/null
+++ b/spec/support/shared_examples/workers/idempotency_shared_examples.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+# This shared_example requires the following variables:
+# - job_args (if not given, will fallback to call perform without arguments)
+#
+# Usage:
+#
+# include_examples 'an idempotent worker' do
+# it 'checks the side-effects for multiple calls' do
+# # it'll call the job's perform method 3 times
+# # by default.
+# subject
+#
+# expect(model.state).to eq('state')
+# end
+# end
+#
+RSpec.shared_examples 'an idempotent worker' do
+ # Avoid stubbing calls for a more accurate run.
+ subject do
+ defined?(job_args) ? perform_multiple(job_args) : perform_multiple
+ end
+
+ it 'is labeled as idempotent' do
+ expect(described_class).to be_idempotent
+ end
+
+ it 'performs multiple times sequentially without raising an exception' do
+ expect { subject }.not_to raise_error
+ end
+end
diff --git a/spec/workers/background_migration_worker_spec.rb b/spec/workers/background_migration_worker_spec.rb
index aae6fa02a0c..2b2ffc9f5b9 100644
--- a/spec/workers/background_migration_worker_spec.rb
+++ b/spec/workers/background_migration_worker_spec.rb
@@ -11,7 +11,7 @@ describe BackgroundMigrationWorker, :clean_gitlab_redis_shared_state do
end
end
- describe '.perform' do
+ describe '#perform' do
it 'performs a background migration' do
expect(Gitlab::BackgroundMigration)
.to receive(:perform)
@@ -52,6 +52,14 @@ describe BackgroundMigrationWorker, :clean_gitlab_redis_shared_state do
worker.perform('Foo', [10, 20])
end
+
+ it 'sets the class that will be executed as the caller_id' do
+ expect(Gitlab::BackgroundMigration).to receive(:perform) do
+ expect(Labkit::Context.current.to_h).to include('meta.caller_id' => 'Foo')
+ end
+
+ worker.perform('Foo', [10, 20])
+ end
end
describe '#healthy_database?' do
diff --git a/spec/workers/expire_job_cache_worker_spec.rb b/spec/workers/expire_job_cache_worker_spec.rb
index eeab304d926..ebca7020ee5 100644
--- a/spec/workers/expire_job_cache_worker_spec.rb
+++ b/spec/workers/expire_job_cache_worker_spec.rb
@@ -6,20 +6,32 @@ describe ExpireJobCacheWorker do
set(:pipeline) { create(:ci_empty_pipeline) }
let(:project) { pipeline.project }
- subject { described_class.new }
-
describe '#perform' do
context 'with a job in the pipeline' do
let(:job) { create(:ci_build, pipeline: pipeline) }
+ let(:job_args) { job.id }
+
+ include_examples 'an idempotent worker' do
+ it 'invalidates Etag caching for the job path' do
+ pipeline_path = "/#{project.full_path}/pipelines/#{pipeline.id}.json"
+ job_path = "/#{project.full_path}/builds/#{job.id}.json"
+
+ spy_store = Gitlab::EtagCaching::Store.new
+
+ allow(Gitlab::EtagCaching::Store).to receive(:new) { spy_store }
- it 'invalidates Etag caching for the job path' do
- pipeline_path = "/#{project.full_path}/pipelines/#{pipeline.id}.json"
- job_path = "/#{project.full_path}/builds/#{job.id}.json"
+ expect(spy_store).to receive(:touch)
+ .exactly(IdempotentWorkerHelper::WORKER_EXEC_TIMES).times
+ .with(pipeline_path)
+ .and_call_original
- expect_any_instance_of(Gitlab::EtagCaching::Store).to receive(:touch).with(pipeline_path)
- expect_any_instance_of(Gitlab::EtagCaching::Store).to receive(:touch).with(job_path)
+ expect(spy_store).to receive(:touch)
+ .exactly(IdempotentWorkerHelper::WORKER_EXEC_TIMES).times
+ .with(job_path)
+ .and_call_original
- subject.perform(job.id)
+ subject
+ end
end
end
@@ -27,7 +39,7 @@ describe ExpireJobCacheWorker do
it 'does not change the etag store' do
expect(Gitlab::EtagCaching::Store).not_to receive(:new)
- subject.perform(9999)
+ perform_multiple(9999)
end
end
end