summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.rubocop.yml3
-rw-r--r--.rubocop_todo.yml18
-rw-r--r--.rubocop_todo/gitlab/namespaced_class.yml2517
-rw-r--r--.rubocop_todo/gitlab/policy_rule_boolean.yml4
-rw-r--r--.rubocop_todo/layout/hash_alignment.yml2
-rw-r--r--.rubocop_todo/rails/create_table_with_timestamps.yml69
-rw-r--r--.rubocop_todo/style/class_and_module_children.yml587
-rw-r--r--.rubocop_todo/style/empty_method.yml196
-rw-r--r--app/assets/javascripts/api/integrations_api.js21
-rw-r--r--app/assets/javascripts/diffs/components/app.vue2
-rw-r--r--app/assets/javascripts/diffs/components/diff_file.vue94
-rw-r--r--app/assets/javascripts/diffs/constants.js2
-rw-r--r--app/assets/javascripts/diffs/utils/queue_events.js26
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/components/add_namespace_modal/groups_list_item.vue50
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/components/app.vue21
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/components/sign_in_oauth_button.vue19
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/constants.js14
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/pages/sign_in/sign_in_page.vue2
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/store/actions.js53
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/store/mutation_types.js9
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/store/mutations.js24
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/store/state.js9
-rw-r--r--app/assets/javascripts/notes/components/discussion_counter.vue6
-rw-r--r--app/assets/stylesheets/page_bundles/jira_connect.scss6
-rw-r--r--app/graphql/types/concerns/gitlab_style_deprecations.rb4
-rw-r--r--app/helpers/namespaces_helper.rb2
-rw-r--r--app/views/jira_connect/users/show.html.haml2
-rw-r--r--app/views/projects/merge_requests/_mr_title.html.haml6
-rw-r--r--app/views/projects/tags/_tag.html.haml2
-rw-r--r--config/feature_categories.yml4
-rw-r--r--config/feature_flags/development/delayed_project_import_schedule_worker.yml8
-rw-r--r--data/removals/15_0/15-0-tracing.yml16
-rw-r--r--doc/ci/yaml/index.md2
-rw-r--r--doc/development/api_graphql_styleguide.md14
-rw-r--r--doc/development/documentation/versions.md2
-rw-r--r--doc/install/requirements.md2
-rw-r--r--doc/raketasks/backup_restore.md42
-rw-r--r--doc/update/removals.md10
-rw-r--r--doc/user/application_security/dependency_scanning/index.md63
-rw-r--r--lib/api/projects.rb11
-rw-r--r--lib/backup/manager.rb58
-rw-r--r--lib/backup/repositories.rb19
-rw-r--r--lib/gitlab/ci/templates/Jobs/Dependency-Scanning.gitlab-ci.yml1
-rw-r--r--locale/gitlab.pot23
-rw-r--r--qa/qa/page/project/pipeline/show.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/multi-project_pipelines_spec.rb14
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/parent_child_pipelines_dependent_relationship_spec.rb23
-rw-r--r--rubocop/cop/gitlab/namespaced_class.rb59
-rw-r--r--spec/features/merge_request/user_posts_diff_notes_spec.rb2
-rw-r--r--spec/frontend/diffs/utils/queue_events_spec.js37
-rw-r--r--spec/frontend/jira_connect/subscriptions/components/add_namespace_modal/groups_list_item_spec.js115
-rw-r--r--spec/frontend/jira_connect/subscriptions/components/app_spec.js26
-rw-r--r--spec/frontend/jira_connect/subscriptions/components/sign_in_oauth_button_spec.js30
-rw-r--r--spec/frontend/jira_connect/subscriptions/pages/sign_in/sign_in_page_spec.js4
-rw-r--r--spec/frontend/jira_connect/subscriptions/store/actions_spec.js113
-rw-r--r--spec/frontend/jira_connect/subscriptions/store/mutations_spec.js60
-rw-r--r--spec/frontend/notes/components/discussion_counter_spec.js1
-rw-r--r--spec/helpers/namespaces_helper_spec.rb4
-rw-r--r--spec/lib/backup/manager_spec.rb3
-rw-r--r--spec/lib/backup/repositories_spec.rb76
-rw-r--r--spec/requests/api/projects_spec.rb37
-rw-r--r--spec/rubocop/cop/gitlab/namespaced_class_spec.rb143
-rw-r--r--spec/support/shared_examples/graphql/types/gitlab_style_deprecations_shared_examples.rb2
-rw-r--r--spec/tasks/gitlab/backup_rake_spec.rb77
-rw-r--r--spec/views/projects/tags/index.html.haml_spec.rb2
-rw-r--r--spec/workers/every_sidekiq_worker_spec.rb2
66 files changed, 3314 insertions, 1567 deletions
diff --git a/.rubocop.yml b/.rubocop.yml
index 7b4ec350a35..3ad7255732b 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -765,3 +765,6 @@ Performance/ActiveRecordSubtransactionMethods:
Migration/BackgroundMigrationBaseClass:
Enabled: false
+
+Style/ClassAndModuleChildren:
+ Enabled: true
diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
index 25d544ee03f..88694e05229 100644
--- a/.rubocop_todo.yml
+++ b/.rubocop_todo.yml
@@ -6,17 +6,6 @@
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.
-# Offense count: 1
-Gitlab/PolicyRuleBoolean:
- Exclude:
- - 'ee/app/policies/ee/identity_provider_policy.rb'
-
-# Configuration parameters: Include.
-# Include: db/migrate/*.rb
-Rails/CreateTableWithTimestamps:
- Enabled: false
-
-# Offense count: 354
# Configuration parameters: Include.
# Include: app/models/**/*.rb
Rails/HasManyOrHasOneDependent:
@@ -26,10 +15,3 @@ Rails/HasManyOrHasOneDependent:
# Cop supports --auto-correct.
Style/CaseLikeIf:
Enabled: false
-
-# Offense count: 205
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle.
-# SupportedStyles: compact, expanded
-Style/EmptyMethod:
- Enabled: false
diff --git a/.rubocop_todo/gitlab/namespaced_class.yml b/.rubocop_todo/gitlab/namespaced_class.yml
index 97e6a8c9c3a..a92520bbe30 100644
--- a/.rubocop_todo/gitlab/namespaced_class.yml
+++ b/.rubocop_todo/gitlab/namespaced_class.yml
@@ -1,1196 +1,1327 @@
---
Gitlab/NamespacedClass:
Exclude:
- - app/channels/issues_channel.rb
- - app/controllers/abuse_reports_controller.rb
- - app/controllers/acme_challenges_controller.rb
- - app/controllers/application_controller.rb
- - app/controllers/autocomplete_controller.rb
- - app/controllers/chaos_controller.rb
- - app/controllers/confirmations_controller.rb
- - app/controllers/dashboard_controller.rb
- - app/controllers/graphql_controller.rb
- - app/controllers/groups_controller.rb
- - app/controllers/health_check_controller.rb
- - app/controllers/health_controller.rb
- - app/controllers/help_controller.rb
- - app/controllers/ide_controller.rb
- - app/controllers/invites_controller.rb
- - app/controllers/jwks_controller.rb
- - app/controllers/jwt_controller.rb
- - app/controllers/metrics_controller.rb
- - app/controllers/notification_settings_controller.rb
- - app/controllers/omniauth_callbacks_controller.rb
- - app/controllers/passwords_controller.rb
- - app/controllers/profiles_controller.rb
- - app/controllers/projects_controller.rb
- - app/controllers/registrations_controller.rb
- - app/controllers/root_controller.rb
- - app/controllers/runner_setup_controller.rb
- - app/controllers/search_controller.rb
- - app/controllers/sent_notifications_controller.rb
- - app/controllers/sessions_controller.rb
- - app/controllers/snippets_controller.rb
- - app/controllers/uploads_controller.rb
- - app/controllers/users_controller.rb
- - app/controllers/whats_new_controller.rb
- - app/finders/abuse_reports_finder.rb
- - app/finders/access_requests_finder.rb
- - app/finders/admin/projects_finder.rb
- - app/finders/applications_finder.rb
- - app/finders/award_emojis_finder.rb
- - app/finders/branches_finder.rb
- - app/finders/cluster_ancestors_finder.rb
- - app/finders/clusters_finder.rb
- - app/finders/container_repositories_finder.rb
- - app/finders/context_commits_finder.rb
- - app/finders/contributed_projects_finder.rb
- - app/finders/deployments_finder.rb
- - app/finders/events_finder.rb
- - app/finders/feature_flags_finder.rb
- - app/finders/feature_flags_user_lists_finder.rb
- - app/finders/fork_projects_finder.rb
- - app/finders/fork_targets_finder.rb
- - app/finders/freeze_periods_finder.rb
- - app/finders/git_refs_finder.rb
- - app/finders/group_descendants_finder.rb
- - app/finders/group_finder.rb
- - app/finders/group_members_finder.rb
- - app/finders/group_projects_finder.rb
- - app/finders/groups_finder.rb
- - app/finders/issuable_finder.rb
- - app/finders/issuable_finder/params.rb
- - app/finders/issues_finder.rb
- - app/finders/issues_finder/params.rb
- - app/finders/joined_groups_finder.rb
- - app/finders/keys_finder.rb
- - app/finders/labels_finder.rb
- - app/finders/lfs_pointers_finder.rb
- - app/finders/license_template_finder.rb
- - app/finders/members_finder.rb
- - app/finders/merge_request_target_project_finder.rb
- - app/finders/merge_requests_finder.rb
- - app/finders/merge_requests_finder/params.rb
- - app/finders/milestones_finder.rb
- - app/finders/notes_finder.rb
- - app/finders/pending_todos_finder.rb
- - app/finders/personal_access_tokens_finder.rb
- - app/finders/personal_projects_finder.rb
- - app/finders/projects_finder.rb
- - app/finders/prometheus_metrics_finder.rb
- - app/finders/protected_branches_finder.rb
- - app/finders/releases_finder.rb
- - app/finders/resource_milestone_event_finder.rb
- - app/finders/resource_state_event_finder.rb
- - app/finders/sentry_issue_finder.rb
- - app/finders/serverless_domain_finder.rb
- - app/finders/snippets_finder.rb
- - app/finders/starred_projects_finder.rb
- - app/finders/tags_finder.rb
- - app/finders/template_finder.rb
- - app/finders/todos_finder.rb
- - app/finders/union_finder.rb
- - app/finders/uploader_finder.rb
- - app/finders/user_finder.rb
- - app/finders/user_group_notification_settings_finder.rb
- - app/finders/user_groups_counter.rb
- - app/finders/user_recent_events_finder.rb
- - app/finders/users_finder.rb
- - app/finders/users_star_projects_finder.rb
- - app/finders/users_with_pending_todos_finder.rb
- - app/graphql/gitlab_schema.rb
- - app/mailers/abuse_report_mailer.rb
- - app/mailers/application_mailer.rb
- - app/mailers/devise_mailer.rb
- - app/mailers/email_rejection_mailer.rb
- - app/mailers/notify.rb
- - app/mailers/previews/devise_mailer_preview.rb
- - app/mailers/previews/email_rejection_mailer_preview.rb
- - app/mailers/previews/notify_preview.rb
- - app/mailers/previews/repository_check_mailer_preview.rb
- - app/mailers/repository_check_mailer.rb
- - app/models/ability.rb
- - app/models/abuse_report.rb
- - app/models/active_session.rb
- - app/models/appearance.rb
- - app/models/application_record.rb
- - app/models/application_setting.rb
- - app/models/application_setting/term.rb
- - app/models/approval.rb
- - app/models/audit_event.rb
- - app/models/authentication_event.rb
- - app/models/award_emoji.rb
- - app/models/badge.rb
- - app/models/badges/group_badge.rb
- - app/models/badges/project_badge.rb
- - app/models/blob.rb
- - app/models/board.rb
- - app/models/board_group_recent_visit.rb
- - app/models/board_project_recent_visit.rb
- - app/models/broadcast_message.rb
- - app/models/bulk_import.rb
- - app/models/chat_name.rb
- - app/models/chat_team.rb
- - app/models/ci_platform_metric.rb
- - app/models/commit.rb
- - app/models/commit_collection.rb
- - app/models/commit_range.rb
- - app/models/commit_status.rb
- - app/models/commit_user_mention.rb
- - app/models/commit_with_pipeline.rb
- - app/models/compare.rb
- - app/models/concerns/uniquify.rb
- - app/models/container_expiration_policy.rb
- - app/models/container_repository.rb
- - app/models/context_commits_diff.rb
- - app/models/custom_emoji.rb
- - app/models/data_list.rb
- - app/models/deploy_key.rb
- - app/models/deploy_keys_project.rb
- - app/models/deploy_token.rb
- - app/models/deployment.rb
- - app/models/deployment_cluster.rb
- - app/models/deployment_merge_request.rb
- - app/models/deployment_metrics.rb
- - app/models/description_version.rb
- - app/models/design_user_mention.rb
- - app/models/diff_discussion.rb
- - app/models/diff_note.rb
- - app/models/diff_note_position.rb
- - app/models/directly_addressed_user.rb
- - app/models/discussion.rb
- - app/models/discussion_note.rb
- - app/models/draft_note.rb
- - app/models/email.rb
- - app/models/environment.rb
- - app/models/environment_status.rb
- - app/models/epic.rb
- - app/models/event.rb
- - app/models/event_collection.rb
- - app/models/experiment.rb
- - app/models/experiment_subject.rb
- - app/models/experiment_user.rb
- - app/models/exported_protected_branch.rb
- - app/models/external_issue.rb
- - app/models/external_pull_request.rb
- - app/models/fork_network.rb
- - app/models/fork_network_member.rb
- - app/models/generic_commit_status.rb
- - app/models/gpg_key.rb
- - app/models/gpg_key_subkey.rb
- - app/models/gpg_signature.rb
- - app/models/grafana_integration.rb
- - app/models/group.rb
- - app/models/group_custom_attribute.rb
- - app/models/group_deploy_key.rb
- - app/models/group_deploy_keys_group.rb
- - app/models/group_deploy_token.rb
- - app/models/group_group_link.rb
- - app/models/group_import_state.rb
- - app/models/group_label.rb
- - app/models/guest.rb
- - app/models/hooks/active_hook_filter.rb
- - app/models/hooks/project_hook.rb
- - app/models/hooks/service_hook.rb
- - app/models/hooks/system_hook.rb
- - app/models/hooks/web_hook.rb
- - app/models/hooks/web_hook_log.rb
- - app/models/identity.rb
- - app/models/identity/uniqueness_scopes.rb
- - app/models/import_export_upload.rb
- - app/models/import_failure.rb
- - app/models/individual_note_discussion.rb
- - app/models/instance_configuration.rb
- - app/models/instance_metadata.rb
- - app/models/integration.rb
- - app/models/internal_id.rb
- - app/models/issuable_severity.rb
- - app/models/issue.rb
- - app/models/issue/metrics.rb
- - app/models/issue_assignee.rb
- - app/models/issue_collection.rb
- - app/models/issue_email_participant.rb
- - app/models/issue_link.rb
- - app/models/issue_user_mention.rb
- - app/models/iteration.rb
- - app/models/jira_connect_installation.rb
- - app/models/jira_connect_subscription.rb
- - app/models/jira_import_state.rb
- - app/models/key.rb
- - app/models/label.rb
- - app/models/label_link.rb
- - app/models/label_note.rb
- - app/models/label_priority.rb
- - app/models/legacy_diff_discussion.rb
- - app/models/legacy_diff_note.rb
- - app/models/lfs_download_object.rb
- - app/models/lfs_file_lock.rb
- - app/models/lfs_object.rb
- - app/models/lfs_objects_project.rb
- - app/models/license_template.rb
- - app/models/list.rb
- - app/models/list_user_preference.rb
- - app/models/member.rb
- - app/models/members/group_member.rb
- - app/models/members/last_group_owner_assigner.rb
- - app/models/members/project_member.rb
- - app/models/members/member_task.rb
- - app/models/members_preloader.rb
- - app/models/merge_request.rb
- - app/models/merge_request_assignee.rb
- - app/models/merge_request_context_commit.rb
- - app/models/merge_request_context_commit_diff_file.rb
- - app/models/merge_request_diff.rb
- - app/models/merge_request_diff_commit.rb
- - app/models/merge_request_diff_file.rb
- - app/models/merge_request_reviewer.rb
- - app/models/merge_request_user_mention.rb
- - app/models/merge_requests_closing_issues.rb
- - app/models/milestone.rb
- - app/models/milestone_note.rb
- - app/models/milestone_release.rb
- - app/models/namespace.rb
- - app/models/namespace/traversal_hierarchy.rb
- - app/models/namespace_onboarding_action.rb
- - app/models/namespace_setting.rb
- - app/models/note.rb
- - app/models/note_diff_file.rb
- - app/models/notification_reason.rb
- - app/models/notification_recipient.rb
- - app/models/notification_setting.rb
- - app/models/oauth_access_grant.rb
- - app/models/oauth_access_token.rb
- - app/models/out_of_context_discussion.rb
- - app/models/onboarding_progress.rb
- - app/models/pages_deployment.rb
- - app/models/pages_domain.rb
- - app/models/pages_domain_acme_order.rb
- - app/models/personal_access_token.rb
- - app/models/personal_snippet.rb
- - app/models/plan.rb
- - app/models/plan_limits.rb
- - app/models/pool_repository.rb
- - app/models/product_analytics_event.rb
- - app/models/programming_language.rb
- - app/models/project.rb
- - app/models/project_authorization.rb
- - app/models/project_auto_devops.rb
- - app/models/project_ci_cd_setting.rb
- - app/models/project_custom_attribute.rb
- - app/models/project_daily_statistic.rb
- - app/models/project_deploy_token.rb
- - app/models/project_export_job.rb
- - app/models/project_feature.rb
- - app/models/project_feature_usage.rb
- - app/models/project_group_link.rb
- - app/models/project_import_data.rb
- - app/models/project_import_state.rb
- - app/models/project_label.rb
- - app/models/project_metrics_setting.rb
- - app/models/project_pages_metadatum.rb
- - app/models/project_repository.rb
- - app/models/project_repository_storage_move.rb
- - app/models/project_setting.rb
- - app/models/project_snippet.rb
- - app/models/project_statistics.rb
- - app/models/project_team.rb
- - app/models/project_tracing_setting.rb
- - app/models/project_wiki.rb
- - app/models/prometheus_alert.rb
- - app/models/prometheus_alert_event.rb
- - app/models/prometheus_metric.rb
- - app/models/protectable_dropdown.rb
- - app/models/protected_branch.rb
- - app/models/protected_tag.rb
- - app/models/push_event.rb
- - app/models/push_event_payload.rb
- - app/models/raw_usage_data.rb
- - app/models/readme_blob.rb
- - app/models/redirect_route.rb
- - app/models/ref_matcher.rb
- - app/models/release.rb
- - app/models/release_highlight.rb
- - app/models/remote_mirror.rb
- - app/models/repository.rb
- - app/models/repository_language.rb
- - app/models/resource_event.rb
- - app/models/resource_label_event.rb
- - app/models/resource_milestone_event.rb
- - app/models/resource_state_event.rb
- - app/models/resource_timebox_event.rb
- - app/models/review.rb
- - app/models/route.rb
- - app/models/self_managed_prometheus_alert_event.rb
- - app/models/sent_notification.rb
- - app/models/sentry_issue.rb
- - app/models/service_desk_setting.rb
- - app/models/service_list.rb
- - app/models/shard.rb
- - app/models/snippet.rb
- - app/models/snippet_blob.rb
- - app/models/snippet_input_action.rb
- - app/models/snippet_input_action_collection.rb
- - app/models/snippet_repository.rb
- - app/models/snippet_repository_storage_move.rb
- - app/models/snippet_statistics.rb
- - app/models/snippet_user_mention.rb
- - app/models/spam_log.rb
- - app/models/ssh_host_key.rb
- - app/models/state_note.rb
- - app/models/subscription.rb
- - app/models/suggestion.rb
- - app/models/synthetic_note.rb
- - app/models/system_note_metadata.rb
- - app/models/term_agreement.rb
- - app/models/timelog.rb
- - app/models/todo.rb
- - app/models/tree.rb
- - app/models/trending_project.rb
- - app/models/u2f_registration.rb
- - app/models/upload.rb
- - app/models/user.rb
- - app/models/user_agent_detail.rb
- - app/models/user_canonical_email.rb
- - app/models/user_custom_attribute.rb
- - app/models/user_detail.rb
- - app/models/user_highest_role.rb
- - app/models/user_interacted_project.rb
- - app/models/user_mention.rb
- - app/models/user_preference.rb
- - app/models/user_status.rb
- - app/models/user_synced_attributes_metadata.rb
- - app/models/users_star_project.rb
- - app/models/users_statistics.rb
- - app/models/vulnerability.rb
- - app/models/web_ide_terminal.rb
- - app/models/webauthn_registration.rb
- - app/models/wiki.rb
- - app/models/wiki_directory.rb
- - app/models/wiki_page.rb
- - app/models/wiki_page/meta.rb
- - app/models/wiki_page/slug.rb
- - app/models/work_item.rb
- - app/models/x509_certificate.rb
- - app/models/x509_commit_signature.rb
- - app/models/x509_issuer.rb
- - app/models/zoom_meeting.rb
- - app/policies/application_setting/term_policy.rb
- - app/policies/award_emoji_policy.rb
- - app/policies/base_policy.rb
- - app/policies/blob_policy.rb
- - app/policies/board_policy.rb
- - app/policies/commit_policy.rb
- - app/policies/commit_status_policy.rb
- - app/policies/container_expiration_policy_policy.rb
- - app/policies/container_repository_policy.rb
- - app/policies/custom_emoji_policy.rb
- - app/policies/deploy_key_policy.rb
- - app/policies/deploy_keys_project_policy.rb
- - app/policies/deploy_token_policy.rb
- - app/policies/deployment_policy.rb
- - app/policies/draft_note_policy.rb
- - app/policies/environment_policy.rb
- - app/policies/external_issue_policy.rb
- - app/policies/global_policy.rb
- - app/policies/grafana_integration_policy.rb
- - app/policies/group_deploy_key_policy.rb
- - app/policies/group_deploy_keys_group_policy.rb
- - app/policies/group_label_policy.rb
- - app/policies/group_member_policy.rb
- - app/policies/group_policy.rb
- - app/policies/identity_provider_policy.rb
- - app/policies/instance_metadata_policy.rb
- - app/policies/integration_policy.rb
- - app/policies/issuable_policy.rb
- - app/policies/issue_policy.rb
- - app/policies/merge_request_policy.rb
- - app/policies/milestone_policy.rb
- - app/policies/namespace_policy.rb
- - app/policies/nil_policy.rb
- - app/policies/note_policy.rb
- - app/policies/personal_access_token_policy.rb
- - app/policies/personal_snippet_policy.rb
- - app/policies/project_ci_cd_setting_policy.rb
- - app/policies/project_label_policy.rb
- - app/policies/project_member_policy.rb
- - app/policies/project_policy.rb
- - app/policies/project_snippet_policy.rb
- - app/policies/project_statistics_policy.rb
- - app/policies/prometheus_alert_policy.rb
- - app/policies/protected_branch_policy.rb
- - app/policies/release_policy.rb
- - app/policies/repository_policy.rb
- - app/policies/resource_label_event_policy.rb
- - app/policies/suggestion_policy.rb
- - app/policies/timebox_policy.rb
- - app/policies/timelog_policy.rb
- - app/policies/todo_policy.rb
- - app/policies/user_policy.rb
- - app/policies/wiki_page_policy.rb
- - app/policies/wiki_policy.rb
- - app/policies/work_item_policy.rb
- - app/presenters/award_emoji_presenter.rb
- - app/presenters/blob_presenter.rb
- - app/presenters/board_presenter.rb
- - app/presenters/clusterable_presenter.rb
- - app/presenters/commit_presenter.rb
- - app/presenters/commit_status_presenter.rb
- - app/presenters/environment_presenter.rb
- - app/presenters/event_presenter.rb
- - app/presenters/generic_commit_status_presenter.rb
- - app/presenters/group_clusterable_presenter.rb
- - app/presenters/group_member_presenter.rb
- - app/presenters/instance_clusterable_presenter.rb
- - app/presenters/invitation_presenter.rb
- - app/presenters/issue_presenter.rb
- - app/presenters/label_presenter.rb
- - app/presenters/member_presenter.rb
- - app/presenters/members_presenter.rb
- - app/presenters/merge_request_presenter.rb
- - app/presenters/milestone_presenter.rb
- - app/presenters/pages_domain_presenter.rb
- - app/presenters/project_clusterable_presenter.rb
- - app/presenters/project_hook_presenter.rb
- - app/presenters/project_member_presenter.rb
- - app/presenters/project_presenter.rb
- - app/presenters/prometheus_alert_presenter.rb
- - app/presenters/release_presenter.rb
- - app/presenters/search_service_presenter.rb
- - app/presenters/sentry_error_presenter.rb
- - app/presenters/service_hook_presenter.rb
- - app/presenters/snippet_blob_presenter.rb
- - app/presenters/snippet_presenter.rb
- - app/presenters/todo_presenter.rb
- - app/presenters/tree_entry_presenter.rb
- - app/presenters/user_presenter.rb
- - app/presenters/web_hook_log_presenter.rb
- - app/serializers/accessibility_error_entity.rb
- - app/serializers/accessibility_reports_comparer_entity.rb
- - app/serializers/accessibility_reports_comparer_serializer.rb
- - app/serializers/analytics_build_entity.rb
- - app/serializers/analytics_build_serializer.rb
- - app/serializers/analytics_commit_entity.rb
- - app/serializers/analytics_commit_serializer.rb
- - app/serializers/analytics_generic_serializer.rb
- - app/serializers/analytics_issue_entity.rb
- - app/serializers/analytics_issue_serializer.rb
- - app/serializers/analytics_merge_request_entity.rb
- - app/serializers/analytics_merge_request_serializer.rb
- - app/serializers/analytics_stage_entity.rb
- - app/serializers/analytics_stage_serializer.rb
- - app/serializers/analytics_summary_entity.rb
- - app/serializers/analytics_summary_serializer.rb
- - app/serializers/award_emoji_entity.rb
- - app/serializers/base_discussion_entity.rb
- - app/serializers/base_serializer.rb
- - app/serializers/blob_entity.rb
- - app/serializers/board_serializer.rb
- - app/serializers/board_simple_entity.rb
- - app/serializers/build_action_entity.rb
- - app/serializers/build_artifact_entity.rb
- - app/serializers/build_coverage_entity.rb
- - app/serializers/build_details_entity.rb
- - app/serializers/build_metadata_entity.rb
- - app/serializers/build_serializer.rb
- - app/serializers/build_trace_entity.rb
- - app/serializers/build_trace_serializer.rb
- - app/serializers/cluster_application_entity.rb
- - app/serializers/cluster_entity.rb
- - app/serializers/cluster_serializer.rb
- - app/serializers/codequality_degradation_entity.rb
- - app/serializers/codequality_reports_comparer_entity.rb
- - app/serializers/codequality_reports_comparer_serializer.rb
- - app/serializers/cohort_activity_month_entity.rb
- - app/serializers/cohort_entity.rb
- - app/serializers/cohorts_entity.rb
- - app/serializers/cohorts_serializer.rb
- - app/serializers/commit_entity.rb
- - app/serializers/container_repositories_serializer.rb
- - app/serializers/container_repository_entity.rb
- - app/serializers/container_tag_entity.rb
- - app/serializers/container_tags_serializer.rb
- - app/serializers/context_commits_diff_entity.rb
- - app/serializers/current_board_entity.rb
- - app/serializers/current_board_serializer.rb
- - app/serializers/current_user_entity.rb
- - app/serializers/deploy_key_entity.rb
- - app/serializers/deploy_key_serializer.rb
- - app/serializers/deploy_keys_project_entity.rb
- - app/serializers/deployment_cluster_entity.rb
- - app/serializers/deployment_entity.rb
- - app/serializers/deployment_serializer.rb
- - app/serializers/detailed_status_entity.rb
- - app/serializers/diff_file_base_entity.rb
- - app/serializers/diff_file_entity.rb
- - app/serializers/diff_file_metadata_entity.rb
- - app/serializers/diff_line_entity.rb
- - app/serializers/diff_line_parallel_entity.rb
- - app/serializers/diff_line_serializer.rb
- - app/serializers/diff_viewer_entity.rb
- - app/serializers/diffs_entity.rb
- - app/serializers/diffs_metadata_entity.rb
- - app/serializers/diffs_metadata_serializer.rb
- - app/serializers/diffs_serializer.rb
- - app/serializers/discussion_diff_file_entity.rb
- - app/serializers/discussion_entity.rb
- - app/serializers/discussion_serializer.rb
- - app/serializers/draft_note_entity.rb
- - app/serializers/draft_note_serializer.rb
- - app/serializers/entity_request.rb
- - app/serializers/environment_entity.rb
- - app/serializers/environment_serializer.rb
- - app/serializers/environment_status_entity.rb
- - app/serializers/environment_status_serializer.rb
- - app/serializers/feature_flag_entity.rb
- - app/serializers/feature_flag_scope_entity.rb
- - app/serializers/feature_flag_serializer.rb
- - app/serializers/feature_flag_summary_entity.rb
- - app/serializers/feature_flag_summary_serializer.rb
- - app/serializers/feature_flags_client_entity.rb
- - app/serializers/feature_flags_client_serializer.rb
- - app/serializers/fork_namespace_entity.rb
- - app/serializers/fork_namespace_serializer.rb
- - app/serializers/group_analytics_stage_entity.rb
- - app/serializers/group_analytics_stage_serializer.rb
- - app/serializers/group_basic_entity.rb
- - app/serializers/group_child_entity.rb
- - app/serializers/group_child_serializer.rb
- - app/serializers/group_deploy_key_entity.rb
- - app/serializers/group_deploy_key_serializer.rb
- - app/serializers/group_deploy_keys_group_entity.rb
- - app/serializers/group_entity.rb
- - app/serializers/group_group_link_entity.rb
- - app/serializers/group_group_link_serializer.rb
- - app/serializers/group_issuable_autocomplete_entity.rb
- - app/serializers/group_issuable_autocomplete_serializer.rb
- - app/serializers/group_serializer.rb
- - app/serializers/issuable_entity.rb
- - app/serializers/issuable_sidebar_basic_entity.rb
- - app/serializers/issuable_sidebar_extras_entity.rb
- - app/serializers/issuable_sidebar_todo_entity.rb
- - app/serializers/issue_board_entity.rb
- - app/serializers/issue_entity.rb
- - app/serializers/issue_serializer.rb
- - app/serializers/issue_sidebar_basic_entity.rb
- - app/serializers/issue_sidebar_extras_entity.rb
- - app/serializers/job_artifact_report_entity.rb
- - app/serializers/job_entity.rb
- - app/serializers/job_group_entity.rb
- - app/serializers/label_entity.rb
- - app/serializers/label_serializer.rb
- - app/serializers/lfs_file_lock_entity.rb
- - app/serializers/lfs_file_lock_serializer.rb
- - app/serializers/linked_issue_entity.rb
- - app/serializers/linked_project_issue_entity.rb
- - app/serializers/linked_project_issue_serializer.rb
- - app/serializers/member_entity.rb
- - app/serializers/member_serializer.rb
- - app/serializers/member_user_entity.rb
- - app/serializers/merge_request_basic_entity.rb
- - app/serializers/merge_request_create_entity.rb
- - app/serializers/merge_request_create_serializer.rb
- - app/serializers/merge_request_current_user_entity.rb
- - app/serializers/merge_request_diff_entity.rb
- - app/serializers/merge_request_for_pipeline_entity.rb
- - app/serializers/merge_request_metrics_entity.rb
- - app/serializers/merge_request_noteable_entity.rb
- - app/serializers/merge_request_poll_cached_widget_entity.rb
- - app/serializers/merge_request_poll_widget_entity.rb
- - app/serializers/merge_request_serializer.rb
- - app/serializers/merge_request_sidebar_basic_entity.rb
- - app/serializers/merge_request_sidebar_extras_entity.rb
- - app/serializers/merge_request_user_entity.rb
- - app/serializers/merge_request_widget_commit_entity.rb
- - app/serializers/merge_request_widget_entity.rb
- - app/serializers/move_to_project_entity.rb
- - app/serializers/move_to_project_serializer.rb
- - app/serializers/namespace_basic_entity.rb
- - app/serializers/namespace_serializer.rb
- - app/serializers/note_attachment_entity.rb
- - app/serializers/note_entity.rb
- - app/serializers/note_user_entity.rb
- - app/serializers/paginated_diff_entity.rb
- - app/serializers/paginated_diff_serializer.rb
- - app/serializers/pipeline_details_entity.rb
- - app/serializers/pipeline_entity.rb
- - app/serializers/pipeline_serializer.rb
- - app/serializers/project_entity.rb
- - app/serializers/project_import_entity.rb
- - app/serializers/project_mirror_entity.rb
- - app/serializers/project_mirror_serializer.rb
- - app/serializers/project_note_entity.rb
- - app/serializers/project_note_serializer.rb
- - app/serializers/project_serializer.rb
- - app/serializers/prometheus_alert_entity.rb
- - app/serializers/prometheus_alert_serializer.rb
- - app/serializers/prometheus_metric_entity.rb
- - app/serializers/prometheus_metric_serializer.rb
- - app/serializers/release_entity.rb
- - app/serializers/release_serializer.rb
- - app/serializers/remote_mirror_entity.rb
- - app/serializers/review_app_setup_entity.rb
- - app/serializers/review_app_setup_serializer.rb
- - app/serializers/rollout_status_entity.rb
- - app/serializers/route_entity.rb
- - app/serializers/route_serializer.rb
- - app/serializers/runner_entity.rb
- - app/serializers/service_event_entity.rb
- - app/serializers/service_event_serializer.rb
- - app/serializers/service_field_entity.rb
- - app/serializers/service_field_serializer.rb
- - app/serializers/stage_entity.rb
- - app/serializers/stage_serializer.rb
- - app/serializers/suggestion_entity.rb
- - app/serializers/suggestion_serializer.rb
- - app/serializers/test_case_entity.rb
- - app/serializers/test_report_entity.rb
- - app/serializers/test_report_serializer.rb
- - app/serializers/test_report_summary_entity.rb
- - app/serializers/test_report_summary_serializer.rb
- - app/serializers/test_reports_comparer_entity.rb
- - app/serializers/test_reports_comparer_serializer.rb
- - app/serializers/test_suite_comparer_entity.rb
- - app/serializers/test_suite_entity.rb
- - app/serializers/test_suite_serializer.rb
- - app/serializers/test_suite_summary_entity.rb
- - app/serializers/trigger_variable_entity.rb
- - app/serializers/triggered_pipeline_entity.rb
- - app/serializers/user_entity.rb
- - app/serializers/user_preference_entity.rb
- - app/serializers/user_serializer.rb
- - app/serializers/web_ide_terminal_entity.rb
- - app/serializers/web_ide_terminal_serializer.rb
- - app/services/access_token_validation_service.rb
- - app/services/audit_event_service.rb
- - app/services/auto_merge_service.rb
- - app/services/base_container_service.rb
- - app/services/base_count_service.rb
- - app/services/base_project_service.rb
- - app/services/base_renderer.rb
- - app/services/base_service.rb
- - app/services/bulk_create_integration_service.rb
- - app/services/bulk_import_service.rb
- - app/services/bulk_push_event_payload_service.rb
- - app/services/bulk_update_integration_service.rb
- - app/services/cohorts_service.rb
- - app/services/compare_service.rb
- - app/services/container_expiration_policy_service.rb
- - app/services/event_create_service.rb
- - app/services/gravatar_service.rb
- - app/services/import_export_clean_up_service.rb
- - app/services/issuable_base_service.rb
- - app/services/issue_rebalancing_service.rb
- - app/services/markdown_content_rewriter_service.rb
- - app/services/merge_request_metrics_service.rb
- - app/services/metrics_service.rb
- - app/services/note_summary.rb
- - app/services/notification_service.rb
- - app/services/onboarding_progress_service.rb
- - app/services/post_receive_service.rb
- - app/services/preview_markdown_service.rb
- - app/services/push_event_payload_service.rb
- - app/services/repository_archive_clean_up_service.rb
- - app/services/reset_project_cache_service.rb
- - app/services/search_service.rb
- - app/services/service_response.rb
- - app/services/service_ping/submit_service.rb
- - app/services/system_hooks_service.rb
- - app/services/task_list_toggle_service.rb
- - app/services/todo_service.rb
- - app/services/update_container_registry_info_service.rb
- - app/services/upload_service.rb
- - app/services/user_agent_detail_service.rb
- - app/services/user_project_access_changed_service.rb
- - app/services/verify_pages_domain_service.rb
- - app/services/web_hook_service.rb
- - app/services/x509_certificate_revoke_service.rb
- - app/uploaders/attachment_uploader.rb
- - app/uploaders/avatar_uploader.rb
- - app/uploaders/deleted_object_uploader.rb
- - app/uploaders/dependency_proxy/file_uploader.rb
- - app/uploaders/external_diff_uploader.rb
- - app/uploaders/favicon_uploader.rb
- - app/uploaders/file_mover.rb
- - app/uploaders/file_uploader.rb
- - app/uploaders/gitlab_uploader.rb
- - app/uploaders/import_export_uploader.rb
- - app/uploaders/job_artifact_uploader.rb
- - app/uploaders/lfs_object_uploader.rb
- - app/uploaders/namespace_file_uploader.rb
- - app/uploaders/personal_file_uploader.rb
- - app/validators/abstract_path_validator.rb
- - app/validators/addressable_url_validator.rb
- - app/validators/any_field_validator.rb
- - app/validators/array_members_validator.rb
- - app/validators/branch_filter_validator.rb
- - app/validators/certificate_fingerprint_validator.rb
- - app/validators/certificate_key_validator.rb
- - app/validators/certificate_validator.rb
- - app/validators/cluster_name_validator.rb
- - app/validators/color_validator.rb
- - app/validators/cron_freeze_period_timezone_validator.rb
- - app/validators/cron_timezone_validator.rb
- - app/validators/cron_validator.rb
- - app/validators/devise_email_validator.rb
- - app/validators/duration_validator.rb
- - app/validators/feature_flag_strategies_validator.rb
- - app/validators/feature_flag_user_xids_validator.rb
- - app/validators/future_date_validator.rb
- - app/validators/html_safety_validator.rb
- - app/validators/ip_address_validator.rb
- - app/validators/js_regex_validator.rb
- - app/validators/json_schema_validator.rb
- - app/validators/key_restriction_validator.rb
- - app/validators/line_code_validator.rb
- - app/validators/named_ecdsa_key_validator.rb
- - app/validators/namespace_path_validator.rb
- - app/validators/project_path_validator.rb
- - app/validators/public_url_validator.rb
- - app/validators/qualified_domain_array_validator.rb
- - app/validators/rsa_key_validator.rb
- - app/validators/same_project_association_validator.rb
- - app/validators/sha_validator.rb
- - app/validators/system_hook_url_validator.rb
- - app/validators/top_level_group_validator.rb
- - app/validators/untrusted_regexp_validator.rb
- - app/validators/nested_attributes_duplicates_validator.rb
- - app/validators/x509_certificate_credentials_validator.rb
- - app/workers/admin_email_worker.rb
- - app/workers/approve_blocked_pending_approval_users_worker.rb
- - app/workers/archive_trace_worker.rb
- - app/workers/authorized_keys_worker.rb
- - app/workers/authorized_projects_worker.rb
- - app/workers/auto_merge_process_worker.rb
- - app/workers/background_migration_worker.rb
- - app/workers/build_coverage_worker.rb
- - app/workers/build_finished_worker.rb
- - app/workers/build_hooks_worker.rb
- - app/workers/build_queue_worker.rb
- - app/workers/build_success_worker.rb
- - app/workers/build_trace_sections_worker.rb
- - app/workers/bulk_import_worker.rb
- - app/workers/chat_notification_worker.rb
- - app/workers/ci_platform_metrics_update_cron_worker.rb
- - app/workers/cleanup_container_repository_worker.rb
- - app/workers/cluster_configure_istio_worker.rb
- - app/workers/cluster_install_app_worker.rb
- - app/workers/cluster_patch_app_worker.rb
- - app/workers/cluster_provision_worker.rb
- - app/workers/cluster_update_app_worker.rb
- - app/workers/cluster_upgrade_app_worker.rb
- - app/workers/cluster_wait_for_app_installation_worker.rb
- - app/workers/cluster_wait_for_app_update_worker.rb
- - app/workers/cluster_wait_for_ingress_ip_address_worker.rb
- - app/workers/container_expiration_policy_worker.rb
- - app/workers/create_commit_signature_worker.rb
- - app/workers/create_note_diff_file_worker.rb
- - app/workers/create_pipeline_worker.rb
- - app/workers/delete_container_repository_worker.rb
- - app/workers/delete_diff_files_worker.rb
- - app/workers/delete_merged_branches_worker.rb
- - app/workers/delete_stored_files_worker.rb
- - app/workers/delete_user_worker.rb
- - app/workers/destroy_pages_deployments_worker.rb
- - app/workers/detect_repository_languages_worker.rb
- - app/workers/disallow_two_factor_for_group_worker.rb
- - app/workers/disallow_two_factor_for_subgroups_worker.rb
- - app/workers/email_receiver_worker.rb
- - app/workers/emails_on_push_worker.rb
- - app/workers/error_tracking_issue_link_worker.rb
- - app/workers/expire_build_artifacts_worker.rb
- - app/workers/expire_build_instance_artifacts_worker.rb
- - app/workers/expire_job_cache_worker.rb
- - app/workers/expire_pipeline_cache_worker.rb
- - app/workers/export_csv_worker.rb
- - app/workers/external_service_reactive_caching_worker.rb
- - app/workers/file_hook_worker.rb
- - app/workers/flush_counter_increments_worker.rb
- - app/workers/git_garbage_collect_worker.rb
- - app/workers/gitlab_performance_bar_stats_worker.rb
- - app/workers/gitlab_shell_worker.rb
- - app/workers/gitlab_service_ping_worker.rb
- - app/workers/gitlab_usage_ping_worker.rb
- - app/workers/group_destroy_worker.rb
- - app/workers/group_export_worker.rb
- - app/workers/group_import_worker.rb
- - app/workers/import_export_project_cleanup_worker.rb
- - app/workers/import_issues_csv_worker.rb
- - app/workers/invalid_gpg_signature_update_worker.rb
- - app/workers/irker_worker.rb
- - app/workers/issuable_export_csv_worker.rb
- - app/workers/issue_due_scheduler_worker.rb
- - app/workers/issue_placement_worker.rb
- - app/workers/issue_rebalancing_worker.rb
- - app/workers/member_invitation_reminder_emails_worker.rb
- - app/workers/merge_request_cleanup_refs_worker.rb
- - app/workers/merge_request_mergeability_check_worker.rb
- - app/workers/merge_worker.rb
- - app/workers/migrate_external_diffs_worker.rb
- - app/workers/namespaceless_project_destroy_worker.rb
- - app/workers/new_issue_worker.rb
- - app/workers/new_merge_request_worker.rb
- - app/workers/new_note_worker.rb
- - app/workers/pages_domain_removal_cron_worker.rb
- - app/workers/pages_domain_ssl_renewal_cron_worker.rb
- - app/workers/pages_domain_ssl_renewal_worker.rb
- - app/workers/pages_domain_verification_cron_worker.rb
- - app/workers/pages_domain_verification_worker.rb
- - app/workers/pages_transfer_worker.rb
- - app/workers/pages_worker.rb
- - app/workers/partition_creation_worker.rb
- - app/workers/pipeline_hooks_worker.rb
- - app/workers/pipeline_metrics_worker.rb
- - app/workers/pipeline_notification_worker.rb
- - app/workers/pipeline_process_worker.rb
- - app/workers/pipeline_schedule_worker.rb
- - app/workers/pipeline_update_worker.rb
- - app/workers/post_receive.rb
- - app/workers/process_commit_worker.rb
- - app/workers/project_cache_worker.rb
- - app/workers/project_daily_statistics_worker.rb
- - app/workers/project_destroy_worker.rb
- - app/workers/project_export_worker.rb
- - app/workers/project_schedule_bulk_repository_shard_moves_worker.rb
- - app/workers/project_service_worker.rb
- - app/workers/project_update_repository_storage_worker.rb
- - app/workers/propagate_integration_group_worker.rb
- - app/workers/propagate_integration_inherit_descendant_worker.rb
- - app/workers/propagate_integration_inherit_worker.rb
- - app/workers/propagate_integration_project_worker.rb
- - app/workers/propagate_integration_worker.rb
- - app/workers/propagate_service_template_worker.rb
- - app/workers/prune_old_events_worker.rb
- - app/workers/prune_web_hook_logs_worker.rb
- - app/workers/purge_dependency_proxy_cache_worker.rb
- - app/workers/reactive_caching_worker.rb
- - app/workers/rebase_worker.rb
- - app/workers/remote_mirror_notification_worker.rb
- - app/workers/remove_expired_group_links_worker.rb
- - app/workers/remove_expired_members_worker.rb
- - app/workers/remove_unaccepted_member_invites_worker.rb
- - app/workers/remove_unreferenced_lfs_objects_worker.rb
- - app/workers/repository_archive_cache_worker.rb
- - app/workers/repository_cleanup_worker.rb
- - app/workers/repository_fork_worker.rb
- - app/workers/repository_import_worker.rb
- - app/workers/repository_remove_remote_worker.rb
- - app/workers/repository_update_remote_mirror_worker.rb
- - app/workers/run_pipeline_schedule_worker.rb
- - app/workers/schedule_merge_request_cleanup_refs_worker.rb
- - app/workers/schedule_migrate_external_diffs_worker.rb
- - app/workers/self_monitoring_project_create_worker.rb
- - app/workers/self_monitoring_project_delete_worker.rb
- - app/workers/service_desk_email_receiver_worker.rb
- - app/workers/snippet_schedule_bulk_repository_shard_moves_worker.rb
- - app/workers/snippet_update_repository_storage_worker.rb
- - app/workers/stage_update_worker.rb
- - app/workers/stuck_ci_jobs_worker.rb
- - app/workers/stuck_export_jobs_worker.rb
- - app/workers/stuck_merge_jobs_worker.rb
- - app/workers/system_hook_push_worker.rb
- - app/workers/trending_projects_worker.rb
- - app/workers/update_container_registry_info_worker.rb
- - app/workers/update_external_pull_requests_worker.rb
- - app/workers/update_head_pipeline_for_merge_request_worker.rb
- - app/workers/update_highest_role_worker.rb
- - app/workers/update_merge_requests_worker.rb
- - app/workers/update_project_statistics_worker.rb
- - app/workers/upload_checksum_worker.rb
- - app/workers/wait_for_cluster_creation_worker.rb
- - app/workers/web_hook_worker.rb
- - app/workers/x509_certificate_revoke_worker.rb
- - app/workers/x509_issuer_crl_check_worker.rb
- - ee/app/controllers/countries_controller.rb
- - ee/app/controllers/country_states_controller.rb
- - ee/app/controllers/omniauth_kerberos_spnego_controller.rb
- - ee/app/controllers/operations_controller.rb
- - ee/app/controllers/sitemap_controller.rb
- - ee/app/controllers/smartcard_controller.rb
- - ee/app/controllers/subscriptions_controller.rb
- - ee/app/controllers/survey_responses_controller.rb
- - ee/app/controllers/trial_registrations_controller.rb
- - ee/app/controllers/trials_controller.rb
- - ee/app/controllers/unsubscribes_controller.rb
- - ee/app/controllers/usernames_controller.rb
- - ee/app/finders/audit_log_finder.rb
- - ee/app/finders/billed_users_finder.rb
- - ee/app/finders/custom_project_templates_finder.rb
- - ee/app/finders/dast_scanner_profiles_finder.rb
- - ee/app/finders/dast_site_profiles_finder.rb
- - ee/app/finders/dast_site_validations_finder.rb
- - ee/app/finders/epics_finder.rb
- - ee/app/finders/geo_node_finder.rb
- - ee/app/finders/gpg_keys_finder.rb
- - ee/app/finders/group_saml_identity_finder.rb
- - ee/app/finders/groups_with_templates_finder.rb
- - ee/app/finders/iterations_finder.rb
- - ee/app/finders/licenses_finder.rb
- - ee/app/finders/merge_requests_compliance_finder.rb
- - ee/app/finders/merge_trains_finder.rb
- - ee/app/finders/productivity_analytics_finder.rb
- - ee/app/finders/scim_finder.rb
- - ee/app/finders/software_license_policies_finder.rb
- - ee/app/mailers/ci_minutes_usage_mailer.rb
- - ee/app/mailers/credentials_inventory_mailer.rb
- - ee/app/mailers/license_mailer.rb
- - ee/app/mailers/previews/ci_minutes_usage_mailer_preview.rb
- - ee/app/mailers/previews/license_mailer_preview.rb
- - ee/app/models/allowed_email_domain.rb
- - ee/app/models/approval_merge_request_rule.rb
- - ee/app/models/approval_merge_request_rule_source.rb
- - ee/app/models/approval_project_rule.rb
- - ee/app/models/approval_project_rules_protected_branch.rb
- - ee/app/models/approval_state.rb
- - ee/app/models/approval_wrapped_any_approver_rule.rb
- - ee/app/models/approval_wrapped_code_owner_rule.rb
- - ee/app/models/approval_wrapped_rule.rb
- - ee/app/models/approver.rb
- - ee/app/models/approver_group.rb
- - ee/app/models/board_assignee.rb
- - ee/app/models/board_label.rb
- - ee/app/models/board_user_preference.rb
- - ee/app/models/burndown.rb
- - ee/app/models/dast_scanner_profile.rb
- - ee/app/models/dast_site.rb
- - ee/app/models/dast_site_profile.rb
- - ee/app/models/dast_site_token.rb
- - ee/app/models/dast_site_validation.rb
- - ee/app/models/elasticsearch_indexed_namespace.rb
- - ee/app/models/elasticsearch_indexed_project.rb
- - ee/app/models/epic_issue.rb
- - ee/app/models/epic_user_mention.rb
- - ee/app/models/feature_flag_issue.rb
- - ee/app/models/geo_node.rb
- - ee/app/models/geo_node_namespace_link.rb
- - ee/app/models/geo_node_status.rb
- - ee/app/models/gitlab_subscription.rb
- - ee/app/models/gitlab_subscription_history.rb
- - ee/app/models/group_deletion_schedule.rb
- - ee/app/models/group_merge_request_approval_setting.rb
- - ee/app/models/group_wiki.rb
- - ee/app/models/group_wiki_repository.rb
- - ee/app/models/historical_data.rb
- - ee/app/models/hooks/group_hook.rb
- - ee/app/models/index_status.rb
- - ee/app/models/insight.rb
- - ee/app/models/instance_security_dashboard.rb
- - ee/app/models/ip_restriction.rb
- - ee/app/models/issuable_metric_image.rb
- - ee/app/models/issuable_sla.rb
- - ee/app/models/issuables_analytics.rb
- - ee/app/models/iteration_note.rb
- - ee/app/models/ldap_group_link.rb
- - ee/app/models/ldap_key.rb
- - ee/app/models/license.rb
- - ee/app/models/merge_request_block.rb
- - ee/app/models/merge_request_diff_detail.rb
- - ee/app/models/merge_train.rb
- - ee/app/models/namespace_limit.rb
- - ee/app/models/namespace_statistics.rb
- - ee/app/models/path_lock.rb
- - ee/app/models/pg_replication_slot.rb
- - ee/app/models/productivity_analytics.rb
- - ee/app/models/project_alias.rb
- - ee/app/models/project_repository_state.rb
- - ee/app/models/project_security_setting.rb
- - ee/app/models/protected_environment.rb
- - ee/app/models/push_rule.rb
- - ee/app/models/resource_iteration_event.rb
- - ee/app/models/resource_weight_event.rb
- - ee/app/models/saml_group_link.rb
- - ee/app/models/saml_provider.rb
- - ee/app/models/scim_identity.rb
- - ee/app/models/scim_oauth_access_token.rb
- - ee/app/models/scoped_label_set.rb
- - ee/app/models/slack_integration.rb
- - ee/app/models/smartcard_identity.rb
- - ee/app/models/software_license.rb
- - ee/app/models/software_license_policy.rb
- - ee/app/models/storage_shard.rb
- - ee/app/models/user_permission_export_upload.rb
- - ee/app/models/users_ops_dashboard_project.rb
- - ee/app/models/users_security_dashboard_project.rb
- - ee/app/models/vulnerability_user_mention.rb
- - ee/app/models/weight_note.rb
- - ee/app/policies/approval_merge_request_rule_policy.rb
- - ee/app/policies/approval_project_rule_policy.rb
- - ee/app/policies/approval_state_policy.rb
- - ee/app/policies/dast_scanner_profile_policy.rb
- - ee/app/policies/dast_site_profile_policy.rb
- - ee/app/policies/dast_site_validation_policy.rb
- - ee/app/policies/epic_policy.rb
- - ee/app/policies/geo_node_policy.rb
- - ee/app/policies/instance_security_dashboard_policy.rb
- - ee/app/policies/issuable_metric_image_policy.rb
- - ee/app/policies/iteration_policy.rb
- - ee/app/policies/push_rule_policy.rb
- - ee/app/policies/saml_provider_policy.rb
- - ee/app/policies/vulnerability_policy.rb
- - ee/app/presenters/approval_rule_presenter.rb
- - ee/app/presenters/audit_event_presenter.rb
- - ee/app/presenters/epic_issue_presenter.rb
- - ee/app/presenters/epic_presenter.rb
- - ee/app/presenters/iteration_presenter.rb
- - ee/app/presenters/merge_request_approver_presenter.rb
- - ee/app/presenters/subscription_presenter.rb
- - ee/app/presenters/vulnerability_presenter.rb
- - ee/app/serializers/audit_event_entity.rb
- - ee/app/serializers/audit_event_serializer.rb
- - ee/app/serializers/blocking_merge_request_entity.rb
- - ee/app/serializers/board_assignee_entity.rb
- - ee/app/serializers/board_label_entity.rb
- - ee/app/serializers/board_milestone_entity.rb
- - ee/app/serializers/dashboard_environment_entity.rb
- - ee/app/serializers/dashboard_environments_project_entity.rb
- - ee/app/serializers/dashboard_environments_serializer.rb
- - ee/app/serializers/dashboard_operations_project_entity.rb
- - ee/app/serializers/dashboard_operations_serializer.rb
- - ee/app/serializers/dependency_entity.rb
- - ee/app/serializers/dependency_list_entity.rb
- - ee/app/serializers/dependency_list_serializer.rb
- - ee/app/serializers/epic_base_entity.rb
- - ee/app/serializers/epic_entity.rb
- - ee/app/serializers/epic_note_entity.rb
- - ee/app/serializers/epic_note_serializer.rb
- - ee/app/serializers/epic_serializer.rb
- - ee/app/serializers/file_lock_entity.rb
- - ee/app/serializers/geo_design_registry_entity.rb
- - ee/app/serializers/geo_design_registry_serializer.rb
- - ee/app/serializers/geo_node_serializer.rb
- - ee/app/serializers/geo_node_status_serializer.rb
- - ee/app/serializers/geo_project_registry_entity.rb
- - ee/app/serializers/geo_project_registry_serializer.rb
- - ee/app/serializers/group_analytics_serializer.rb
- - ee/app/serializers/group_vulnerability_autocomplete_entity.rb
- - ee/app/serializers/group_vulnerability_autocomplete_serializer.rb
- - ee/app/serializers/invited_group_entity.rb
- - ee/app/serializers/invited_group_serializer.rb
- - ee/app/serializers/iteration_serializer.rb
- - ee/app/serializers/license_entity.rb
- - ee/app/serializers/license_scanning_reports_comparer_entity.rb
- - ee/app/serializers/license_scanning_reports_comparer_serializer.rb
- - ee/app/serializers/license_scanning_reports_serializer.rb
- - ee/app/serializers/licenses_list_entity.rb
- - ee/app/serializers/licenses_list_serializer.rb
- - ee/app/serializers/linked_epic_entity.rb
- - ee/app/serializers/linked_epic_issue_entity.rb
- - ee/app/serializers/linked_epic_issue_serializer.rb
- - ee/app/serializers/linked_epic_serializer.rb
- - ee/app/serializers/linked_feature_flag_issue_entity.rb
- - ee/app/serializers/linked_feature_flag_issue_serializer.rb
- - ee/app/serializers/managed_license_entity.rb
- - ee/app/serializers/managed_license_serializer.rb
- - ee/app/serializers/merge_request_compliance_entity.rb
- - ee/app/serializers/metrics_report_metric_entity.rb
- - ee/app/serializers/metrics_reports_comparer_entity.rb
- - ee/app/serializers/metrics_reports_comparer_serializer.rb
- - ee/app/serializers/milestone_serializer.rb
- - ee/app/serializers/namespace_entity.rb
- - ee/app/serializers/productivity_analytics_merge_request_entity.rb
- - ee/app/serializers/report_list_entity.rb
- - ee/app/serializers/scim_oauth_access_token_entity.rb
- - ee/app/serializers/storage_shard_entity.rb
- - ee/app/serializers/storage_shard_serializer.rb
- - ee/app/serializers/user_analytics_entity.rb
- - ee/app/serializers/vulnerability_entity.rb
- - ee/app/serializers/vulnerability_note_entity.rb
- - ee/app/serializers/vulnerability_note_serializer.rb
- - ee/app/serializers/vulnerability_serializer.rb
- - ee/app/services/clear_namespace_shared_runners_minutes_service.rb
- - ee/app/services/ldap_group_reset_service.rb
- - ee/app/services/start_pull_mirroring_service.rb
- - ee/app/services/timebox_report_service.rb
- - ee/app/uploaders/issuable_metric_image_uploader.rb
- - ee/app/validators/host_validator.rb
- - ee/app/validators/ldap_filter_validator.rb
- - ee/app/workers/active_user_count_threshold_worker.rb
- - ee/app/workers/adjourned_group_deletion_worker.rb
- - ee/app/workers/adjourned_project_deletion_worker.rb
- - ee/app/workers/adjourned_projects_deletion_cron_worker.rb
- - ee/app/workers/admin_emails_worker.rb
- - ee/app/workers/clear_shared_runners_minutes_worker.rb
- - ee/app/workers/create_github_webhook_worker.rb
- - ee/app/workers/dast_site_validation_worker.rb
- - ee/app/workers/elastic_association_indexer_worker.rb
- - ee/app/workers/elastic_cluster_reindexing_cron_worker.rb
- - ee/app/workers/elastic_commit_indexer_worker.rb
- - ee/app/workers/elastic_delete_project_worker.rb
- - ee/app/workers/elastic_full_index_worker.rb
- - ee/app/workers/elastic_index_bulk_cron_worker.rb
- - ee/app/workers/elastic_index_initial_bulk_cron_worker.rb
- - ee/app/workers/elastic_indexing_control_worker.rb
- - ee/app/workers/elastic_namespace_indexer_worker.rb
- - ee/app/workers/elastic_namespace_rollout_worker.rb
- - ee/app/workers/elastic_remove_expired_namespace_subscriptions_from_index_cron_worker.rb
- - ee/app/workers/geo_repository_destroy_worker.rb
- - ee/app/workers/group_saml_group_sync_worker.rb
- - ee/app/workers/historical_data_worker.rb
- - ee/app/workers/import_software_licenses_worker.rb
- - ee/app/workers/ingress_modsecurity_counter_metrics_worker.rb
- - ee/app/workers/iterations_update_status_worker.rb
- - ee/app/workers/ldap_all_groups_sync_worker.rb
- - ee/app/workers/ldap_group_sync_worker.rb
- - ee/app/workers/ldap_sync_worker.rb
- - ee/app/workers/merge_request_reset_approvals_worker.rb
- - ee/app/workers/network_policy_metrics_worker.rb
- - ee/app/workers/new_epic_worker.rb
- - ee/app/workers/project_import_schedule_worker.rb
- - ee/app/workers/project_template_export_worker.rb
- - ee/app/workers/refresh_license_compliance_checks_worker.rb
- - ee/app/workers/repository_push_audit_event_worker.rb
- - ee/app/workers/repository_update_mirror_worker.rb
- - ee/app/workers/scan_security_report_secrets_worker.rb
- - ee/app/workers/set_user_status_based_on_user_cap_setting_worker.rb
- - ee/app/workers/store_security_reports_worker.rb
- - ee/app/workers/store_security_scans_worker.rb
- - ee/app/workers/sync_seat_link_request_worker.rb
- - ee/app/workers/sync_seat_link_worker.rb
- - ee/app/workers/sync_security_reports_to_report_approval_rules_worker.rb
- - ee/app/workers/update_all_mirrors_worker.rb
- - ee/app/workers/update_max_seats_used_for_gitlab_com_subscriptions_worker.rb
- - ee/lib/gitlab/path_locks_finder.rb
- - ee/spec/support/elastic_query_name_inspector.rb
- - ee/spec/support/ssh_keygen.rb
- - ee/spec/support/test_license.rb
- - lib/carrier_wave_string_file.rb
- - lib/csv_builder.rb
- - lib/event_filter.rb
- - lib/feature.rb
- - lib/feature/definition.rb
- - lib/feature/gitaly.rb
- - lib/feature/logger.rb
- - lib/feature/shared.rb
- - lib/file_size_validator.rb
- - lib/forever.rb
- - lib/gitlab_danger.rb
- - lib/learn_gitlab.rb
- - lib/tasks/gitlab/graphql.rake
- - lib/tasks/gitlab/seed/group_seed.rake
- - lib/tasks/import.rake
- - lib/tasks/tokens.rake
- - lib/uploaded_file.rb
- - lib/version_check.rb
- - qa/spec/specs/helpers/quarantine_spec.rb
- - spec/controllers/concerns/page_limiter_spec.rb
- - spec/lib/bitbucket/collection_spec.rb
- - spec/lib/gitlab/database/bulk_update_spec.rb
- - spec/lib/gitlab/multi_destination_logger_spec.rb
- - spec/lib/marginalia_spec.rb
- - spec/mailers/notify_spec.rb
- - spec/models/concerns/batch_destroy_dependent_associations_spec.rb
- - spec/models/concerns/bulk_insertable_associations_spec.rb
- - spec/models/concerns/triggerable_hooks_spec.rb
- - spec/support/helpers/bare_repo_operations.rb
- - spec/support/helpers/ci_artifact_metadata_generator.rb
- - spec/support/helpers/fake_migration_classes.rb
- - spec/support/helpers/fake_u2f_device.rb
- - spec/support/helpers/fake_webauthn_device.rb
- - spec/support/helpers/markdown_feature.rb
- - spec/support/helpers/redis_without_keys.rb
- - spec/support/helpers/require_migration.rb
- - spec/support/inspect_squelch.rb
- - spec/support/models/merge_request_without_merge_request_diff.rb
- - spec/support/renameable_upload.rb
- - spec/support/sidekiq_middleware.rb
- - spec/tasks/gitlab/task_helpers_spec.rb
- - spec/uploaders/object_storage_spec.rb
+ - 'app/controllers/abuse_reports_controller.rb'
+ - 'app/controllers/acme_challenges_controller.rb'
+ - 'app/controllers/application_controller.rb'
+ - 'app/controllers/autocomplete_controller.rb'
+ - 'app/controllers/chaos_controller.rb'
+ - 'app/controllers/confirmations_controller.rb'
+ - 'app/controllers/dashboard_controller.rb'
+ - 'app/controllers/graphql_controller.rb'
+ - 'app/controllers/groups_controller.rb'
+ - 'app/controllers/health_check_controller.rb'
+ - 'app/controllers/health_controller.rb'
+ - 'app/controllers/help_controller.rb'
+ - 'app/controllers/ide_controller.rb'
+ - 'app/controllers/invites_controller.rb'
+ - 'app/controllers/jwks_controller.rb'
+ - 'app/controllers/jwt_controller.rb'
+ - 'app/controllers/metrics_controller.rb'
+ - 'app/controllers/omniauth_callbacks_controller.rb'
+ - 'app/controllers/passwords_controller.rb'
+ - 'app/controllers/profiles_controller.rb'
+ - 'app/controllers/projects_controller.rb'
+ - 'app/controllers/registrations_controller.rb'
+ - 'app/controllers/root_controller.rb'
+ - 'app/controllers/runner_setup_controller.rb'
+ - 'app/controllers/search_controller.rb'
+ - 'app/controllers/sent_notifications_controller.rb'
+ - 'app/controllers/sessions_controller.rb'
+ - 'app/controllers/snippets_controller.rb'
+ - 'app/controllers/uploads_controller.rb'
+ - 'app/controllers/users_controller.rb'
+ - 'app/controllers/whats_new_controller.rb'
+ - 'app/finders/abuse_reports_finder.rb'
+ - 'app/finders/access_requests_finder.rb'
+ - 'app/finders/applications_finder.rb'
+ - 'app/finders/award_emojis_finder.rb'
+ - 'app/finders/branches_finder.rb'
+ - 'app/finders/cluster_ancestors_finder.rb'
+ - 'app/finders/clusters_finder.rb'
+ - 'app/finders/container_repositories_finder.rb'
+ - 'app/finders/context_commits_finder.rb'
+ - 'app/finders/contributed_projects_finder.rb'
+ - 'app/finders/deployments_finder.rb'
+ - 'app/finders/events_finder.rb'
+ - 'app/finders/feature_flags_finder.rb'
+ - 'app/finders/feature_flags_user_lists_finder.rb'
+ - 'app/finders/fork_projects_finder.rb'
+ - 'app/finders/fork_targets_finder.rb'
+ - 'app/finders/freeze_periods_finder.rb'
+ - 'app/finders/git_refs_finder.rb'
+ - 'app/finders/group_descendants_finder.rb'
+ - 'app/finders/group_finder.rb'
+ - 'app/finders/group_members_finder.rb'
+ - 'app/finders/group_projects_finder.rb'
+ - 'app/finders/groups_finder.rb'
+ - 'app/finders/issuable_finder.rb'
+ - 'app/finders/issuable_finder/params.rb'
+ - 'app/finders/issues_finder.rb'
+ - 'app/finders/issues_finder/params.rb'
+ - 'app/finders/joined_groups_finder.rb'
+ - 'app/finders/keys_finder.rb'
+ - 'app/finders/labels_finder.rb'
+ - 'app/finders/lfs_pointers_finder.rb'
+ - 'app/finders/license_template_finder.rb'
+ - 'app/finders/members_finder.rb'
+ - 'app/finders/merge_request_target_project_finder.rb'
+ - 'app/finders/merge_requests_finder.rb'
+ - 'app/finders/merge_requests_finder/params.rb'
+ - 'app/finders/milestones_finder.rb'
+ - 'app/finders/notes_finder.rb'
+ - 'app/finders/pending_todos_finder.rb'
+ - 'app/finders/personal_access_tokens_finder.rb'
+ - 'app/finders/personal_projects_finder.rb'
+ - 'app/finders/projects_finder.rb'
+ - 'app/finders/prometheus_metrics_finder.rb'
+ - 'app/finders/protected_branches_finder.rb'
+ - 'app/finders/releases_finder.rb'
+ - 'app/finders/resource_milestone_event_finder.rb'
+ - 'app/finders/resource_state_event_finder.rb'
+ - 'app/finders/sentry_issue_finder.rb'
+ - 'app/finders/serverless_domain_finder.rb'
+ - 'app/finders/snippets_finder.rb'
+ - 'app/finders/starred_projects_finder.rb'
+ - 'app/finders/tags_finder.rb'
+ - 'app/finders/template_finder.rb'
+ - 'app/finders/todos_finder.rb'
+ - 'app/finders/union_finder.rb'
+ - 'app/finders/uploader_finder.rb'
+ - 'app/finders/user_finder.rb'
+ - 'app/finders/user_group_notification_settings_finder.rb'
+ - 'app/finders/user_groups_counter.rb'
+ - 'app/finders/user_recent_events_finder.rb'
+ - 'app/finders/users_finder.rb'
+ - 'app/finders/users_star_projects_finder.rb'
+ - 'app/graphql/gitlab_schema.rb'
+ - 'app/mailers/abuse_report_mailer.rb'
+ - 'app/mailers/application_mailer.rb'
+ - 'app/mailers/devise_mailer.rb'
+ - 'app/mailers/email_rejection_mailer.rb'
+ - 'app/mailers/notify.rb'
+ - 'app/mailers/previews/devise_mailer_preview.rb'
+ - 'app/mailers/previews/email_rejection_mailer_preview.rb'
+ - 'app/mailers/previews/notify_preview.rb'
+ - 'app/mailers/previews/repository_check_mailer_preview.rb'
+ - 'app/mailers/repository_check_mailer.rb'
+ - 'app/models/ability.rb'
+ - 'app/models/abuse_report.rb'
+ - 'app/models/active_session.rb'
+ - 'app/models/appearance.rb'
+ - 'app/models/application_record.rb'
+ - 'app/models/application_setting.rb'
+ - 'app/models/application_setting/term.rb'
+ - 'app/models/approval.rb'
+ - 'app/models/audit_event.rb'
+ - 'app/models/authentication_event.rb'
+ - 'app/models/award_emoji.rb'
+ - 'app/models/badge.rb'
+ - 'app/models/badges/group_badge.rb'
+ - 'app/models/badges/project_badge.rb'
+ - 'app/models/blob.rb'
+ - 'app/models/board.rb'
+ - 'app/models/board_group_recent_visit.rb'
+ - 'app/models/board_project_recent_visit.rb'
+ - 'app/models/broadcast_message.rb'
+ - 'app/models/bulk_import.rb'
+ - 'app/models/chat_name.rb'
+ - 'app/models/chat_team.rb'
+ - 'app/models/ci_platform_metric.rb'
+ - 'app/models/commit.rb'
+ - 'app/models/commit_collection.rb'
+ - 'app/models/commit_range.rb'
+ - 'app/models/commit_status.rb'
+ - 'app/models/commit_user_mention.rb'
+ - 'app/models/compare.rb'
+ - 'app/models/concerns/uniquify.rb'
+ - 'app/models/container_expiration_policy.rb'
+ - 'app/models/container_repository.rb'
+ - 'app/models/context_commits_diff.rb'
+ - 'app/models/custom_emoji.rb'
+ - 'app/models/data_list.rb'
+ - 'app/models/deploy_key.rb'
+ - 'app/models/deploy_keys_project.rb'
+ - 'app/models/deploy_token.rb'
+ - 'app/models/deployment.rb'
+ - 'app/models/deployment_cluster.rb'
+ - 'app/models/deployment_merge_request.rb'
+ - 'app/models/deployment_metrics.rb'
+ - 'app/models/description_version.rb'
+ - 'app/models/design_user_mention.rb'
+ - 'app/models/diff_discussion.rb'
+ - 'app/models/diff_note.rb'
+ - 'app/models/diff_note_position.rb'
+ - 'app/models/directly_addressed_user.rb'
+ - 'app/models/discussion.rb'
+ - 'app/models/discussion_note.rb'
+ - 'app/models/draft_note.rb'
+ - 'app/models/email.rb'
+ - 'app/models/environment.rb'
+ - 'app/models/environment_status.rb'
+ - 'app/models/epic.rb'
+ - 'app/models/event.rb'
+ - 'app/models/event_collection.rb'
+ - 'app/models/experiment.rb'
+ - 'app/models/experiment_subject.rb'
+ - 'app/models/experiment_user.rb'
+ - 'app/models/exported_protected_branch.rb'
+ - 'app/models/external_issue.rb'
+ - 'app/models/external_pull_request.rb'
+ - 'app/models/fork_network.rb'
+ - 'app/models/fork_network_member.rb'
+ - 'app/models/generic_commit_status.rb'
+ - 'app/models/gpg_key.rb'
+ - 'app/models/gpg_key_subkey.rb'
+ - 'app/models/grafana_integration.rb'
+ - 'app/models/group.rb'
+ - 'app/models/group_custom_attribute.rb'
+ - 'app/models/group_deploy_key.rb'
+ - 'app/models/group_deploy_keys_group.rb'
+ - 'app/models/group_deploy_token.rb'
+ - 'app/models/group_group_link.rb'
+ - 'app/models/group_import_state.rb'
+ - 'app/models/group_label.rb'
+ - 'app/models/guest.rb'
+ - 'app/models/hooks/active_hook_filter.rb'
+ - 'app/models/hooks/project_hook.rb'
+ - 'app/models/hooks/service_hook.rb'
+ - 'app/models/hooks/system_hook.rb'
+ - 'app/models/hooks/web_hook.rb'
+ - 'app/models/hooks/web_hook_log.rb'
+ - 'app/models/identity.rb'
+ - 'app/models/identity/uniqueness_scopes.rb'
+ - 'app/models/import_export_upload.rb'
+ - 'app/models/import_failure.rb'
+ - 'app/models/individual_note_discussion.rb'
+ - 'app/models/instance_configuration.rb'
+ - 'app/models/instance_metadata.rb'
+ - 'app/models/integration.rb'
+ - 'app/models/internal_id.rb'
+ - 'app/models/issuable_severity.rb'
+ - 'app/models/issue.rb'
+ - 'app/models/issue_assignee.rb'
+ - 'app/models/issue_collection.rb'
+ - 'app/models/issue_email_participant.rb'
+ - 'app/models/issue_link.rb'
+ - 'app/models/issue_user_mention.rb'
+ - 'app/models/iteration.rb'
+ - 'app/models/jira_connect_installation.rb'
+ - 'app/models/jira_connect_subscription.rb'
+ - 'app/models/jira_import_state.rb'
+ - 'app/models/key.rb'
+ - 'app/models/label.rb'
+ - 'app/models/label_link.rb'
+ - 'app/models/label_note.rb'
+ - 'app/models/label_priority.rb'
+ - 'app/models/legacy_diff_discussion.rb'
+ - 'app/models/legacy_diff_note.rb'
+ - 'app/models/lfs_download_object.rb'
+ - 'app/models/lfs_file_lock.rb'
+ - 'app/models/lfs_object.rb'
+ - 'app/models/lfs_objects_project.rb'
+ - 'app/models/license_template.rb'
+ - 'app/models/list.rb'
+ - 'app/models/list_user_preference.rb'
+ - 'app/models/member.rb'
+ - 'app/models/members/group_member.rb'
+ - 'app/models/members/last_group_owner_assigner.rb'
+ - 'app/models/members/member_task.rb'
+ - 'app/models/members/project_member.rb'
+ - 'app/models/members_preloader.rb'
+ - 'app/models/merge_request.rb'
+ - 'app/models/merge_request_assignee.rb'
+ - 'app/models/merge_request_context_commit.rb'
+ - 'app/models/merge_request_context_commit_diff_file.rb'
+ - 'app/models/merge_request_diff.rb'
+ - 'app/models/merge_request_diff_commit.rb'
+ - 'app/models/merge_request_diff_file.rb'
+ - 'app/models/merge_request_reviewer.rb'
+ - 'app/models/merge_request_user_mention.rb'
+ - 'app/models/merge_requests_closing_issues.rb'
+ - 'app/models/milestone.rb'
+ - 'app/models/milestone_note.rb'
+ - 'app/models/milestone_release.rb'
+ - 'app/models/namespace.rb'
+ - 'app/models/namespace/traversal_hierarchy.rb'
+ - 'app/models/namespace_setting.rb'
+ - 'app/models/note.rb'
+ - 'app/models/note_diff_file.rb'
+ - 'app/models/notification_reason.rb'
+ - 'app/models/notification_recipient.rb'
+ - 'app/models/notification_setting.rb'
+ - 'app/models/oauth_access_grant.rb'
+ - 'app/models/oauth_access_token.rb'
+ - 'app/models/onboarding_progress.rb'
+ - 'app/models/out_of_context_discussion.rb'
+ - 'app/models/pages_deployment.rb'
+ - 'app/models/pages_domain.rb'
+ - 'app/models/pages_domain_acme_order.rb'
+ - 'app/models/personal_access_token.rb'
+ - 'app/models/personal_snippet.rb'
+ - 'app/models/plan.rb'
+ - 'app/models/plan_limits.rb'
+ - 'app/models/pool_repository.rb'
+ - 'app/models/product_analytics_event.rb'
+ - 'app/models/programming_language.rb'
+ - 'app/models/project.rb'
+ - 'app/models/project_authorization.rb'
+ - 'app/models/project_auto_devops.rb'
+ - 'app/models/project_ci_cd_setting.rb'
+ - 'app/models/project_custom_attribute.rb'
+ - 'app/models/project_daily_statistic.rb'
+ - 'app/models/project_deploy_token.rb'
+ - 'app/models/project_export_job.rb'
+ - 'app/models/project_feature.rb'
+ - 'app/models/project_feature_usage.rb'
+ - 'app/models/project_group_link.rb'
+ - 'app/models/project_import_data.rb'
+ - 'app/models/project_import_state.rb'
+ - 'app/models/project_label.rb'
+ - 'app/models/project_metrics_setting.rb'
+ - 'app/models/project_pages_metadatum.rb'
+ - 'app/models/project_repository.rb'
+ - 'app/models/project_setting.rb'
+ - 'app/models/project_snippet.rb'
+ - 'app/models/project_statistics.rb'
+ - 'app/models/project_team.rb'
+ - 'app/models/project_tracing_setting.rb'
+ - 'app/models/project_wiki.rb'
+ - 'app/models/prometheus_alert.rb'
+ - 'app/models/prometheus_alert_event.rb'
+ - 'app/models/prometheus_metric.rb'
+ - 'app/models/protectable_dropdown.rb'
+ - 'app/models/protected_branch.rb'
+ - 'app/models/protected_tag.rb'
+ - 'app/models/push_event.rb'
+ - 'app/models/push_event_payload.rb'
+ - 'app/models/raw_usage_data.rb'
+ - 'app/models/redirect_route.rb'
+ - 'app/models/ref_matcher.rb'
+ - 'app/models/release.rb'
+ - 'app/models/release_highlight.rb'
+ - 'app/models/remote_mirror.rb'
+ - 'app/models/repository.rb'
+ - 'app/models/repository_language.rb'
+ - 'app/models/resource_event.rb'
+ - 'app/models/resource_label_event.rb'
+ - 'app/models/resource_milestone_event.rb'
+ - 'app/models/resource_state_event.rb'
+ - 'app/models/resource_timebox_event.rb'
+ - 'app/models/review.rb'
+ - 'app/models/route.rb'
+ - 'app/models/self_managed_prometheus_alert_event.rb'
+ - 'app/models/sent_notification.rb'
+ - 'app/models/sentry_issue.rb'
+ - 'app/models/service_desk_setting.rb'
+ - 'app/models/service_list.rb'
+ - 'app/models/shard.rb'
+ - 'app/models/snippet.rb'
+ - 'app/models/snippet_blob.rb'
+ - 'app/models/snippet_input_action.rb'
+ - 'app/models/snippet_input_action_collection.rb'
+ - 'app/models/snippet_repository.rb'
+ - 'app/models/snippet_statistics.rb'
+ - 'app/models/snippet_user_mention.rb'
+ - 'app/models/spam_log.rb'
+ - 'app/models/ssh_host_key.rb'
+ - 'app/models/state_note.rb'
+ - 'app/models/subscription.rb'
+ - 'app/models/suggestion.rb'
+ - 'app/models/synthetic_note.rb'
+ - 'app/models/system_note_metadata.rb'
+ - 'app/models/term_agreement.rb'
+ - 'app/models/timelog.rb'
+ - 'app/models/todo.rb'
+ - 'app/models/tree.rb'
+ - 'app/models/trending_project.rb'
+ - 'app/models/u2f_registration.rb'
+ - 'app/models/upload.rb'
+ - 'app/models/user.rb'
+ - 'app/models/user_agent_detail.rb'
+ - 'app/models/user_canonical_email.rb'
+ - 'app/models/user_custom_attribute.rb'
+ - 'app/models/user_detail.rb'
+ - 'app/models/user_highest_role.rb'
+ - 'app/models/user_interacted_project.rb'
+ - 'app/models/user_mention.rb'
+ - 'app/models/user_preference.rb'
+ - 'app/models/user_status.rb'
+ - 'app/models/user_synced_attributes_metadata.rb'
+ - 'app/models/users_star_project.rb'
+ - 'app/models/users_statistics.rb'
+ - 'app/models/vulnerability.rb'
+ - 'app/models/web_ide_terminal.rb'
+ - 'app/models/webauthn_registration.rb'
+ - 'app/models/wiki.rb'
+ - 'app/models/wiki_directory.rb'
+ - 'app/models/wiki_page.rb'
+ - 'app/models/wiki_page/meta.rb'
+ - 'app/models/wiki_page/slug.rb'
+ - 'app/models/work_item.rb'
+ - 'app/models/x509_certificate.rb'
+ - 'app/models/x509_issuer.rb'
+ - 'app/models/zoom_meeting.rb'
+ - 'app/policies/application_setting/term_policy.rb'
+ - 'app/policies/award_emoji_policy.rb'
+ - 'app/policies/base_policy.rb'
+ - 'app/policies/blob_policy.rb'
+ - 'app/policies/board_policy.rb'
+ - 'app/policies/commit_policy.rb'
+ - 'app/policies/commit_status_policy.rb'
+ - 'app/policies/container_expiration_policy_policy.rb'
+ - 'app/policies/container_repository_policy.rb'
+ - 'app/policies/custom_emoji_policy.rb'
+ - 'app/policies/deploy_key_policy.rb'
+ - 'app/policies/deploy_keys_project_policy.rb'
+ - 'app/policies/deploy_token_policy.rb'
+ - 'app/policies/deployment_policy.rb'
+ - 'app/policies/draft_note_policy.rb'
+ - 'app/policies/environment_policy.rb'
+ - 'app/policies/external_issue_policy.rb'
+ - 'app/policies/global_policy.rb'
+ - 'app/policies/grafana_integration_policy.rb'
+ - 'app/policies/group_deploy_key_policy.rb'
+ - 'app/policies/group_deploy_keys_group_policy.rb'
+ - 'app/policies/group_label_policy.rb'
+ - 'app/policies/group_member_policy.rb'
+ - 'app/policies/group_policy.rb'
+ - 'app/policies/identity_provider_policy.rb'
+ - 'app/policies/instance_metadata_policy.rb'
+ - 'app/policies/integration_policy.rb'
+ - 'app/policies/issuable_policy.rb'
+ - 'app/policies/issue_policy.rb'
+ - 'app/policies/merge_request_policy.rb'
+ - 'app/policies/milestone_policy.rb'
+ - 'app/policies/namespace_policy.rb'
+ - 'app/policies/note_policy.rb'
+ - 'app/policies/personal_access_token_policy.rb'
+ - 'app/policies/personal_snippet_policy.rb'
+ - 'app/policies/project_ci_cd_setting_policy.rb'
+ - 'app/policies/project_label_policy.rb'
+ - 'app/policies/project_member_policy.rb'
+ - 'app/policies/project_policy.rb'
+ - 'app/policies/project_snippet_policy.rb'
+ - 'app/policies/project_statistics_policy.rb'
+ - 'app/policies/prometheus_alert_policy.rb'
+ - 'app/policies/protected_branch_policy.rb'
+ - 'app/policies/release_policy.rb'
+ - 'app/policies/repository_policy.rb'
+ - 'app/policies/resource_label_event_policy.rb'
+ - 'app/policies/suggestion_policy.rb'
+ - 'app/policies/timebox_policy.rb'
+ - 'app/policies/timelog_policy.rb'
+ - 'app/policies/todo_policy.rb'
+ - 'app/policies/user_policy.rb'
+ - 'app/policies/wiki_page_policy.rb'
+ - 'app/policies/wiki_policy.rb'
+ - 'app/policies/work_item_policy.rb'
+ - 'app/presenters/award_emoji_presenter.rb'
+ - 'app/presenters/blob_presenter.rb'
+ - 'app/presenters/board_presenter.rb'
+ - 'app/presenters/clusterable_presenter.rb'
+ - 'app/presenters/commit_presenter.rb'
+ - 'app/presenters/commit_status_presenter.rb'
+ - 'app/presenters/environment_presenter.rb'
+ - 'app/presenters/event_presenter.rb'
+ - 'app/presenters/generic_commit_status_presenter.rb'
+ - 'app/presenters/gitlab/blame_presenter.rb'
+ - 'app/presenters/group_clusterable_presenter.rb'
+ - 'app/presenters/group_member_presenter.rb'
+ - 'app/presenters/instance_clusterable_presenter.rb'
+ - 'app/presenters/invitation_presenter.rb'
+ - 'app/presenters/issue_presenter.rb'
+ - 'app/presenters/label_presenter.rb'
+ - 'app/presenters/member_presenter.rb'
+ - 'app/presenters/members_presenter.rb'
+ - 'app/presenters/merge_request_presenter.rb'
+ - 'app/presenters/milestone_presenter.rb'
+ - 'app/presenters/pages_domain_presenter.rb'
+ - 'app/presenters/project_clusterable_presenter.rb'
+ - 'app/presenters/project_hook_presenter.rb'
+ - 'app/presenters/project_member_presenter.rb'
+ - 'app/presenters/project_presenter.rb'
+ - 'app/presenters/prometheus_alert_presenter.rb'
+ - 'app/presenters/release_presenter.rb'
+ - 'app/presenters/search_service_presenter.rb'
+ - 'app/presenters/sentry_error_presenter.rb'
+ - 'app/presenters/service_hook_presenter.rb'
+ - 'app/presenters/snippet_blob_presenter.rb'
+ - 'app/presenters/snippet_presenter.rb'
+ - 'app/presenters/todo_presenter.rb'
+ - 'app/presenters/tree_entry_presenter.rb'
+ - 'app/presenters/user_presenter.rb'
+ - 'app/presenters/web_hook_log_presenter.rb'
+ - 'app/serializers/accessibility_error_entity.rb'
+ - 'app/serializers/accessibility_reports_comparer_entity.rb'
+ - 'app/serializers/accessibility_reports_comparer_serializer.rb'
+ - 'app/serializers/analytics_build_entity.rb'
+ - 'app/serializers/analytics_build_serializer.rb'
+ - 'app/serializers/analytics_commit_entity.rb'
+ - 'app/serializers/analytics_commit_serializer.rb'
+ - 'app/serializers/analytics_generic_serializer.rb'
+ - 'app/serializers/analytics_issue_entity.rb'
+ - 'app/serializers/analytics_issue_serializer.rb'
+ - 'app/serializers/analytics_merge_request_entity.rb'
+ - 'app/serializers/analytics_merge_request_serializer.rb'
+ - 'app/serializers/analytics_stage_entity.rb'
+ - 'app/serializers/analytics_stage_serializer.rb'
+ - 'app/serializers/analytics_summary_entity.rb'
+ - 'app/serializers/analytics_summary_serializer.rb'
+ - 'app/serializers/award_emoji_entity.rb'
+ - 'app/serializers/base_discussion_entity.rb'
+ - 'app/serializers/base_serializer.rb'
+ - 'app/serializers/blob_entity.rb'
+ - 'app/serializers/board_serializer.rb'
+ - 'app/serializers/board_simple_entity.rb'
+ - 'app/serializers/build_action_entity.rb'
+ - 'app/serializers/build_artifact_entity.rb'
+ - 'app/serializers/build_coverage_entity.rb'
+ - 'app/serializers/build_details_entity.rb'
+ - 'app/serializers/build_metadata_entity.rb'
+ - 'app/serializers/build_trace_entity.rb'
+ - 'app/serializers/build_trace_serializer.rb'
+ - 'app/serializers/cluster_application_entity.rb'
+ - 'app/serializers/cluster_entity.rb'
+ - 'app/serializers/cluster_serializer.rb'
+ - 'app/serializers/codequality_degradation_entity.rb'
+ - 'app/serializers/codequality_reports_comparer_entity.rb'
+ - 'app/serializers/codequality_reports_comparer_serializer.rb'
+ - 'app/serializers/cohort_activity_month_entity.rb'
+ - 'app/serializers/cohort_entity.rb'
+ - 'app/serializers/cohorts_entity.rb'
+ - 'app/serializers/cohorts_serializer.rb'
+ - 'app/serializers/commit_entity.rb'
+ - 'app/serializers/container_repositories_serializer.rb'
+ - 'app/serializers/container_repository_entity.rb'
+ - 'app/serializers/container_tag_entity.rb'
+ - 'app/serializers/container_tags_serializer.rb'
+ - 'app/serializers/context_commits_diff_entity.rb'
+ - 'app/serializers/current_board_entity.rb'
+ - 'app/serializers/current_board_serializer.rb'
+ - 'app/serializers/current_user_entity.rb'
+ - 'app/serializers/deploy_key_entity.rb'
+ - 'app/serializers/deploy_key_serializer.rb'
+ - 'app/serializers/deploy_keys_project_entity.rb'
+ - 'app/serializers/deployment_cluster_entity.rb'
+ - 'app/serializers/deployment_entity.rb'
+ - 'app/serializers/deployment_serializer.rb'
+ - 'app/serializers/detailed_status_entity.rb'
+ - 'app/serializers/diff_file_base_entity.rb'
+ - 'app/serializers/diff_file_entity.rb'
+ - 'app/serializers/diff_file_metadata_entity.rb'
+ - 'app/serializers/diff_line_entity.rb'
+ - 'app/serializers/diff_line_parallel_entity.rb'
+ - 'app/serializers/diff_line_serializer.rb'
+ - 'app/serializers/diff_viewer_entity.rb'
+ - 'app/serializers/diffs_entity.rb'
+ - 'app/serializers/diffs_metadata_entity.rb'
+ - 'app/serializers/diffs_metadata_serializer.rb'
+ - 'app/serializers/diffs_serializer.rb'
+ - 'app/serializers/discussion_diff_file_entity.rb'
+ - 'app/serializers/discussion_entity.rb'
+ - 'app/serializers/discussion_serializer.rb'
+ - 'app/serializers/draft_note_entity.rb'
+ - 'app/serializers/draft_note_serializer.rb'
+ - 'app/serializers/entity_request.rb'
+ - 'app/serializers/environment_entity.rb'
+ - 'app/serializers/environment_serializer.rb'
+ - 'app/serializers/environment_status_entity.rb'
+ - 'app/serializers/environment_status_serializer.rb'
+ - 'app/serializers/feature_flag_entity.rb'
+ - 'app/serializers/feature_flag_serializer.rb'
+ - 'app/serializers/feature_flag_summary_entity.rb'
+ - 'app/serializers/feature_flag_summary_serializer.rb'
+ - 'app/serializers/feature_flags_client_entity.rb'
+ - 'app/serializers/feature_flags_client_serializer.rb'
+ - 'app/serializers/fork_namespace_entity.rb'
+ - 'app/serializers/fork_namespace_serializer.rb'
+ - 'app/serializers/group_basic_entity.rb'
+ - 'app/serializers/group_child_entity.rb'
+ - 'app/serializers/group_child_serializer.rb'
+ - 'app/serializers/group_deploy_key_entity.rb'
+ - 'app/serializers/group_deploy_key_serializer.rb'
+ - 'app/serializers/group_deploy_keys_group_entity.rb'
+ - 'app/serializers/group_entity.rb'
+ - 'app/serializers/group_issuable_autocomplete_entity.rb'
+ - 'app/serializers/group_issuable_autocomplete_serializer.rb'
+ - 'app/serializers/group_serializer.rb'
+ - 'app/serializers/issuable_entity.rb'
+ - 'app/serializers/issuable_sidebar_basic_entity.rb'
+ - 'app/serializers/issuable_sidebar_extras_entity.rb'
+ - 'app/serializers/issuable_sidebar_todo_entity.rb'
+ - 'app/serializers/issue_board_entity.rb'
+ - 'app/serializers/issue_entity.rb'
+ - 'app/serializers/issue_serializer.rb'
+ - 'app/serializers/issue_sidebar_basic_entity.rb'
+ - 'app/serializers/issue_sidebar_extras_entity.rb'
+ - 'app/serializers/job_artifact_report_entity.rb'
+ - 'app/serializers/job_group_entity.rb'
+ - 'app/serializers/label_entity.rb'
+ - 'app/serializers/label_serializer.rb'
+ - 'app/serializers/lfs_file_lock_entity.rb'
+ - 'app/serializers/lfs_file_lock_serializer.rb'
+ - 'app/serializers/linked_issue_entity.rb'
+ - 'app/serializers/linked_project_issue_entity.rb'
+ - 'app/serializers/linked_project_issue_serializer.rb'
+ - 'app/serializers/member_entity.rb'
+ - 'app/serializers/member_serializer.rb'
+ - 'app/serializers/member_user_entity.rb'
+ - 'app/serializers/merge_request_basic_entity.rb'
+ - 'app/serializers/merge_request_create_entity.rb'
+ - 'app/serializers/merge_request_create_serializer.rb'
+ - 'app/serializers/merge_request_current_user_entity.rb'
+ - 'app/serializers/merge_request_diff_entity.rb'
+ - 'app/serializers/merge_request_for_pipeline_entity.rb'
+ - 'app/serializers/merge_request_metrics_entity.rb'
+ - 'app/serializers/merge_request_noteable_entity.rb'
+ - 'app/serializers/merge_request_poll_cached_widget_entity.rb'
+ - 'app/serializers/merge_request_poll_widget_entity.rb'
+ - 'app/serializers/merge_request_serializer.rb'
+ - 'app/serializers/merge_request_sidebar_basic_entity.rb'
+ - 'app/serializers/merge_request_sidebar_extras_entity.rb'
+ - 'app/serializers/merge_request_user_entity.rb'
+ - 'app/serializers/merge_request_widget_commit_entity.rb'
+ - 'app/serializers/merge_request_widget_entity.rb'
+ - 'app/serializers/move_to_project_entity.rb'
+ - 'app/serializers/move_to_project_serializer.rb'
+ - 'app/serializers/namespace_basic_entity.rb'
+ - 'app/serializers/namespace_serializer.rb'
+ - 'app/serializers/note_attachment_entity.rb'
+ - 'app/serializers/note_entity.rb'
+ - 'app/serializers/note_user_entity.rb'
+ - 'app/serializers/paginated_diff_entity.rb'
+ - 'app/serializers/paginated_diff_serializer.rb'
+ - 'app/serializers/pipeline_details_entity.rb'
+ - 'app/serializers/pipeline_serializer.rb'
+ - 'app/serializers/project_entity.rb'
+ - 'app/serializers/project_import_entity.rb'
+ - 'app/serializers/project_mirror_entity.rb'
+ - 'app/serializers/project_mirror_serializer.rb'
+ - 'app/serializers/project_note_entity.rb'
+ - 'app/serializers/project_note_serializer.rb'
+ - 'app/serializers/project_serializer.rb'
+ - 'app/serializers/prometheus_alert_entity.rb'
+ - 'app/serializers/prometheus_alert_serializer.rb'
+ - 'app/serializers/prometheus_metric_entity.rb'
+ - 'app/serializers/prometheus_metric_serializer.rb'
+ - 'app/serializers/release_entity.rb'
+ - 'app/serializers/release_serializer.rb'
+ - 'app/serializers/remote_mirror_entity.rb'
+ - 'app/serializers/review_app_setup_entity.rb'
+ - 'app/serializers/review_app_setup_serializer.rb'
+ - 'app/serializers/rollout_status_entity.rb'
+ - 'app/serializers/route_entity.rb'
+ - 'app/serializers/route_serializer.rb'
+ - 'app/serializers/runner_entity.rb'
+ - 'app/serializers/service_event_entity.rb'
+ - 'app/serializers/service_event_serializer.rb'
+ - 'app/serializers/service_field_entity.rb'
+ - 'app/serializers/service_field_serializer.rb'
+ - 'app/serializers/stage_entity.rb'
+ - 'app/serializers/stage_serializer.rb'
+ - 'app/serializers/suggestion_entity.rb'
+ - 'app/serializers/suggestion_serializer.rb'
+ - 'app/serializers/test_case_entity.rb'
+ - 'app/serializers/test_report_entity.rb'
+ - 'app/serializers/test_report_serializer.rb'
+ - 'app/serializers/test_report_summary_entity.rb'
+ - 'app/serializers/test_report_summary_serializer.rb'
+ - 'app/serializers/test_reports_comparer_entity.rb'
+ - 'app/serializers/test_reports_comparer_serializer.rb'
+ - 'app/serializers/test_suite_comparer_entity.rb'
+ - 'app/serializers/test_suite_entity.rb'
+ - 'app/serializers/test_suite_serializer.rb'
+ - 'app/serializers/test_suite_summary_entity.rb'
+ - 'app/serializers/trigger_variable_entity.rb'
+ - 'app/serializers/triggered_pipeline_entity.rb'
+ - 'app/serializers/user_entity.rb'
+ - 'app/serializers/user_preference_entity.rb'
+ - 'app/serializers/user_serializer.rb'
+ - 'app/serializers/web_ide_terminal_entity.rb'
+ - 'app/serializers/web_ide_terminal_serializer.rb'
+ - 'app/services/access_token_validation_service.rb'
+ - 'app/services/audit_event_service.rb'
+ - 'app/services/auto_merge_service.rb'
+ - 'app/services/base_container_service.rb'
+ - 'app/services/base_count_service.rb'
+ - 'app/services/base_project_service.rb'
+ - 'app/services/base_renderer.rb'
+ - 'app/services/base_service.rb'
+ - 'app/services/bulk_create_integration_service.rb'
+ - 'app/services/bulk_push_event_payload_service.rb'
+ - 'app/services/bulk_update_integration_service.rb'
+ - 'app/services/cohorts_service.rb'
+ - 'app/services/compare_service.rb'
+ - 'app/services/event_create_service.rb'
+ - 'app/services/gravatar_service.rb'
+ - 'app/services/import_export_clean_up_service.rb'
+ - 'app/services/issuable_base_service.rb'
+ - 'app/services/markdown_content_rewriter_service.rb'
+ - 'app/services/merge_request_metrics_service.rb'
+ - 'app/services/metrics_service.rb'
+ - 'app/services/note_summary.rb'
+ - 'app/services/notification_service.rb'
+ - 'app/services/onboarding_progress_service.rb'
+ - 'app/services/post_receive_service.rb'
+ - 'app/services/preview_markdown_service.rb'
+ - 'app/services/push_event_payload_service.rb'
+ - 'app/services/repository_archive_clean_up_service.rb'
+ - 'app/services/reset_project_cache_service.rb'
+ - 'app/services/search_service.rb'
+ - 'app/services/service_response.rb'
+ - 'app/services/system_hooks_service.rb'
+ - 'app/services/task_list_toggle_service.rb'
+ - 'app/services/todo_service.rb'
+ - 'app/services/update_container_registry_info_service.rb'
+ - 'app/services/upload_service.rb'
+ - 'app/services/user_agent_detail_service.rb'
+ - 'app/services/user_project_access_changed_service.rb'
+ - 'app/services/verify_pages_domain_service.rb'
+ - 'app/services/web_hook_service.rb'
+ - 'app/services/x509_certificate_revoke_service.rb'
+ - 'app/uploaders/attachment_uploader.rb'
+ - 'app/uploaders/avatar_uploader.rb'
+ - 'app/uploaders/deleted_object_uploader.rb'
+ - 'app/uploaders/external_diff_uploader.rb'
+ - 'app/uploaders/favicon_uploader.rb'
+ - 'app/uploaders/file_mover.rb'
+ - 'app/uploaders/file_uploader.rb'
+ - 'app/uploaders/gitlab_uploader.rb'
+ - 'app/uploaders/import_export_uploader.rb'
+ - 'app/uploaders/job_artifact_uploader.rb'
+ - 'app/uploaders/lfs_object_uploader.rb'
+ - 'app/uploaders/namespace_file_uploader.rb'
+ - 'app/uploaders/personal_file_uploader.rb'
+ - 'app/validators/abstract_path_validator.rb'
+ - 'app/validators/addressable_url_validator.rb'
+ - 'app/validators/any_field_validator.rb'
+ - 'app/validators/array_members_validator.rb'
+ - 'app/validators/branch_filter_validator.rb'
+ - 'app/validators/certificate_fingerprint_validator.rb'
+ - 'app/validators/certificate_key_validator.rb'
+ - 'app/validators/certificate_validator.rb'
+ - 'app/validators/cluster_name_validator.rb'
+ - 'app/validators/color_validator.rb'
+ - 'app/validators/cron_freeze_period_timezone_validator.rb'
+ - 'app/validators/cron_timezone_validator.rb'
+ - 'app/validators/cron_validator.rb'
+ - 'app/validators/devise_email_validator.rb'
+ - 'app/validators/duration_validator.rb'
+ - 'app/validators/feature_flag_strategies_validator.rb'
+ - 'app/validators/feature_flag_user_xids_validator.rb'
+ - 'app/validators/future_date_validator.rb'
+ - 'app/validators/gitlab/emoji_name_validator.rb'
+ - 'app/validators/gitlab/zoom_url_validator.rb'
+ - 'app/validators/html_safety_validator.rb'
+ - 'app/validators/ip_address_validator.rb'
+ - 'app/validators/js_regex_validator.rb'
+ - 'app/validators/json_schema_validator.rb'
+ - 'app/validators/key_restriction_validator.rb'
+ - 'app/validators/line_code_validator.rb'
+ - 'app/validators/named_ecdsa_key_validator.rb'
+ - 'app/validators/namespace_path_validator.rb'
+ - 'app/validators/nested_attributes_duplicates_validator.rb'
+ - 'app/validators/project_path_validator.rb'
+ - 'app/validators/public_url_validator.rb'
+ - 'app/validators/qualified_domain_array_validator.rb'
+ - 'app/validators/rsa_key_validator.rb'
+ - 'app/validators/same_project_association_validator.rb'
+ - 'app/validators/sha_validator.rb'
+ - 'app/validators/system_hook_url_validator.rb'
+ - 'app/validators/top_level_group_validator.rb'
+ - 'app/validators/untrusted_regexp_validator.rb'
+ - 'app/validators/x509_certificate_credentials_validator.rb'
+ - 'app/workers/admin_email_worker.rb'
+ - 'app/workers/approve_blocked_pending_approval_users_worker.rb'
+ - 'app/workers/archive_trace_worker.rb'
+ - 'app/workers/authorized_keys_worker.rb'
+ - 'app/workers/authorized_projects_worker.rb'
+ - 'app/workers/auto_merge_process_worker.rb'
+ - 'app/workers/background_migration_worker.rb'
+ - 'app/workers/build_finished_worker.rb'
+ - 'app/workers/build_hooks_worker.rb'
+ - 'app/workers/build_queue_worker.rb'
+ - 'app/workers/build_success_worker.rb'
+ - 'app/workers/bulk_import_worker.rb'
+ - 'app/workers/chat_notification_worker.rb'
+ - 'app/workers/ci_platform_metrics_update_cron_worker.rb'
+ - 'app/workers/cleanup_container_repository_worker.rb'
+ - 'app/workers/cluster_configure_istio_worker.rb'
+ - 'app/workers/cluster_install_app_worker.rb'
+ - 'app/workers/cluster_patch_app_worker.rb'
+ - 'app/workers/cluster_provision_worker.rb'
+ - 'app/workers/cluster_update_app_worker.rb'
+ - 'app/workers/cluster_upgrade_app_worker.rb'
+ - 'app/workers/cluster_wait_for_app_installation_worker.rb'
+ - 'app/workers/cluster_wait_for_app_update_worker.rb'
+ - 'app/workers/cluster_wait_for_ingress_ip_address_worker.rb'
+ - 'app/workers/container_expiration_policy_worker.rb'
+ - 'app/workers/create_commit_signature_worker.rb'
+ - 'app/workers/create_note_diff_file_worker.rb'
+ - 'app/workers/create_pipeline_worker.rb'
+ - 'app/workers/delete_container_repository_worker.rb'
+ - 'app/workers/delete_diff_files_worker.rb'
+ - 'app/workers/delete_merged_branches_worker.rb'
+ - 'app/workers/delete_stored_files_worker.rb'
+ - 'app/workers/delete_user_worker.rb'
+ - 'app/workers/destroy_pages_deployments_worker.rb'
+ - 'app/workers/detect_repository_languages_worker.rb'
+ - 'app/workers/disallow_two_factor_for_group_worker.rb'
+ - 'app/workers/disallow_two_factor_for_subgroups_worker.rb'
+ - 'app/workers/email_receiver_worker.rb'
+ - 'app/workers/emails_on_push_worker.rb'
+ - 'app/workers/error_tracking_issue_link_worker.rb'
+ - 'app/workers/expire_build_artifacts_worker.rb'
+ - 'app/workers/expire_build_instance_artifacts_worker.rb'
+ - 'app/workers/expire_job_cache_worker.rb'
+ - 'app/workers/expire_pipeline_cache_worker.rb'
+ - 'app/workers/export_csv_worker.rb'
+ - 'app/workers/external_service_reactive_caching_worker.rb'
+ - 'app/workers/file_hook_worker.rb'
+ - 'app/workers/flush_counter_increments_worker.rb'
+ - 'app/workers/gitlab_performance_bar_stats_worker.rb'
+ - 'app/workers/gitlab_service_ping_worker.rb'
+ - 'app/workers/gitlab_shell_worker.rb'
+ - 'app/workers/group_destroy_worker.rb'
+ - 'app/workers/group_export_worker.rb'
+ - 'app/workers/group_import_worker.rb'
+ - 'app/workers/import_export_project_cleanup_worker.rb'
+ - 'app/workers/import_issues_csv_worker.rb'
+ - 'app/workers/invalid_gpg_signature_update_worker.rb'
+ - 'app/workers/irker_worker.rb'
+ - 'app/workers/issuable_export_csv_worker.rb'
+ - 'app/workers/issue_due_scheduler_worker.rb'
+ - 'app/workers/issue_placement_worker.rb'
+ - 'app/workers/issue_rebalancing_worker.rb'
+ - 'app/workers/member_invitation_reminder_emails_worker.rb'
+ - 'app/workers/merge_request_cleanup_refs_worker.rb'
+ - 'app/workers/merge_request_mergeability_check_worker.rb'
+ - 'app/workers/merge_worker.rb'
+ - 'app/workers/migrate_external_diffs_worker.rb'
+ - 'app/workers/namespaceless_project_destroy_worker.rb'
+ - 'app/workers/new_issue_worker.rb'
+ - 'app/workers/new_merge_request_worker.rb'
+ - 'app/workers/new_note_worker.rb'
+ - 'app/workers/pages_domain_removal_cron_worker.rb'
+ - 'app/workers/pages_domain_ssl_renewal_cron_worker.rb'
+ - 'app/workers/pages_domain_ssl_renewal_worker.rb'
+ - 'app/workers/pages_domain_verification_cron_worker.rb'
+ - 'app/workers/pages_domain_verification_worker.rb'
+ - 'app/workers/pages_transfer_worker.rb'
+ - 'app/workers/pages_worker.rb'
+ - 'app/workers/partition_creation_worker.rb'
+ - 'app/workers/pipeline_hooks_worker.rb'
+ - 'app/workers/pipeline_metrics_worker.rb'
+ - 'app/workers/pipeline_notification_worker.rb'
+ - 'app/workers/pipeline_process_worker.rb'
+ - 'app/workers/pipeline_schedule_worker.rb'
+ - 'app/workers/post_receive.rb'
+ - 'app/workers/process_commit_worker.rb'
+ - 'app/workers/project_cache_worker.rb'
+ - 'app/workers/project_daily_statistics_worker.rb'
+ - 'app/workers/project_destroy_worker.rb'
+ - 'app/workers/project_export_worker.rb'
+ - 'app/workers/project_service_worker.rb'
+ - 'app/workers/propagate_integration_group_worker.rb'
+ - 'app/workers/propagate_integration_inherit_descendant_worker.rb'
+ - 'app/workers/propagate_integration_inherit_worker.rb'
+ - 'app/workers/propagate_integration_project_worker.rb'
+ - 'app/workers/propagate_integration_worker.rb'
+ - 'app/workers/prune_old_events_worker.rb'
+ - 'app/workers/purge_dependency_proxy_cache_worker.rb'
+ - 'app/workers/reactive_caching_worker.rb'
+ - 'app/workers/rebase_worker.rb'
+ - 'app/workers/remote_mirror_notification_worker.rb'
+ - 'app/workers/remove_expired_group_links_worker.rb'
+ - 'app/workers/remove_expired_members_worker.rb'
+ - 'app/workers/remove_unaccepted_member_invites_worker.rb'
+ - 'app/workers/remove_unreferenced_lfs_objects_worker.rb'
+ - 'app/workers/repository_archive_cache_worker.rb'
+ - 'app/workers/repository_cleanup_worker.rb'
+ - 'app/workers/repository_fork_worker.rb'
+ - 'app/workers/repository_import_worker.rb'
+ - 'app/workers/repository_remove_remote_worker.rb'
+ - 'app/workers/repository_update_remote_mirror_worker.rb'
+ - 'app/workers/run_pipeline_schedule_worker.rb'
+ - 'app/workers/schedule_merge_request_cleanup_refs_worker.rb'
+ - 'app/workers/schedule_migrate_external_diffs_worker.rb'
+ - 'app/workers/self_monitoring_project_create_worker.rb'
+ - 'app/workers/self_monitoring_project_delete_worker.rb'
+ - 'app/workers/service_desk_email_receiver_worker.rb'
+ - 'app/workers/stage_update_worker.rb'
+ - 'app/workers/stuck_ci_jobs_worker.rb'
+ - 'app/workers/stuck_export_jobs_worker.rb'
+ - 'app/workers/stuck_merge_jobs_worker.rb'
+ - 'app/workers/system_hook_push_worker.rb'
+ - 'app/workers/trending_projects_worker.rb'
+ - 'app/workers/update_container_registry_info_worker.rb'
+ - 'app/workers/update_external_pull_requests_worker.rb'
+ - 'app/workers/update_head_pipeline_for_merge_request_worker.rb'
+ - 'app/workers/update_highest_role_worker.rb'
+ - 'app/workers/update_merge_requests_worker.rb'
+ - 'app/workers/update_project_statistics_worker.rb'
+ - 'app/workers/upload_checksum_worker.rb'
+ - 'app/workers/wait_for_cluster_creation_worker.rb'
+ - 'app/workers/web_hook_worker.rb'
+ - 'app/workers/x509_certificate_revoke_worker.rb'
+ - 'app/workers/x509_issuer_crl_check_worker.rb'
+ - 'ee/app/controllers/countries_controller.rb'
+ - 'ee/app/controllers/country_states_controller.rb'
+ - 'ee/app/controllers/omniauth_kerberos_spnego_controller.rb'
+ - 'ee/app/controllers/operations_controller.rb'
+ - 'ee/app/controllers/sitemap_controller.rb'
+ - 'ee/app/controllers/smartcard_controller.rb'
+ - 'ee/app/controllers/subscriptions_controller.rb'
+ - 'ee/app/controllers/survey_responses_controller.rb'
+ - 'ee/app/controllers/trial_registrations_controller.rb'
+ - 'ee/app/controllers/trials_controller.rb'
+ - 'ee/app/finders/audit_log_finder.rb'
+ - 'ee/app/finders/billed_users_finder.rb'
+ - 'ee/app/finders/custom_project_templates_finder.rb'
+ - 'ee/app/finders/dast_scanner_profiles_finder.rb'
+ - 'ee/app/finders/dast_site_profiles_finder.rb'
+ - 'ee/app/finders/dast_site_validations_finder.rb'
+ - 'ee/app/finders/epics_finder.rb'
+ - 'ee/app/finders/geo_node_finder.rb'
+ - 'ee/app/finders/gpg_keys_finder.rb'
+ - 'ee/app/finders/group_saml_identity_finder.rb'
+ - 'ee/app/finders/groups_with_templates_finder.rb'
+ - 'ee/app/finders/iterations_finder.rb'
+ - 'ee/app/finders/licenses_finder.rb'
+ - 'ee/app/finders/merge_trains_finder.rb'
+ - 'ee/app/finders/productivity_analytics_finder.rb'
+ - 'ee/app/finders/scim_finder.rb'
+ - 'ee/app/finders/software_license_policies_finder.rb'
+ - 'ee/app/mailers/ci_minutes_usage_mailer.rb'
+ - 'ee/app/mailers/credentials_inventory_mailer.rb'
+ - 'ee/app/mailers/license_mailer.rb'
+ - 'ee/app/mailers/previews/ci_minutes_usage_mailer_preview.rb'
+ - 'ee/app/mailers/previews/license_mailer_preview.rb'
+ - 'ee/app/models/allowed_email_domain.rb'
+ - 'ee/app/models/approval_merge_request_rule.rb'
+ - 'ee/app/models/approval_merge_request_rule_source.rb'
+ - 'ee/app/models/approval_project_rule.rb'
+ - 'ee/app/models/approval_project_rules_protected_branch.rb'
+ - 'ee/app/models/approval_state.rb'
+ - 'ee/app/models/approval_wrapped_any_approver_rule.rb'
+ - 'ee/app/models/approval_wrapped_code_owner_rule.rb'
+ - 'ee/app/models/approval_wrapped_rule.rb'
+ - 'ee/app/models/approver.rb'
+ - 'ee/app/models/approver_group.rb'
+ - 'ee/app/models/board_assignee.rb'
+ - 'ee/app/models/board_label.rb'
+ - 'ee/app/models/board_user_preference.rb'
+ - 'ee/app/models/burndown.rb'
+ - 'ee/app/models/dast_scanner_profile.rb'
+ - 'ee/app/models/dast_site.rb'
+ - 'ee/app/models/dast_site_profile.rb'
+ - 'ee/app/models/dast_site_token.rb'
+ - 'ee/app/models/dast_site_validation.rb'
+ - 'ee/app/models/elasticsearch_indexed_namespace.rb'
+ - 'ee/app/models/elasticsearch_indexed_project.rb'
+ - 'ee/app/models/epic_issue.rb'
+ - 'ee/app/models/epic_user_mention.rb'
+ - 'ee/app/models/feature_flag_issue.rb'
+ - 'ee/app/models/geo_node.rb'
+ - 'ee/app/models/geo_node_namespace_link.rb'
+ - 'ee/app/models/geo_node_status.rb'
+ - 'ee/app/models/gitlab/seat_link_data.rb'
+ - 'ee/app/models/gitlab_subscription.rb'
+ - 'ee/app/models/gitlab_subscription_history.rb'
+ - 'ee/app/models/group_deletion_schedule.rb'
+ - 'ee/app/models/group_merge_request_approval_setting.rb'
+ - 'ee/app/models/group_wiki.rb'
+ - 'ee/app/models/group_wiki_repository.rb'
+ - 'ee/app/models/historical_data.rb'
+ - 'ee/app/models/hooks/group_hook.rb'
+ - 'ee/app/models/index_status.rb'
+ - 'ee/app/models/insight.rb'
+ - 'ee/app/models/instance_security_dashboard.rb'
+ - 'ee/app/models/ip_restriction.rb'
+ - 'ee/app/models/issuable_metric_image.rb'
+ - 'ee/app/models/issuable_sla.rb'
+ - 'ee/app/models/issuables_analytics.rb'
+ - 'ee/app/models/iteration_note.rb'
+ - 'ee/app/models/ldap_group_link.rb'
+ - 'ee/app/models/ldap_key.rb'
+ - 'ee/app/models/license.rb'
+ - 'ee/app/models/merge_request_block.rb'
+ - 'ee/app/models/merge_request_diff_detail.rb'
+ - 'ee/app/models/merge_train.rb'
+ - 'ee/app/models/namespace_limit.rb'
+ - 'ee/app/models/path_lock.rb'
+ - 'ee/app/models/productivity_analytics.rb'
+ - 'ee/app/models/project_alias.rb'
+ - 'ee/app/models/project_repository_state.rb'
+ - 'ee/app/models/project_security_setting.rb'
+ - 'ee/app/models/protected_environment.rb'
+ - 'ee/app/models/push_rule.rb'
+ - 'ee/app/models/resource_iteration_event.rb'
+ - 'ee/app/models/resource_weight_event.rb'
+ - 'ee/app/models/saml_group_link.rb'
+ - 'ee/app/models/saml_provider.rb'
+ - 'ee/app/models/scim_identity.rb'
+ - 'ee/app/models/scim_oauth_access_token.rb'
+ - 'ee/app/models/scoped_label_set.rb'
+ - 'ee/app/models/slack_integration.rb'
+ - 'ee/app/models/smartcard_identity.rb'
+ - 'ee/app/models/software_license.rb'
+ - 'ee/app/models/software_license_policy.rb'
+ - 'ee/app/models/storage_shard.rb'
+ - 'ee/app/models/user_permission_export_upload.rb'
+ - 'ee/app/models/users_ops_dashboard_project.rb'
+ - 'ee/app/models/users_security_dashboard_project.rb'
+ - 'ee/app/models/vulnerability_user_mention.rb'
+ - 'ee/app/models/weight_note.rb'
+ - 'ee/app/policies/approval_merge_request_rule_policy.rb'
+ - 'ee/app/policies/approval_project_rule_policy.rb'
+ - 'ee/app/policies/approval_state_policy.rb'
+ - 'ee/app/policies/dast_scanner_profile_policy.rb'
+ - 'ee/app/policies/dast_site_profile_policy.rb'
+ - 'ee/app/policies/dast_site_validation_policy.rb'
+ - 'ee/app/policies/epic_policy.rb'
+ - 'ee/app/policies/geo_node_policy.rb'
+ - 'ee/app/policies/instance_security_dashboard_policy.rb'
+ - 'ee/app/policies/issuable_metric_image_policy.rb'
+ - 'ee/app/policies/iteration_policy.rb'
+ - 'ee/app/policies/push_rule_policy.rb'
+ - 'ee/app/policies/saml_provider_policy.rb'
+ - 'ee/app/policies/vulnerability_policy.rb'
+ - 'ee/app/presenters/approval_rule_presenter.rb'
+ - 'ee/app/presenters/audit_event_presenter.rb'
+ - 'ee/app/presenters/epic_issue_presenter.rb'
+ - 'ee/app/presenters/epic_presenter.rb'
+ - 'ee/app/presenters/iteration_presenter.rb'
+ - 'ee/app/presenters/merge_request_approver_presenter.rb'
+ - 'ee/app/presenters/subscription_presenter.rb'
+ - 'ee/app/presenters/vulnerability_presenter.rb'
+ - 'ee/app/serializers/audit_event_entity.rb'
+ - 'ee/app/serializers/audit_event_serializer.rb'
+ - 'ee/app/serializers/blocking_merge_request_entity.rb'
+ - 'ee/app/serializers/board_assignee_entity.rb'
+ - 'ee/app/serializers/board_label_entity.rb'
+ - 'ee/app/serializers/board_milestone_entity.rb'
+ - 'ee/app/serializers/dashboard_environment_entity.rb'
+ - 'ee/app/serializers/dashboard_environments_project_entity.rb'
+ - 'ee/app/serializers/dashboard_environments_serializer.rb'
+ - 'ee/app/serializers/dashboard_operations_project_entity.rb'
+ - 'ee/app/serializers/dashboard_operations_serializer.rb'
+ - 'ee/app/serializers/dependency_entity.rb'
+ - 'ee/app/serializers/dependency_list_entity.rb'
+ - 'ee/app/serializers/dependency_list_serializer.rb'
+ - 'ee/app/serializers/epic_base_entity.rb'
+ - 'ee/app/serializers/epic_entity.rb'
+ - 'ee/app/serializers/epic_note_entity.rb'
+ - 'ee/app/serializers/epic_note_serializer.rb'
+ - 'ee/app/serializers/epic_serializer.rb'
+ - 'ee/app/serializers/file_lock_entity.rb'
+ - 'ee/app/serializers/geo_design_registry_entity.rb'
+ - 'ee/app/serializers/geo_design_registry_serializer.rb'
+ - 'ee/app/serializers/geo_node_serializer.rb'
+ - 'ee/app/serializers/geo_node_status_serializer.rb'
+ - 'ee/app/serializers/geo_project_registry_entity.rb'
+ - 'ee/app/serializers/geo_project_registry_serializer.rb'
+ - 'ee/app/serializers/group_analytics_serializer.rb'
+ - 'ee/app/serializers/group_vulnerability_autocomplete_entity.rb'
+ - 'ee/app/serializers/group_vulnerability_autocomplete_serializer.rb'
+ - 'ee/app/serializers/invited_group_entity.rb'
+ - 'ee/app/serializers/invited_group_serializer.rb'
+ - 'ee/app/serializers/iteration_serializer.rb'
+ - 'ee/app/serializers/license_entity.rb'
+ - 'ee/app/serializers/license_scanning_reports_serializer.rb'
+ - 'ee/app/serializers/licenses_list_entity.rb'
+ - 'ee/app/serializers/licenses_list_serializer.rb'
+ - 'ee/app/serializers/linked_epic_entity.rb'
+ - 'ee/app/serializers/linked_epic_issue_entity.rb'
+ - 'ee/app/serializers/linked_epic_issue_serializer.rb'
+ - 'ee/app/serializers/linked_epic_serializer.rb'
+ - 'ee/app/serializers/linked_feature_flag_issue_entity.rb'
+ - 'ee/app/serializers/linked_feature_flag_issue_serializer.rb'
+ - 'ee/app/serializers/metrics_report_metric_entity.rb'
+ - 'ee/app/serializers/metrics_reports_comparer_entity.rb'
+ - 'ee/app/serializers/metrics_reports_comparer_serializer.rb'
+ - 'ee/app/serializers/milestone_serializer.rb'
+ - 'ee/app/serializers/namespace_entity.rb'
+ - 'ee/app/serializers/productivity_analytics_merge_request_entity.rb'
+ - 'ee/app/serializers/report_list_entity.rb'
+ - 'ee/app/serializers/scim_oauth_access_token_entity.rb'
+ - 'ee/app/serializers/storage_shard_entity.rb'
+ - 'ee/app/serializers/storage_shard_serializer.rb'
+ - 'ee/app/serializers/user_analytics_entity.rb'
+ - 'ee/app/serializers/vulnerability_entity.rb'
+ - 'ee/app/serializers/vulnerability_note_entity.rb'
+ - 'ee/app/serializers/vulnerability_note_serializer.rb'
+ - 'ee/app/serializers/vulnerability_serializer.rb'
+ - 'ee/app/services/ldap_group_reset_service.rb'
+ - 'ee/app/services/start_pull_mirroring_service.rb'
+ - 'ee/app/services/timebox_report_service.rb'
+ - 'ee/app/validators/host_validator.rb'
+ - 'ee/app/validators/ldap_filter_validator.rb'
+ - 'ee/app/workers/active_user_count_threshold_worker.rb'
+ - 'ee/app/workers/adjourned_group_deletion_worker.rb'
+ - 'ee/app/workers/adjourned_project_deletion_worker.rb'
+ - 'ee/app/workers/adjourned_projects_deletion_cron_worker.rb'
+ - 'ee/app/workers/admin_emails_worker.rb'
+ - 'ee/app/workers/clear_shared_runners_minutes_worker.rb'
+ - 'ee/app/workers/create_github_webhook_worker.rb'
+ - 'ee/app/workers/dast_site_validation_worker.rb'
+ - 'ee/app/workers/elastic_association_indexer_worker.rb'
+ - 'ee/app/workers/elastic_cluster_reindexing_cron_worker.rb'
+ - 'ee/app/workers/elastic_commit_indexer_worker.rb'
+ - 'ee/app/workers/elastic_delete_project_worker.rb'
+ - 'ee/app/workers/elastic_full_index_worker.rb'
+ - 'ee/app/workers/elastic_index_bulk_cron_worker.rb'
+ - 'ee/app/workers/elastic_index_initial_bulk_cron_worker.rb'
+ - 'ee/app/workers/elastic_indexing_control_worker.rb'
+ - 'ee/app/workers/elastic_namespace_indexer_worker.rb'
+ - 'ee/app/workers/elastic_namespace_rollout_worker.rb'
+ - 'ee/app/workers/elastic_remove_expired_namespace_subscriptions_from_index_cron_worker.rb'
+ - 'ee/app/workers/geo_repository_destroy_worker.rb'
+ - 'ee/app/workers/group_saml_group_sync_worker.rb'
+ - 'ee/app/workers/historical_data_worker.rb'
+ - 'ee/app/workers/import_software_licenses_worker.rb'
+ - 'ee/app/workers/iterations_update_status_worker.rb'
+ - 'ee/app/workers/ldap_all_groups_sync_worker.rb'
+ - 'ee/app/workers/ldap_group_sync_worker.rb'
+ - 'ee/app/workers/ldap_sync_worker.rb'
+ - 'ee/app/workers/merge_request_reset_approvals_worker.rb'
+ - 'ee/app/workers/new_epic_worker.rb'
+ - 'ee/app/workers/project_import_schedule_worker.rb'
+ - 'ee/app/workers/project_template_export_worker.rb'
+ - 'ee/app/workers/refresh_license_compliance_checks_worker.rb'
+ - 'ee/app/workers/repository_push_audit_event_worker.rb'
+ - 'ee/app/workers/repository_update_mirror_worker.rb'
+ - 'ee/app/workers/scan_security_report_secrets_worker.rb'
+ - 'ee/app/workers/set_user_status_based_on_user_cap_setting_worker.rb'
+ - 'ee/app/workers/store_security_reports_worker.rb'
+ - 'ee/app/workers/sync_seat_link_request_worker.rb'
+ - 'ee/app/workers/sync_seat_link_worker.rb'
+ - 'ee/app/workers/update_all_mirrors_worker.rb'
+ - 'ee/app/workers/update_max_seats_used_for_gitlab_com_subscriptions_worker.rb'
+ - 'ee/lib/gitlab/auth_logger.rb'
+ - 'ee/lib/gitlab/authority_analyzer.rb'
+ - 'ee/lib/gitlab/cidr.rb'
+ - 'ee/lib/gitlab/custom_file_templates.rb'
+ - 'ee/lib/gitlab/expiring_subscription_message.rb'
+ - 'ee/lib/gitlab/geo_logger.rb'
+ - 'ee/lib/gitlab/group_plans_preloader.rb'
+ - 'ee/lib/gitlab/ip_address_state.rb'
+ - 'ee/lib/gitlab/items_collection.rb'
+ - 'ee/lib/gitlab/manual_banner.rb'
+ - 'ee/lib/gitlab/manual_quarterly_co_term_banner.rb'
+ - 'ee/lib/gitlab/manual_renewal_banner.rb'
+ - 'ee/lib/gitlab/pagination_delegate.rb'
+ - 'ee/lib/gitlab/path_locks_finder.rb'
+ - 'ee/lib/gitlab/proxy.rb'
+ - 'ee/lib/gitlab/return_to_location.rb'
+ - 'ee/lib/gitlab/update_mirror_service_json_logger.rb'
+ - 'ee/spec/support/elastic_query_name_inspector.rb'
+ - 'ee/spec/support/test_license.rb'
+ - 'lib/carrier_wave_string_file.rb'
+ - 'lib/csv_builder.rb'
+ - 'lib/event_filter.rb'
+ - 'lib/feature.rb'
+ - 'lib/feature/definition.rb'
+ - 'lib/feature/gitaly.rb'
+ - 'lib/feature/logger.rb'
+ - 'lib/feature/shared.rb'
+ - 'lib/file_size_validator.rb'
+ - 'lib/forever.rb'
+ - 'lib/generators/gitlab/snowplow_event_definition_generator.rb'
+ - 'lib/generators/gitlab/usage_metric_definition_generator.rb'
+ - 'lib/generators/gitlab/usage_metric_generator.rb'
+ - 'lib/gitlab/anonymous_session.rb'
+ - 'lib/gitlab/app_json_logger.rb'
+ - 'lib/gitlab/app_logger.rb'
+ - 'lib/gitlab/app_text_logger.rb'
+ - 'lib/gitlab/application_context.rb'
+ - 'lib/gitlab/audit_json_logger.rb'
+ - 'lib/gitlab/auth_logger.rb'
+ - 'lib/gitlab/authorized_keys.rb'
+ - 'lib/gitlab/avatar_cache.rb'
+ - 'lib/gitlab/backup_logger.rb'
+ - 'lib/gitlab/base_doorkeeper_controller.rb'
+ - 'lib/gitlab/batch_pop_queueing.rb'
+ - 'lib/gitlab/batch_worker_context.rb'
+ - 'lib/gitlab/blame.rb'
+ - 'lib/gitlab/branch_push_merge_commit_analyzer.rb'
+ - 'lib/gitlab/buffered_io.rb'
+ - 'lib/gitlab/build_access.rb'
+ - 'lib/gitlab/changes_list.rb'
+ - 'lib/gitlab/chaos.rb'
+ - 'lib/gitlab/chat_name_token.rb'
+ - 'lib/gitlab/ci_access.rb'
+ - 'lib/gitlab/closing_issue_extractor.rb'
+ - 'lib/gitlab/code_navigation_path.rb'
+ - 'lib/gitlab/color.rb'
+ - 'lib/gitlab/conan_token.rb'
+ - 'lib/gitlab/contributions_calendar.rb'
+ - 'lib/gitlab/contributor.rb'
+ - 'lib/gitlab/cross_project_access.rb'
+ - 'lib/gitlab/cross_project_access/check_collection.rb'
+ - 'lib/gitlab/cross_project_access/check_info.rb'
+ - 'lib/gitlab/cross_project_access/class_methods.rb'
+ - 'lib/gitlab/daemon.rb'
+ - 'lib/gitlab/deploy_key_access.rb'
+ - 'lib/gitlab/deprecation_json_logger.rb'
+ - 'lib/gitlab/devise_failure.rb'
+ - 'lib/gitlab/empty_search_results.rb'
+ - 'lib/gitlab/encrypted_command_base.rb'
+ - 'lib/gitlab/encrypted_configuration.rb'
+ - 'lib/gitlab/encrypted_ldap_command.rb'
+ - 'lib/gitlab/encrypted_smtp_command.rb'
+ - 'lib/gitlab/environment_logger.rb'
+ - 'lib/gitlab/exceptions_app.rb'
+ - 'lib/gitlab/exclusive_lease.rb'
+ - 'lib/gitlab/experiment/rollout/feature.rb'
+ - 'lib/gitlab/experimentation_logger.rb'
+ - 'lib/gitlab/fake_application_settings.rb'
+ - 'lib/gitlab/favicon.rb'
+ - 'lib/gitlab/feature_categories.rb'
+ - 'lib/gitlab/file_finder.rb'
+ - 'lib/gitlab/file_hook_logger.rb'
+ - 'lib/gitlab/fips.rb'
+ - 'lib/gitlab/git_access.rb'
+ - 'lib/gitlab/git_access_design.rb'
+ - 'lib/gitlab/git_access_project.rb'
+ - 'lib/gitlab/git_access_snippet.rb'
+ - 'lib/gitlab/git_access_wiki.rb'
+ - 'lib/gitlab/git_logger.rb'
+ - 'lib/gitlab/git_post_receive.rb'
+ - 'lib/gitlab/gl_repository.rb'
+ - 'lib/gitlab/gl_repository/identifier.rb'
+ - 'lib/gitlab/gl_repository/repo_type.rb'
+ - 'lib/gitlab/graphql_logger.rb'
+ - 'lib/gitlab/group_search_results.rb'
+ - 'lib/gitlab/hashed_path.rb'
+ - 'lib/gitlab/highlight.rb'
+ - 'lib/gitlab/hotlinking_detector.rb'
+ - 'lib/gitlab/http.rb'
+ - 'lib/gitlab/http_connection_adapter.rb'
+ - 'lib/gitlab/http_io.rb'
+ - 'lib/gitlab/import_formatter.rb'
+ - 'lib/gitlab/inactive_projects_deletion_warning_tracker.rb'
+ - 'lib/gitlab/insecure_key_fingerprint.rb'
+ - 'lib/gitlab/integrations_logger.rb'
+ - 'lib/gitlab/issuable_metadata.rb'
+ - 'lib/gitlab/issuables_count_for_state.rb'
+ - 'lib/gitlab/issues_labels.rb'
+ - 'lib/gitlab/job_waiter.rb'
+ - 'lib/gitlab/json_cache.rb'
+ - 'lib/gitlab/json_logger.rb'
+ - 'lib/gitlab/jwt_token.rb'
+ - 'lib/gitlab/language_detection.rb'
+ - 'lib/gitlab/lazy.rb'
+ - 'lib/gitlab/lfs_token.rb'
+ - 'lib/gitlab/log_timestamp_formatter.rb'
+ - 'lib/gitlab/logger.rb'
+ - 'lib/gitlab/marker_range.rb'
+ - 'lib/gitlab/multi_collection_paginator.rb'
+ - 'lib/gitlab/multi_destination_logger.rb'
+ - 'lib/gitlab/namespace_sanitizer.rb'
+ - 'lib/gitlab/namespaced_session_store.rb'
+ - 'lib/gitlab/net_http_adapter.rb'
+ - 'lib/gitlab/null_request_store.rb'
+ - 'lib/gitlab/object_hierarchy.rb'
+ - 'lib/gitlab/omniauth_initializer.rb'
+ - 'lib/gitlab/otp_key_rotator.rb'
+ - 'lib/gitlab/pages_transfer.rb'
+ - 'lib/gitlab/pipeline_scope_counts.rb'
+ - 'lib/gitlab/polling_interval.rb'
+ - 'lib/gitlab/process_memory_cache.rb'
+ - 'lib/gitlab/process_memory_cache/helper.rb'
+ - 'lib/gitlab/process_supervisor.rb'
+ - 'lib/gitlab/project_authorizations.rb'
+ - 'lib/gitlab/project_search_results.rb'
+ - 'lib/gitlab/project_template.rb'
+ - 'lib/gitlab/project_transfer.rb'
+ - 'lib/gitlab/prometheus_client.rb'
+ - 'lib/gitlab/push_options.rb'
+ - 'lib/gitlab/reactive_cache_set_cache.rb'
+ - 'lib/gitlab/redacted_search_results_logger.rb'
+ - 'lib/gitlab/reference_counter.rb'
+ - 'lib/gitlab/reference_extractor.rb'
+ - 'lib/gitlab/repository_cache.rb'
+ - 'lib/gitlab/repository_cache/preloader.rb'
+ - 'lib/gitlab/repository_check_logger.rb'
+ - 'lib/gitlab/repository_hash_cache.rb'
+ - 'lib/gitlab/repository_set_cache.rb'
+ - 'lib/gitlab/repository_size_checker.rb'
+ - 'lib/gitlab/repository_size_error_message.rb'
+ - 'lib/gitlab/request_context.rb'
+ - 'lib/gitlab/route_map.rb'
+ - 'lib/gitlab/safe_request_loader.rb'
+ - 'lib/gitlab/safe_request_purger.rb'
+ - 'lib/gitlab/sample_data_template.rb'
+ - 'lib/gitlab/search_context.rb'
+ - 'lib/gitlab/search_results.rb'
+ - 'lib/gitlab/seeder.rb'
+ - 'lib/gitlab/session.rb'
+ - 'lib/gitlab/set_cache.rb'
+ - 'lib/gitlab/shard_health_cache.rb'
+ - 'lib/gitlab/shell.rb'
+ - 'lib/gitlab/sidekiq_migrate_jobs.rb'
+ - 'lib/gitlab/sidekiq_queue.rb'
+ - 'lib/gitlab/signed_commit.rb'
+ - 'lib/gitlab/signed_tag.rb'
+ - 'lib/gitlab/snippet_search_results.rb'
+ - 'lib/gitlab/sourcegraph.rb'
+ - 'lib/gitlab/ssh_public_key.rb'
+ - 'lib/gitlab/stack_prof.rb'
+ - 'lib/gitlab/string_placeholder_replacer.rb'
+ - 'lib/gitlab/string_range_marker.rb'
+ - 'lib/gitlab/string_regex_marker.rb'
+ - 'lib/gitlab/submodule_links.rb'
+ - 'lib/gitlab/tcp_checker.rb'
+ - 'lib/gitlab/terraform_registry_token.rb'
+ - 'lib/gitlab/throttle.rb'
+ - 'lib/gitlab/tree_summary.rb'
+ - 'lib/gitlab/unicode.rb'
+ - 'lib/gitlab/untrusted_regexp.rb'
+ - 'lib/gitlab/untrusted_regexp/ruby_syntax.rb'
+ - 'lib/gitlab/updated_notes_paginator.rb'
+ - 'lib/gitlab/uploads_transfer.rb'
+ - 'lib/gitlab/url_blocker.rb'
+ - 'lib/gitlab/url_builder.rb'
+ - 'lib/gitlab/url_helpers.rb'
+ - 'lib/gitlab/url_sanitizer.rb'
+ - 'lib/gitlab/usage_data.rb'
+ - 'lib/gitlab/usage_data/topology.rb'
+ - 'lib/gitlab/usage_data_metrics.rb'
+ - 'lib/gitlab/usage_data_non_sql_metrics.rb'
+ - 'lib/gitlab/usage_data_queries.rb'
+ - 'lib/gitlab/user_access.rb'
+ - 'lib/gitlab/user_access_snippet.rb'
+ - 'lib/gitlab/uuid.rb'
+ - 'lib/gitlab/version_info.rb'
+ - 'lib/gitlab/visibility_level_checker.rb'
+ - 'lib/gitlab/wiki_file_finder.rb'
+ - 'lib/gitlab/workhorse.rb'
+ - 'lib/gitlab/zoom_link_extractor.rb'
+ - 'lib/tasks/gitlab/graphql.rake'
+ - 'lib/tasks/gitlab/seed/group_seed.rake'
+ - 'lib/tasks/import.rake'
+ - 'lib/tasks/tokens.rake'
+ - 'lib/uploaded_file.rb'
+ - 'lib/version_check.rb'
+ - 'spec/controllers/concerns/page_limiter_spec.rb'
+ - 'spec/lib/bitbucket/collection_spec.rb'
+ - 'spec/lib/gitlab/multi_destination_logger_spec.rb'
+ - 'spec/lib/marginalia_spec.rb'
+ - 'spec/mailers/notify_spec.rb'
+ - 'spec/models/concerns/batch_destroy_dependent_associations_spec.rb'
+ - 'spec/models/concerns/bulk_insertable_associations_spec.rb'
+ - 'spec/models/concerns/triggerable_hooks_spec.rb'
+ - 'spec/support/helpers/bare_repo_operations.rb'
+ - 'spec/support/helpers/ci_artifact_metadata_generator.rb'
+ - 'spec/support/helpers/fake_migration_classes.rb'
+ - 'spec/support/helpers/fake_u2f_device.rb'
+ - 'spec/support/helpers/fake_webauthn_device.rb'
+ - 'spec/support/helpers/markdown_feature.rb'
+ - 'spec/support/helpers/redis_without_keys.rb'
+ - 'spec/support/helpers/require_migration.rb'
+ - 'spec/support/models/merge_request_without_merge_request_diff.rb'
+ - 'spec/support/renameable_upload.rb'
+ - 'spec/tasks/gitlab/task_helpers_spec.rb'
+ - 'spec/uploaders/object_storage_spec.rb'
diff --git a/.rubocop_todo/gitlab/policy_rule_boolean.yml b/.rubocop_todo/gitlab/policy_rule_boolean.yml
new file mode 100644
index 00000000000..64689eb8fa0
--- /dev/null
+++ b/.rubocop_todo/gitlab/policy_rule_boolean.yml
@@ -0,0 +1,4 @@
+---
+Gitlab/PolicyRuleBoolean:
+ Exclude:
+ - 'ee/app/policies/ee/identity_provider_policy.rb'
diff --git a/.rubocop_todo/layout/hash_alignment.yml b/.rubocop_todo/layout/hash_alignment.yml
index d7228ff381e..32c4ddbced4 100644
--- a/.rubocop_todo/layout/hash_alignment.yml
+++ b/.rubocop_todo/layout/hash_alignment.yml
@@ -337,7 +337,7 @@ Layout/HashAlignment:
- 'ee/app/helpers/ee/feature_flags_helper.rb'
- 'ee/app/helpers/ee/sorting_helper.rb'
- 'ee/app/models/allowed_email_domain.rb'
- - 'ee/app/models/ci/minutes/quota.rb'
+ - 'ee/app/models/ci/minutes/usage.rb'
- 'ee/app/models/ee/application_setting.rb'
- 'ee/app/models/elastic/reindexing_task.rb'
- 'ee/app/models/gitlab_subscriptions/features.rb'
diff --git a/.rubocop_todo/rails/create_table_with_timestamps.yml b/.rubocop_todo/rails/create_table_with_timestamps.yml
new file mode 100644
index 00000000000..6e60fa3e1d5
--- /dev/null
+++ b/.rubocop_todo/rails/create_table_with_timestamps.yml
@@ -0,0 +1,69 @@
+---
+Rails/CreateTableWithTimestamps:
+ # Offense count: 63
+ # Temporarily disabled due to too many offenses
+ Enabled: false
+ Exclude:
+ - 'db/migrate/20210305180331_create_ci_unit_tests.rb'
+ - 'db/migrate/20210305182855_create_ci_unit_test_failures.rb'
+ - 'db/migrate/20210317035357_create_dast_profiles_pipelines.rb'
+ - 'db/migrate/20210317104301_create_in_product_marketing_emails.rb'
+ - 'db/migrate/20210323125809_create_status_check_responses_table.rb'
+ - 'db/migrate/20210329191850_add_finding_signature_table.rb'
+ - 'db/migrate/20210411212813_add_clusters_integrations_prometheus.rb'
+ - 'db/migrate/20210423054022_create_dast_site_profiles_pipelines.rb'
+ - 'db/migrate/20210429032320_add_escalation_rules.rb'
+ - 'db/migrate/20210429131525_create_user_credit_card_validations.rb'
+ - 'db/migrate/20210511104929_add_epic_board_recent_visits_table.rb'
+ - 'db/migrate/20210512120122_add_pending_builds_table.rb'
+ - 'db/migrate/20210527194558_create_ci_job_token_project_scope_links.rb'
+ - 'db/migrate/20210601123341_add_running_builds_table.rb'
+ - 'db/migrate/20210602122213_add_upcoming_reconciliations.rb'
+ - 'db/migrate/20210604032738_create_dast_site_profiles_builds.rb'
+ - 'db/migrate/20210604051330_create_dast_scanner_profiles_builds.rb'
+ - 'db/migrate/20210604082145_create_external_status_checks_table.rb'
+ - 'db/migrate/20210713211008_create_banned_users.rb'
+ - 'db/migrate/20210729081739_create_project_topics.rb'
+ - 'db/migrate/20210729202143_create_incident_management_issuable_escalation_statuses.rb'
+ - 'db/migrate/20210730101609_create_analytics_cycle_analytics_stage_event_hashes.rb'
+ - 'db/migrate/20210809014850_create_agent_group_authorizations.rb'
+ - 'db/migrate/20210812171704_create_project_ci_feature_usages.rb'
+ - 'db/migrate/20210813101742_create_zentao_tracker_data.rb'
+ - 'db/migrate/20210813111909_create_ci_build_trace_metadata.rb'
+ - 'db/migrate/20210819185500_create_external_audit_event_destinations_table.rb'
+ - 'db/migrate/20210823172643_create_user_group_callout.rb'
+ - 'db/migrate/20210823213417_create_dependency_proxy_image_ttl_group_policies.rb'
+ - 'db/migrate/20210913010411_create_agent_project_authorizations.rb'
+ - 'db/migrate/20210922215740_create_issue_customer_relations_contacts.rb'
+ - 'db/migrate/20211004062942_create_coverage_fuzzing_corpuses.rb'
+ - 'db/migrate/20211004122540_create_member_tasks.rb'
+ - 'db/migrate/20211011004242_create_content_blocked_states.rb'
+ - 'db/migrate/20211011140930_create_ci_namespace_mirrors.rb'
+ - 'db/migrate/20211011140931_create_ci_project_mirrors.rb'
+ - 'db/migrate/20211011140932_create_namespaces_sync_events.rb'
+ - 'db/migrate/20211011141239_create_projects_sync_events.rb'
+ - 'db/migrate/20211028132247_create_packages_npm_metadata.rb'
+ - 'db/migrate/20211101132310_add_reindexing_queue.rb'
+ - 'db/migrate/20211101165656_create_upload_states.rb'
+ - 'db/migrate/20211110014701_create_agent_activity_events.rb'
+ - 'db/migrate/20211110092710_create_issue_emails.rb'
+ - 'db/migrate/20211111112425_create_merge_requests_compliance_violations.rb'
+ - 'db/migrate/20211115132613_create_incident_management_timeline_events.rb'
+ - 'db/migrate/20211117174209_create_vulnerability_reads.rb'
+ - 'db/migrate/20211119111006_create_job_artifact_states.rb'
+ - 'db/migrate/20211119154221_create_pages_deployment_states.rb'
+ - 'db/migrate/20211119195201_create_deployment_approvals.rb'
+ - 'db/migrate/20211201143042_create_lfs_object_states.rb'
+ - 'db/migrate/20211216220939_add_group_crm_settings.rb'
+ - 'db/migrate/20220110170953_create_ci_secure_files.rb'
+ - 'db/migrate/20220112205111_create_security_training_providers.rb'
+ - 'db/migrate/20220113125401_create_security_trainings.rb'
+ - 'db/migrate/20220120033115_create_alert_management_alert_metric_images.rb'
+ - 'db/migrate/20220204093120_create_analytics_cycle_analytics_aggregations.rb'
+ - 'db/migrate/20220211125954_create_related_epic_links.rb'
+ - 'db/migrate/20220216110023_create_saved_replies.rb'
+ - 'db/migrate/20220301175426_create_project_build_artifacts_size_refresh.rb'
+ - 'db/migrate/20220302110724_add_group_features_table.rb'
+ - 'db/migrate/20220314184009_create_protected_environment_approval_rules.rb'
+ - 'db/migrate/20220425120604_create_packages_cleanup_policies.rb'
+ - 'db/migrate/20220503102855_add_namespace_ci_cd_settings_table.rb'
diff --git a/.rubocop_todo/style/class_and_module_children.yml b/.rubocop_todo/style/class_and_module_children.yml
new file mode 100644
index 00000000000..9d89acfb394
--- /dev/null
+++ b/.rubocop_todo/style/class_and_module_children.yml
@@ -0,0 +1,587 @@
+---
+# Cop supports --auto-correct.
+Style/ClassAndModuleChildren:
+ Exclude:
+ - 'app/components/pajamas/toggle_component.rb'
+ - 'app/controllers/admin/abuse_reports_controller.rb'
+ - 'app/controllers/admin/application_controller.rb'
+ - 'app/controllers/admin/application_settings/appearances_controller.rb'
+ - 'app/controllers/admin/application_settings_controller.rb'
+ - 'app/controllers/admin/applications_controller.rb'
+ - 'app/controllers/admin/background_jobs_controller.rb'
+ - 'app/controllers/admin/background_migrations_controller.rb'
+ - 'app/controllers/admin/batched_jobs_controller.rb'
+ - 'app/controllers/admin/broadcast_messages_controller.rb'
+ - 'app/controllers/admin/ci/variables_controller.rb'
+ - 'app/controllers/admin/clusters/integrations_controller.rb'
+ - 'app/controllers/admin/clusters_controller.rb'
+ - 'app/controllers/admin/cohorts_controller.rb'
+ - 'app/controllers/admin/dashboard_controller.rb'
+ - 'app/controllers/admin/deploy_keys_controller.rb'
+ - 'app/controllers/admin/dev_ops_report_controller.rb'
+ - 'app/controllers/admin/gitaly_servers_controller.rb'
+ - 'app/controllers/admin/groups_controller.rb'
+ - 'app/controllers/admin/health_check_controller.rb'
+ - 'app/controllers/admin/hook_logs_controller.rb'
+ - 'app/controllers/admin/hooks_controller.rb'
+ - 'app/controllers/admin/identities_controller.rb'
+ - 'app/controllers/admin/impersonation_tokens_controller.rb'
+ - 'app/controllers/admin/impersonations_controller.rb'
+ - 'app/controllers/admin/instance_review_controller.rb'
+ - 'app/controllers/admin/integrations_controller.rb'
+ - 'app/controllers/admin/jobs_controller.rb'
+ - 'app/controllers/admin/keys_controller.rb'
+ - 'app/controllers/admin/labels_controller.rb'
+ - 'app/controllers/admin/plan_limits_controller.rb'
+ - 'app/controllers/admin/projects_controller.rb'
+ - 'app/controllers/admin/runner_projects_controller.rb'
+ - 'app/controllers/admin/runners_controller.rb'
+ - 'app/controllers/admin/sessions_controller.rb'
+ - 'app/controllers/admin/spam_logs_controller.rb'
+ - 'app/controllers/admin/system_info_controller.rb'
+ - 'app/controllers/admin/topics/avatars_controller.rb'
+ - 'app/controllers/admin/topics_controller.rb'
+ - 'app/controllers/admin/usage_trends_controller.rb'
+ - 'app/controllers/admin/users_controller.rb'
+ - 'app/controllers/admin/version_check_controller.rb'
+ - 'app/controllers/clusters/base_controller.rb'
+ - 'app/controllers/clusters/clusters_controller.rb'
+ - 'app/controllers/concerns/integrations/actions.rb'
+ - 'app/controllers/concerns/integrations/hooks_execution.rb'
+ - 'app/controllers/concerns/metrics/dashboard/prometheus_api_proxy.rb'
+ - 'app/controllers/concerns/snippets/blobs_actions.rb'
+ - 'app/controllers/concerns/snippets/send_blob.rb'
+ - 'app/controllers/concerns/spammable_actions/akismet_mark_as_spam_action.rb'
+ - 'app/controllers/concerns/spammable_actions/captcha_check/html_format_actions_support.rb'
+ - 'app/controllers/concerns/spammable_actions/captcha_check/json_format_actions_support.rb'
+ - 'app/controllers/concerns/spammable_actions/captcha_check/rest_api_actions_support.rb'
+ - 'app/controllers/dashboard/application_controller.rb'
+ - 'app/controllers/dashboard/groups_controller.rb'
+ - 'app/controllers/dashboard/labels_controller.rb'
+ - 'app/controllers/dashboard/milestones_controller.rb'
+ - 'app/controllers/dashboard/projects_controller.rb'
+ - 'app/controllers/dashboard/snippets_controller.rb'
+ - 'app/controllers/dashboard/todos_controller.rb'
+ - 'app/controllers/explore/application_controller.rb'
+ - 'app/controllers/explore/groups_controller.rb'
+ - 'app/controllers/explore/projects_controller.rb'
+ - 'app/controllers/explore/snippets_controller.rb'
+ - 'app/controllers/groups/application_controller.rb'
+ - 'app/controllers/groups/autocomplete_sources_controller.rb'
+ - 'app/controllers/groups/avatars_controller.rb'
+ - 'app/controllers/groups/boards_controller.rb'
+ - 'app/controllers/groups/clusters/integrations_controller.rb'
+ - 'app/controllers/groups/clusters_controller.rb'
+ - 'app/controllers/groups/crm/contacts_controller.rb'
+ - 'app/controllers/groups/crm/organizations_controller.rb'
+ - 'app/controllers/groups/dependency_proxy_auth_controller.rb'
+ - 'app/controllers/groups/dependency_proxy_for_containers_controller.rb'
+ - 'app/controllers/groups/deploy_tokens_controller.rb'
+ - 'app/controllers/groups/email_campaigns_controller.rb'
+ - 'app/controllers/groups/group_links_controller.rb'
+ - 'app/controllers/groups/group_members_controller.rb'
+ - 'app/controllers/groups/imports_controller.rb'
+ - 'app/controllers/groups/labels_controller.rb'
+ - 'app/controllers/groups/milestones_controller.rb'
+ - 'app/controllers/groups/runners_controller.rb'
+ - 'app/controllers/groups/uploads_controller.rb'
+ - 'app/controllers/import/available_namespaces_controller.rb'
+ - 'app/controllers/import/base_controller.rb'
+ - 'app/controllers/import/bitbucket_controller.rb'
+ - 'app/controllers/import/bitbucket_server_controller.rb'
+ - 'app/controllers/import/bulk_imports_controller.rb'
+ - 'app/controllers/import/fogbugz_controller.rb'
+ - 'app/controllers/import/gitea_controller.rb'
+ - 'app/controllers/import/github_controller.rb'
+ - 'app/controllers/import/gitlab_controller.rb'
+ - 'app/controllers/import/gitlab_groups_controller.rb'
+ - 'app/controllers/import/gitlab_projects_controller.rb'
+ - 'app/controllers/import/history_controller.rb'
+ - 'app/controllers/import/manifest_controller.rb'
+ - 'app/controllers/import/phabricator_controller.rb'
+ - 'app/controllers/import/url_controller.rb'
+ - 'app/controllers/jira_connect/app_descriptor_controller.rb'
+ - 'app/controllers/jira_connect/application_controller.rb'
+ - 'app/controllers/jira_connect/branches_controller.rb'
+ - 'app/controllers/jira_connect/events_controller.rb'
+ - 'app/controllers/jira_connect/installations_controller.rb'
+ - 'app/controllers/jira_connect/oauth_callbacks_controller.rb'
+ - 'app/controllers/jira_connect/subscriptions_controller.rb'
+ - 'app/controllers/jira_connect/users_controller.rb'
+ - 'app/controllers/ldap/omniauth_callbacks_controller.rb'
+ - 'app/controllers/oauth/applications_controller.rb'
+ - 'app/controllers/oauth/authorizations_controller.rb'
+ - 'app/controllers/oauth/authorized_applications_controller.rb'
+ - 'app/controllers/oauth/jira_dvcs/authorizations_controller.rb'
+ - 'app/controllers/oauth/token_info_controller.rb'
+ - 'app/controllers/oauth/tokens_controller.rb'
+ - 'app/controllers/profiles/accounts_controller.rb'
+ - 'app/controllers/profiles/active_sessions_controller.rb'
+ - 'app/controllers/profiles/application_controller.rb'
+ - 'app/controllers/profiles/avatars_controller.rb'
+ - 'app/controllers/profiles/chat_names_controller.rb'
+ - 'app/controllers/profiles/emails_controller.rb'
+ - 'app/controllers/profiles/gpg_keys_controller.rb'
+ - 'app/controllers/profiles/groups_controller.rb'
+ - 'app/controllers/profiles/keys_controller.rb'
+ - 'app/controllers/profiles/notifications_controller.rb'
+ - 'app/controllers/profiles/passwords_controller.rb'
+ - 'app/controllers/profiles/personal_access_tokens_controller.rb'
+ - 'app/controllers/profiles/preferences_controller.rb'
+ - 'app/controllers/profiles/two_factor_auths_controller.rb'
+ - 'app/controllers/profiles/u2f_registrations_controller.rb'
+ - 'app/controllers/profiles/webauthn_registrations_controller.rb'
+ - 'app/controllers/projects/alert_management_controller.rb'
+ - 'app/controllers/projects/analytics/cycle_analytics/stages_controller.rb'
+ - 'app/controllers/projects/analytics/cycle_analytics/summary_controller.rb'
+ - 'app/controllers/projects/analytics/cycle_analytics/value_streams_controller.rb'
+ - 'app/controllers/projects/application_controller.rb'
+ - 'app/controllers/projects/artifacts_controller.rb'
+ - 'app/controllers/projects/autocomplete_sources_controller.rb'
+ - 'app/controllers/projects/avatars_controller.rb'
+ - 'app/controllers/projects/badges_controller.rb'
+ - 'app/controllers/projects/blame_controller.rb'
+ - 'app/controllers/projects/blob_controller.rb'
+ - 'app/controllers/projects/boards_controller.rb'
+ - 'app/controllers/projects/branches_controller.rb'
+ - 'app/controllers/projects/build_artifacts_controller.rb'
+ - 'app/controllers/projects/builds_controller.rb'
+ - 'app/controllers/projects/ci/daily_build_group_report_results_controller.rb'
+ - 'app/controllers/projects/ci/lints_controller.rb'
+ - 'app/controllers/projects/ci/pipeline_editor_controller.rb'
+ - 'app/controllers/projects/ci/secure_files_controller.rb'
+ - 'app/controllers/projects/cluster_agents_controller.rb'
+ - 'app/controllers/projects/clusters/integrations_controller.rb'
+ - 'app/controllers/projects/clusters_controller.rb'
+ - 'app/controllers/projects/commit_controller.rb'
+ - 'app/controllers/projects/commits_controller.rb'
+ - 'app/controllers/projects/compare_controller.rb'
+ - 'app/controllers/projects/confluences_controller.rb'
+ - 'app/controllers/projects/cycle_analytics_controller.rb'
+ - 'app/controllers/projects/deploy_keys_controller.rb'
+ - 'app/controllers/projects/deploy_tokens_controller.rb'
+ - 'app/controllers/projects/deployments_controller.rb'
+ - 'app/controllers/projects/design_management/designs_controller.rb'
+ - 'app/controllers/projects/discussions_controller.rb'
+ - 'app/controllers/projects/environments/prometheus_api_controller.rb'
+ - 'app/controllers/projects/environments/sample_metrics_controller.rb'
+ - 'app/controllers/projects/environments_controller.rb'
+ - 'app/controllers/projects/error_tracking/base_controller.rb'
+ - 'app/controllers/projects/error_tracking_controller.rb'
+ - 'app/controllers/projects/feature_flags_clients_controller.rb'
+ - 'app/controllers/projects/feature_flags_controller.rb'
+ - 'app/controllers/projects/feature_flags_user_lists_controller.rb'
+ - 'app/controllers/projects/find_file_controller.rb'
+ - 'app/controllers/projects/forks_controller.rb'
+ - 'app/controllers/projects/google_cloud/base_controller.rb'
+ - 'app/controllers/projects/google_cloud/deployments_controller.rb'
+ - 'app/controllers/projects/google_cloud/gcp_regions_controller.rb'
+ - 'app/controllers/projects/google_cloud/revoke_oauth_controller.rb'
+ - 'app/controllers/projects/google_cloud/service_accounts_controller.rb'
+ - 'app/controllers/projects/google_cloud_controller.rb'
+ - 'app/controllers/projects/grafana_api_controller.rb'
+ - 'app/controllers/projects/graphs_controller.rb'
+ - 'app/controllers/projects/group_links_controller.rb'
+ - 'app/controllers/projects/hook_logs_controller.rb'
+ - 'app/controllers/projects/hooks_controller.rb'
+ - 'app/controllers/projects/imports_controller.rb'
+ - 'app/controllers/projects/incidents_controller.rb'
+ - 'app/controllers/projects/issues_controller.rb'
+ - 'app/controllers/projects/jobs_controller.rb'
+ - 'app/controllers/projects/labels_controller.rb'
+ - 'app/controllers/projects/learn_gitlab_controller.rb'
+ - 'app/controllers/projects/mattermosts_controller.rb'
+ - 'app/controllers/projects/merge_requests/application_controller.rb'
+ - 'app/controllers/projects/merge_requests/conflicts_controller.rb'
+ - 'app/controllers/projects/merge_requests/content_controller.rb'
+ - 'app/controllers/projects/merge_requests/creations_controller.rb'
+ - 'app/controllers/projects/merge_requests/diffs_controller.rb'
+ - 'app/controllers/projects/merge_requests/drafts_controller.rb'
+ - 'app/controllers/projects/merge_requests_controller.rb'
+ - 'app/controllers/projects/milestones_controller.rb'
+ - 'app/controllers/projects/mirrors_controller.rb'
+ - 'app/controllers/projects/network_controller.rb'
+ - 'app/controllers/projects/notes_controller.rb'
+ - 'app/controllers/projects/pages_controller.rb'
+ - 'app/controllers/projects/pages_domains_controller.rb'
+ - 'app/controllers/projects/pipeline_schedules_controller.rb'
+ - 'app/controllers/projects/pipelines_controller.rb'
+ - 'app/controllers/projects/pipelines_settings_controller.rb'
+ - 'app/controllers/projects/product_analytics_controller.rb'
+ - 'app/controllers/projects/project_members_controller.rb'
+ - 'app/controllers/projects/protected_branches_controller.rb'
+ - 'app/controllers/projects/protected_refs_controller.rb'
+ - 'app/controllers/projects/protected_tags_controller.rb'
+ - 'app/controllers/projects/raw_controller.rb'
+ - 'app/controllers/projects/redirect_controller.rb'
+ - 'app/controllers/projects/refs_controller.rb'
+ - 'app/controllers/projects/releases_controller.rb'
+ - 'app/controllers/projects/repositories_controller.rb'
+ - 'app/controllers/projects/runner_projects_controller.rb'
+ - 'app/controllers/projects/runners_controller.rb'
+ - 'app/controllers/projects/service_desk_controller.rb'
+ - 'app/controllers/projects/service_hook_logs_controller.rb'
+ - 'app/controllers/projects/service_ping_controller.rb'
+ - 'app/controllers/projects/services_controller.rb'
+ - 'app/controllers/projects/snippets/application_controller.rb'
+ - 'app/controllers/projects/snippets/blobs_controller.rb'
+ - 'app/controllers/projects/snippets_controller.rb'
+ - 'app/controllers/projects/starrers_controller.rb'
+ - 'app/controllers/projects/static_site_editor_controller.rb'
+ - 'app/controllers/projects/tags/releases_controller.rb'
+ - 'app/controllers/projects/tags_controller.rb'
+ - 'app/controllers/projects/templates_controller.rb'
+ - 'app/controllers/projects/terraform_controller.rb'
+ - 'app/controllers/projects/todos_controller.rb'
+ - 'app/controllers/projects/tree_controller.rb'
+ - 'app/controllers/projects/triggers_controller.rb'
+ - 'app/controllers/projects/uploads_controller.rb'
+ - 'app/controllers/projects/usage_quotas_controller.rb'
+ - 'app/controllers/projects/variables_controller.rb'
+ - 'app/controllers/projects/web_ide_schemas_controller.rb'
+ - 'app/controllers/projects/web_ide_terminals_controller.rb'
+ - 'app/controllers/projects/wikis_controller.rb'
+ - 'app/controllers/projects/work_items_controller.rb'
+ - 'app/controllers/snippets/application_controller.rb'
+ - 'app/controllers/snippets/blobs_controller.rb'
+ - 'app/controllers/snippets/notes_controller.rb'
+ - 'app/controllers/terraform/services_controller.rb'
+ - 'app/finders/admin/projects_finder.rb'
+ - 'app/finders/merge_request/metrics_finder.rb'
+ - 'app/finders/packages/package_file_finder.rb'
+ - 'app/finders/packages/tags_finder.rb'
+ - 'app/graphql/types/dependency_proxy/blob_type.rb'
+ - 'app/graphql/types/dependency_proxy/group_setting_type.rb'
+ - 'app/graphql/types/dependency_proxy/image_ttl_group_policy_type.rb'
+ - 'app/graphql/types/dependency_proxy/manifest_type.rb'
+ - 'app/graphql/types/dependency_proxy/manifest_type_enum.rb'
+ - 'app/graphql/types/namespace/package_settings_type.rb'
+ - 'app/graphql/types/namespace/shared_runners_setting_enum.rb'
+ - 'app/helpers/ci/triggers_helper.rb'
+ - 'app/helpers/groups/group_members_helper.rb'
+ - 'app/helpers/projects/alert_management_helper.rb'
+ - 'app/helpers/projects/cluster_agents_helper.rb'
+ - 'app/helpers/projects/error_tracking_helper.rb'
+ - 'app/helpers/projects/incidents_helper.rb'
+ - 'app/helpers/projects/project_members_helper.rb'
+ - 'app/helpers/projects/terraform_helper.rb'
+ - 'app/models/analytics/cycle_analytics/aggregation.rb'
+ - 'app/models/analytics/cycle_analytics/project_value_stream.rb'
+ - 'app/models/bulk_imports/configuration.rb'
+ - 'app/models/bulk_imports/entity.rb'
+ - 'app/models/bulk_imports/failure.rb'
+ - 'app/models/bulk_imports/tracker.rb'
+ - 'app/models/ci/build_pending_state.rb'
+ - 'app/models/ci/commit_with_pipeline.rb'
+ - 'app/models/customer_relations/contact.rb'
+ - 'app/models/customer_relations/issue_contact.rb'
+ - 'app/models/customer_relations/organization.rb'
+ - 'app/models/dependency_proxy/blob.rb'
+ - 'app/models/dependency_proxy/group_setting.rb'
+ - 'app/models/dependency_proxy/image_ttl_group_policy.rb'
+ - 'app/models/dependency_proxy/manifest.rb'
+ - 'app/models/dependency_proxy/registry.rb'
+ - 'app/models/error_tracking/client_key.rb'
+ - 'app/models/error_tracking/error.rb'
+ - 'app/models/error_tracking/error_event.rb'
+ - 'app/models/group/crm_settings.rb'
+ - 'app/models/instance_metadata/kas.rb'
+ - 'app/models/issue/email.rb'
+ - 'app/models/issue/metrics.rb'
+ - 'app/models/issues/csv_import.rb'
+ - 'app/models/loose_foreign_keys/deleted_record.rb'
+ - 'app/models/merge_request/cleanup_schedule.rb'
+ - 'app/models/merge_request/diff_commit_user.rb'
+ - 'app/models/merge_request/metrics.rb'
+ - 'app/models/namespace/admin_note.rb'
+ - 'app/models/namespace/aggregation_schedule.rb'
+ - 'app/models/namespace/package_setting.rb'
+ - 'app/models/namespace/root_storage_statistics.rb'
+ - 'app/models/namespaces/sync_event.rb'
+ - 'app/models/packages/build_info.rb'
+ - 'app/models/packages/conan/file_metadatum.rb'
+ - 'app/models/packages/conan/metadatum.rb'
+ - 'app/models/packages/debian/file_metadatum.rb'
+ - 'app/models/packages/debian/group_architecture.rb'
+ - 'app/models/packages/debian/group_component.rb'
+ - 'app/models/packages/debian/group_component_file.rb'
+ - 'app/models/packages/debian/group_distribution.rb'
+ - 'app/models/packages/debian/group_distribution_key.rb'
+ - 'app/models/packages/debian/project_architecture.rb'
+ - 'app/models/packages/debian/project_component.rb'
+ - 'app/models/packages/debian/project_component_file.rb'
+ - 'app/models/packages/debian/project_distribution.rb'
+ - 'app/models/packages/debian/project_distribution_key.rb'
+ - 'app/models/packages/debian/publication.rb'
+ - 'app/models/packages/dependency.rb'
+ - 'app/models/packages/dependency_link.rb'
+ - 'app/models/packages/event.rb'
+ - 'app/models/packages/maven/metadatum.rb'
+ - 'app/models/packages/npm/metadatum.rb'
+ - 'app/models/packages/nuget/dependency_link_metadatum.rb'
+ - 'app/models/packages/nuget/metadatum.rb'
+ - 'app/models/packages/package.rb'
+ - 'app/models/packages/package_file.rb'
+ - 'app/models/packages/package_file_build_info.rb'
+ - 'app/models/packages/pypi/metadatum.rb'
+ - 'app/models/packages/sem_ver.rb'
+ - 'app/models/packages/tag.rb'
+ - 'app/models/projects/sync_event.rb'
+ - 'app/models/protected_branch/merge_access_level.rb'
+ - 'app/models/protected_branch/push_access_level.rb'
+ - 'app/models/protected_tag/create_access_level.rb'
+ - 'app/policies/namespace/package_setting_policy.rb'
+ - 'app/policies/namespace/root_storage_statistics_policy.rb'
+ - 'app/policies/wiki_page/meta_policy.rb'
+ - 'app/serializers/acts_as_taggable_on/tag_entity.rb'
+ - 'app/serializers/acts_as_taggable_on/tag_serializer.rb'
+ - 'app/serializers/ci/lint/job_entity.rb'
+ - 'app/serializers/ci/lint/result_entity.rb'
+ - 'app/serializers/ci/lint/result_serializer.rb'
+ - 'app/serializers/ci/pipeline_entity.rb'
+ - 'app/serializers/import/base_provider_repo_entity.rb'
+ - 'app/serializers/import/bitbucket_provider_repo_entity.rb'
+ - 'app/serializers/import/bitbucket_server_provider_repo_entity.rb'
+ - 'app/serializers/import/bulk_import_entity.rb'
+ - 'app/serializers/import/fogbugz_provider_repo_entity.rb'
+ - 'app/serializers/import/githubish_provider_repo_entity.rb'
+ - 'app/serializers/import/gitlab_provider_repo_entity.rb'
+ - 'app/serializers/import/manifest_provider_repo_entity.rb'
+ - 'app/serializers/import/provider_repo_serializer.rb'
+ - 'app/serializers/jira_connect/app_data_serializer.rb'
+ - 'app/serializers/jira_connect/group_entity.rb'
+ - 'app/serializers/jira_connect/subscription_entity.rb'
+ - 'app/serializers/merge_requests/pipeline_entity.rb'
+ - 'app/services/projects/branches_by_mode_service.rb'
+ - 'app/services/repositories/base_service.rb'
+ - 'app/services/repositories/destroy_rollback_service.rb'
+ - 'app/services/repositories/destroy_service.rb'
+ - 'app/services/repositories/shell_destroy_service.rb'
+ - 'app/uploaders/dependency_proxy/file_uploader.rb'
+ - 'app/uploaders/packages/composer/cache_uploader.rb'
+ - 'app/uploaders/packages/debian/component_file_uploader.rb'
+ - 'app/uploaders/packages/debian/distribution_release_file_uploader.rb'
+ - 'app/uploaders/packages/package_file_uploader.rb'
+ - 'app/workers/merge_requests/delete_source_branch_worker.rb'
+ - 'app/workers/merge_requests/handle_assignees_change_worker.rb'
+ - 'app/workers/merge_requests/resolve_todos_worker.rb'
+ - 'config/initializers/active_record_data_types.rb'
+ - 'config/initializers/http_hostname_override.rb'
+ - 'config/initializers/httpclient_patch.rb'
+ - 'config/initializers/omniauth.rb'
+ - 'config/initializers/postgres_cte_as_materialized.rb'
+ - 'config/initializers/postgresql_cte.rb'
+ - 'config/initializers/rdoc_segfault_patch.rb'
+ - 'config/initializers/zz_metrics.rb'
+ - 'ee/app/controllers/admin/audit_log_reports_controller.rb'
+ - 'ee/app/controllers/admin/audit_logs_controller.rb'
+ - 'ee/app/controllers/admin/credentials_controller.rb'
+ - 'ee/app/controllers/admin/elasticsearch_controller.rb'
+ - 'ee/app/controllers/admin/emails_controller.rb'
+ - 'ee/app/controllers/admin/geo/application_controller.rb'
+ - 'ee/app/controllers/admin/geo/designs_controller.rb'
+ - 'ee/app/controllers/admin/geo/nodes_controller.rb'
+ - 'ee/app/controllers/admin/geo/projects_controller.rb'
+ - 'ee/app/controllers/admin/geo/replicables_controller.rb'
+ - 'ee/app/controllers/admin/geo/settings_controller.rb'
+ - 'ee/app/controllers/admin/licenses_controller.rb'
+ - 'ee/app/controllers/admin/push_rules_controller.rb'
+ - 'ee/app/controllers/admin/subscriptions_controller.rb'
+ - 'ee/app/controllers/admin/user_permission_exports_controller.rb'
+ - 'ee/app/controllers/concerns/registrations/apply_trial.rb'
+ - 'ee/app/controllers/concerns/registrations/create_group.rb'
+ - 'ee/app/controllers/concerns/registrations/create_project.rb'
+ - 'ee/app/controllers/concerns/registrations/verification.rb'
+ - 'ee/app/controllers/ee/profiles/accounts_controller.rb'
+ - 'ee/app/controllers/ee/profiles/preferences_controller.rb'
+ - 'ee/app/controllers/ee/projects/analytics/cycle_analytics/summary_controller.rb'
+ - 'ee/app/controllers/ee/projects/incidents_controller.rb'
+ - 'ee/app/controllers/groups/analytics/application_controller.rb'
+ - 'ee/app/controllers/groups/analytics/ci_cd_analytics_controller.rb'
+ - 'ee/app/controllers/groups/analytics/coverage_reports_controller.rb'
+ - 'ee/app/controllers/groups/analytics/cycle_analytics/value_streams_controller.rb'
+ - 'ee/app/controllers/groups/analytics/cycle_analytics_controller.rb'
+ - 'ee/app/controllers/groups/analytics/devops_adoption_controller.rb'
+ - 'ee/app/controllers/groups/analytics/productivity_analytics_controller.rb'
+ - 'ee/app/controllers/groups/analytics/repository_analytics_controller.rb'
+ - 'ee/app/controllers/groups/analytics/tasks_by_type_controller.rb'
+ - 'ee/app/controllers/groups/audit_events_controller.rb'
+ - 'ee/app/controllers/groups/billings_controller.rb'
+ - 'ee/app/controllers/groups/bulk_update_controller.rb'
+ - 'ee/app/controllers/groups/compliance_frameworks_controller.rb'
+ - 'ee/app/controllers/groups/contribution_analytics_controller.rb'
+ - 'ee/app/controllers/groups/epic_boards_controller.rb'
+ - 'ee/app/controllers/groups/epic_issues_controller.rb'
+ - 'ee/app/controllers/groups/epics/notes_controller.rb'
+ - 'ee/app/controllers/groups/epics_controller.rb'
+ - 'ee/app/controllers/groups/hooks_controller.rb'
+ - 'ee/app/controllers/groups/insights_controller.rb'
+ - 'ee/app/controllers/groups/issues_analytics_controller.rb'
+ - 'ee/app/controllers/groups/issues_controller.rb'
+ - 'ee/app/controllers/groups/iteration_cadences_controller.rb'
+ - 'ee/app/controllers/groups/iterations_controller.rb'
+ - 'ee/app/controllers/groups/ldap_group_links_controller.rb'
+ - 'ee/app/controllers/groups/ldap_settings_controller.rb'
+ - 'ee/app/controllers/groups/ldaps_controller.rb'
+ - 'ee/app/controllers/groups/merge_requests_controller.rb'
+ - 'ee/app/controllers/groups/omniauth_callbacks_controller.rb'
+ - 'ee/app/controllers/groups/push_rules_controller.rb'
+ - 'ee/app/controllers/groups/saml_providers_controller.rb'
+ - 'ee/app/controllers/groups/scim_oauth_controller.rb'
+ - 'ee/app/controllers/groups/seat_usage_controller.rb'
+ - 'ee/app/controllers/groups/security/compliance_dashboards_controller.rb'
+ - 'ee/app/controllers/groups/security/credentials_controller.rb'
+ - 'ee/app/controllers/groups/security/dashboard_controller.rb'
+ - 'ee/app/controllers/groups/security/discover_controller.rb'
+ - 'ee/app/controllers/groups/security/merge_commit_reports_controller.rb'
+ - 'ee/app/controllers/groups/sso_controller.rb'
+ - 'ee/app/controllers/groups/todos_controller.rb'
+ - 'ee/app/controllers/groups/usage_quotas_controller.rb'
+ - 'ee/app/controllers/groups/wikis_controller.rb'
+ - 'ee/app/controllers/oauth/geo_auth_controller.rb'
+ - 'ee/app/controllers/profiles/billings_controller.rb'
+ - 'ee/app/controllers/profiles/slacks_controller.rb'
+ - 'ee/app/controllers/profiles/usage_quotas_controller.rb'
+ - 'ee/app/controllers/projects/analytics/issues_analytics_controller.rb'
+ - 'ee/app/controllers/projects/analytics/merge_request_analytics_controller.rb'
+ - 'ee/app/controllers/projects/approver_groups_controller.rb'
+ - 'ee/app/controllers/projects/approvers_controller.rb'
+ - 'ee/app/controllers/projects/audit_events_controller.rb'
+ - 'ee/app/controllers/projects/insights_controller.rb'
+ - 'ee/app/controllers/projects/iteration_cadences_controller.rb'
+ - 'ee/app/controllers/projects/iterations_controller.rb'
+ - 'ee/app/controllers/projects/path_locks_controller.rb'
+ - 'ee/app/controllers/projects/protected_environments_controller.rb'
+ - 'ee/app/controllers/projects/push_rules_controller.rb'
+ - 'ee/app/controllers/projects/quality/test_cases_controller.rb'
+ - 'ee/app/controllers/projects/requirements_management/requirements_controller.rb'
+ - 'ee/app/controllers/projects/subscriptions_controller.rb'
+ - 'ee/app/controllers/projects/vulnerability_feedback_controller.rb'
+ - 'ee/app/finders/ee/group_members_finder.rb'
+ - 'ee/app/graphql/mutations/app_sec/fuzzing/coverage/corpus/create.rb'
+ - 'ee/app/helpers/ee/groups/analytics/cycle_analytics_helper.rb'
+ - 'ee/app/helpers/ee/groups/group_members_helper.rb'
+ - 'ee/app/helpers/ee/security_orchestration_helper.rb'
+ - 'ee/app/helpers/groups/ldap_sync_helper.rb'
+ - 'ee/app/helpers/groups/security_features_helper.rb'
+ - 'ee/app/helpers/groups/sso_helper.rb'
+ - 'ee/app/helpers/projects/on_demand_scans_helper.rb'
+ - 'ee/app/helpers/projects/security/api_fuzzing_configuration_helper.rb'
+ - 'ee/app/helpers/projects/security/dast_configuration_helper.rb'
+ - 'ee/app/helpers/projects/security/dast_profiles_helper.rb'
+ - 'ee/app/helpers/projects/security/discover_helper.rb'
+ - 'ee/app/helpers/projects/security/sast_configuration_helper.rb'
+ - 'ee/app/models/analytics/cycle_analytics/group_value_stream.rb'
+ - 'ee/app/models/analytics/devops_adoption.rb'
+ - 'ee/app/models/analytics/devops_adoption/enabled_namespace.rb'
+ - 'ee/app/models/analytics/devops_adoption/snapshot.rb'
+ - 'ee/app/models/analytics/issues_analytics.rb'
+ - 'ee/app/models/analytics/language_trend.rb'
+ - 'ee/app/models/analytics/language_trend/repository_language.rb'
+ - 'ee/app/models/concerns/geo/replicable_registry.rb'
+ - 'ee/app/models/concerns/geo/selective_sync.rb'
+ - 'ee/app/models/concerns/geo/syncable.rb'
+ - 'ee/app/models/dast/profile_schedule.rb'
+ - 'ee/app/models/ee/ci/job_artifact.rb'
+ - 'ee/app/models/ee/namespace/root_excess_storage_size.rb'
+ - 'ee/app/models/ee/namespace/root_storage_size.rb'
+ - 'ee/app/models/elastic/reindexing_slice.rb'
+ - 'ee/app/models/elastic/reindexing_subtask.rb'
+ - 'ee/app/models/elastic/reindexing_task.rb'
+ - 'ee/app/models/epic/metrics.rb'
+ - 'ee/app/models/epic/related_epic_link.rb'
+ - 'ee/app/models/geo/base_registry.rb'
+ - 'ee/app/models/geo/container_repository_registry.rb'
+ - 'ee/app/models/geo/deleted_project.rb'
+ - 'ee/app/models/geo/design_registry.rb'
+ - 'ee/app/models/geo/event_log_state.rb'
+ - 'ee/app/models/geo/group_wiki_repository_registry.rb'
+ - 'ee/app/models/geo/job_artifact_registry.rb'
+ - 'ee/app/models/geo/lfs_object_registry.rb'
+ - 'ee/app/models/geo/merge_request_diff_registry.rb'
+ - 'ee/app/models/geo/package_file_registry.rb'
+ - 'ee/app/models/geo/pages_deployment_registry.rb'
+ - 'ee/app/models/geo/project_registry.rb'
+ - 'ee/app/models/geo/push_user.rb'
+ - 'ee/app/models/geo/secondary_usage_data.rb'
+ - 'ee/app/models/geo/snippet_repository_registry.rb'
+ - 'ee/app/models/geo/terraform_state_version_registry.rb'
+ - 'ee/app/models/geo/upload_registry.rb'
+ - 'ee/app/models/protected_branch/required_code_owners_section.rb'
+ - 'ee/app/models/protected_branch/unprotect_access_level.rb'
+ - 'ee/app/models/protected_environment/deploy_access_level.rb'
+ - 'ee/app/serializers/vulnerabilities/feedback_entity.rb'
+ - 'ee/app/serializers/vulnerabilities/feedback_serializer.rb'
+ - 'ee/app/serializers/vulnerabilities/finding_diff_serializer.rb'
+ - 'ee/app/serializers/vulnerabilities/finding_entity.rb'
+ - 'ee/app/serializers/vulnerabilities/finding_reports_comparer_entity.rb'
+ - 'ee/app/serializers/vulnerabilities/finding_serializer.rb'
+ - 'ee/app/serializers/vulnerabilities/identifier_entity.rb'
+ - 'ee/app/serializers/vulnerabilities/request_entity.rb'
+ - 'ee/app/serializers/vulnerabilities/response_entity.rb'
+ - 'ee/app/serializers/vulnerabilities/scanner_entity.rb'
+ - 'ee/app/services/concerns/epics/related_epic_links/usage_data_helper.rb'
+ - 'ee/app/services/ee/projects/after_rename_service.rb'
+ - 'ee/app/services/ee/projects/disable_deploy_key_service.rb'
+ - 'ee/app/services/ee/projects/enable_deploy_key_service.rb'
+ - 'ee/app/services/ee/projects/update_pages_service.rb'
+ - 'ee/db/fixtures/development/20_burndown.rb'
+ - 'ee/db/fixtures/development/20_vulnerabilities.rb'
+ - 'ee/db/fixtures/development/21_dast_profiles.rb'
+ - 'ee/db/fixtures/development/30_customizable_cycle_analytics.rb'
+ - 'ee/db/fixtures/development/32_compliance_report_violations.rb'
+ - 'ee/db/fixtures/development/90_productivity_analytics.rb'
+ - 'ee/lib/ee/gitlab/analytics/cycle_analytics/aggregated/base_query_builder.rb'
+ - 'ee/lib/ee/gitlab/analytics/cycle_analytics/base_query_builder.rb'
+ - 'ee/lib/ee/gitlab/analytics/cycle_analytics/records_fetcher.rb'
+ - 'ee/lib/ee/gitlab/background_migration/recalculate_vulnerability_finding_signatures_for_findings.rb'
+ - 'ee/lib/ee/gitlab/throttle.rb'
+ - 'ee/lib/gitlab/path_locks_finder.rb'
+ - 'lib/api/error_tracking/client_keys.rb'
+ - 'lib/api/error_tracking/collector.rb'
+ - 'lib/api/error_tracking/project_settings.rb'
+ - 'lib/gitlab/background_migration/drop_invalid_vulnerabilities.rb'
+ - 'lib/gitlab/background_migration/recalculate_vulnerabilities_occurrences_uuid.rb'
+ - 'lib/gitlab/background_migration/remove_duplicate_vulnerabilities_findings.rb'
+ - 'lib/gitlab/background_migration/remove_occurrence_pipelines_and_duplicate_vulnerabilities_findings.rb'
+ - 'lib/gitlab/background_migration/update_jira_tracker_data_deployment_type_based_on_url.rb'
+ - 'lib/gitlab/ci/badge/base.rb'
+ - 'lib/gitlab/ci/badge/coverage/metadata.rb'
+ - 'lib/gitlab/ci/badge/coverage/report.rb'
+ - 'lib/gitlab/ci/badge/coverage/template.rb'
+ - 'lib/gitlab/ci/badge/metadata.rb'
+ - 'lib/gitlab/ci/badge/pipeline/metadata.rb'
+ - 'lib/gitlab/ci/badge/pipeline/status.rb'
+ - 'lib/gitlab/ci/badge/pipeline/template.rb'
+ - 'lib/gitlab/ci/badge/release/latest_release.rb'
+ - 'lib/gitlab/ci/badge/release/metadata.rb'
+ - 'lib/gitlab/ci/badge/release/template.rb'
+ - 'lib/gitlab/ci/badge/template.rb'
+ - 'lib/gitlab/ci/build/auto_retry.rb'
+ - 'lib/gitlab/ci/build/rules/rule.rb'
+ - 'lib/gitlab/ci/build/rules/rule/clause.rb'
+ - 'lib/gitlab/ci/build/rules/rule/clause/changes.rb'
+ - 'lib/gitlab/ci/build/rules/rule/clause/exists.rb'
+ - 'lib/gitlab/ci/build/rules/rule/clause/if.rb'
+ - 'lib/gitlab/ci/config/entry/include/rules/rule.rb'
+ - 'lib/gitlab/ci/config/entry/rules/rule.rb'
+ - 'lib/gitlab/ci/mask_secret.rb'
+ - 'lib/gitlab/ci/warnings.rb'
+ - 'lib/gitlab/config_helper.rb'
+ - 'lib/gitlab/instrumentation/elasticsearch_transport.rb'
+ - 'lib/gitlab/serverless/service.rb'
+ - 'lib/gitlab/usage_data_counters/base_counter.rb'
+ - 'lib/gitlab/usage_data_counters/ci_template_unique_counter.rb'
+ - 'lib/gitlab/usage_data_counters/cycle_analytics_counter.rb'
+ - 'lib/gitlab/usage_data_counters/designs_counter.rb'
+ - 'lib/gitlab/usage_data_counters/note_counter.rb'
+ - 'lib/gitlab/usage_data_counters/productivity_analytics_counter.rb'
+ - 'lib/gitlab/usage_data_counters/service_usage_data_counter.rb'
+ - 'lib/gitlab/usage_data_counters/snippet_counter.rb'
+ - 'lib/gitlab/usage_data_counters/source_code_counter.rb'
+ - 'lib/gitlab/usage_data_counters/wiki_page_counter.rb'
+ - 'lib/release_highlights/validator/entry.rb'
+ - 'qa/qa/page/component/project/templates.rb'
+ - 'scripts/perf/gc/print_gc_stats.rb'
+ - 'spec/support/inspect_squelch.rb'
+ - 'spec/support/matchers/markdown_matchers.rb'
diff --git a/.rubocop_todo/style/empty_method.yml b/.rubocop_todo/style/empty_method.yml
new file mode 100644
index 00000000000..9bca01015aa
--- /dev/null
+++ b/.rubocop_todo/style/empty_method.yml
@@ -0,0 +1,196 @@
+---
+# Cop supports --auto-correct.
+Style/EmptyMethod:
+ # Offense count: 240
+ # Temporarily disabled due to too many offenses
+ Enabled: false
+ Exclude:
+ - 'app/controllers/admin/application_settings/appearances_controller.rb'
+ - 'app/controllers/admin/applications_controller.rb'
+ - 'app/controllers/admin/broadcast_messages_controller.rb'
+ - 'app/controllers/admin/deploy_keys_controller.rb'
+ - 'app/controllers/admin/hook_logs_controller.rb'
+ - 'app/controllers/admin/hooks_controller.rb'
+ - 'app/controllers/admin/identities_controller.rb'
+ - 'app/controllers/admin/labels_controller.rb'
+ - 'app/controllers/admin/runners_controller.rb'
+ - 'app/controllers/admin/topics_controller.rb'
+ - 'app/controllers/admin/usage_trends_controller.rb'
+ - 'app/controllers/admin/users_controller.rb'
+ - 'app/controllers/concerns/boards_actions.rb'
+ - 'app/controllers/groups/milestones_controller.rb'
+ - 'app/controllers/groups/runners_controller.rb'
+ - 'app/controllers/groups/settings/applications_controller.rb'
+ - 'app/controllers/groups/settings/ci_cd_controller.rb'
+ - 'app/controllers/groups/settings/packages_and_registries_controller.rb'
+ - 'app/controllers/help_controller.rb'
+ - 'app/controllers/import/bitbucket_server_controller.rb'
+ - 'app/controllers/import/fogbugz_controller.rb'
+ - 'app/controllers/import/manifest_controller.rb'
+ - 'app/controllers/import/phabricator_controller.rb'
+ - 'app/controllers/profiles/chat_names_controller.rb'
+ - 'app/controllers/profiles/passwords_controller.rb'
+ - 'app/controllers/profiles/preferences_controller.rb'
+ - 'app/controllers/profiles_controller.rb'
+ - 'app/controllers/projects/alert_management_controller.rb'
+ - 'app/controllers/projects/ci/lints_controller.rb'
+ - 'app/controllers/projects/ci/pipeline_editor_controller.rb'
+ - 'app/controllers/projects/ci/secure_files_controller.rb'
+ - 'app/controllers/projects/confluences_controller.rb'
+ - 'app/controllers/projects/deploy_keys_controller.rb'
+ - 'app/controllers/projects/environments_controller.rb'
+ - 'app/controllers/projects/feature_flags_controller.rb'
+ - 'app/controllers/projects/feature_flags_user_lists_controller.rb'
+ - 'app/controllers/projects/hook_logs_controller.rb'
+ - 'app/controllers/projects/import/jira_controller.rb'
+ - 'app/controllers/projects/imports_controller.rb'
+ - 'app/controllers/projects/incidents_controller.rb'
+ - 'app/controllers/projects/jobs_controller.rb'
+ - 'app/controllers/projects/labels_controller.rb'
+ - 'app/controllers/projects/learn_gitlab_controller.rb'
+ - 'app/controllers/projects/mattermosts_controller.rb'
+ - 'app/controllers/projects/pages_domains_controller.rb'
+ - 'app/controllers/projects/pipeline_schedules_controller.rb'
+ - 'app/controllers/projects/product_analytics_controller.rb'
+ - 'app/controllers/projects/runners_controller.rb'
+ - 'app/controllers/projects/services_controller.rb'
+ - 'app/controllers/projects/settings/packages_and_registries_controller.rb'
+ - 'app/controllers/projects/tags/releases_controller.rb'
+ - 'app/controllers/projects/terraform_controller.rb'
+ - 'app/controllers/projects/triggers_controller.rb'
+ - 'app/controllers/registrations/welcome_controller.rb'
+ - 'app/controllers/search_controller.rb'
+ - 'app/graphql/resolvers/concerns/caching_array_resolver.rb'
+ - 'app/helpers/namespace_storage_limit_alert_helper.rb'
+ - 'app/helpers/subscribable_banner_helper.rb'
+ - 'app/helpers/users/callouts_helper.rb'
+ - 'app/models/ci/bridge.rb'
+ - 'app/models/concerns/cross_database_modification.rb'
+ - 'app/models/concerns/reactive_caching.rb'
+ - 'app/models/concerns/relative_positioning.rb'
+ - 'app/models/hooks/web_hook.rb'
+ - 'app/models/integrations/hangouts_chat.rb'
+ - 'app/models/integrations/microsoft_teams.rb'
+ - 'app/models/integrations/unify_circuit.rb'
+ - 'app/models/integrations/webex_teams.rb'
+ - 'app/models/wiki.rb'
+ - 'app/services/auto_merge/base_service.rb'
+ - 'app/services/award_emojis/destroy_service.rb'
+ - 'app/services/issuable_base_service.rb'
+ - 'app/services/issues/reopen_service.rb'
+ - 'app/services/projects/transfer_service.rb'
+ - 'app/workers/authorized_projects_worker.rb'
+ - 'app/workers/namespaces/root_statistics_worker.rb'
+ - 'db/migrate/20210420012444_change_web_hook_events_default.rb'
+ - 'db/migrate/20210507191949_add_remove_on_issue_close_to_labels.rb'
+ - 'db/migrate/20210729123101_confirm_security_bot.rb'
+ - 'db/migrate/20211012134316_clean_up_migrate_merge_request_diff_commit_users.rb'
+ - 'db/post_migrate/20210511095658_schedule_migrate_project_taggings_context_from_tags_to_topics.rb'
+ - 'db/post_migrate/20210730170823_schedule_security_setting_creation.rb'
+ - 'db/post_migrate/20210823132600_remove_duplicate_dast_site_tokens.rb'
+ - 'db/post_migrate/20210826171758_initialize_throttle_unauthenticated_api_columns.rb'
+ - 'db/post_migrate/20211028100843_delete_issue_merge_request_taggings_records.rb'
+ - 'db/post_migrate/20220324032250_migrate_shimo_confluence_service_category.rb'
+ - 'db/post_migrate/20220412143552_consume_remaining_encrypt_integration_property_jobs.rb'
+ - 'db/post_migrate/20220425121435_backfill_integrations_enable_ssl_verification.rb'
+ - 'ee/app/controllers/admin/emails_controller.rb'
+ - 'ee/app/controllers/admin/geo/designs_controller.rb'
+ - 'ee/app/controllers/admin/geo/settings_controller.rb'
+ - 'ee/app/controllers/admin/push_rules_controller.rb'
+ - 'ee/app/controllers/groups/analytics/ci_cd_analytics_controller.rb'
+ - 'ee/app/controllers/groups/analytics/cycle_analytics_controller.rb'
+ - 'ee/app/controllers/groups/analytics/devops_adoption_controller.rb'
+ - 'ee/app/controllers/groups/compliance_frameworks_controller.rb'
+ - 'ee/app/controllers/groups/feature_discovery_moments_controller.rb'
+ - 'ee/app/controllers/groups/hooks_controller.rb'
+ - 'ee/app/controllers/groups/ldap_group_links_controller.rb'
+ - 'ee/app/controllers/groups/push_rules_controller.rb'
+ - 'ee/app/controllers/projects/analytics/code_reviews_controller.rb'
+ - 'ee/app/controllers/projects/analytics/merge_request_analytics_controller.rb'
+ - 'ee/app/controllers/projects/incident_management/escalation_policies_controller.rb'
+ - 'ee/app/controllers/projects/incident_management/oncall_schedules_controller.rb'
+ - 'ee/app/controllers/projects/on_demand_scans_controller.rb'
+ - 'ee/app/controllers/projects/security/api_fuzzing_configuration_controller.rb'
+ - 'ee/app/controllers/projects/security/corpus_management_controller.rb'
+ - 'ee/app/controllers/projects/security/dast_configuration_controller.rb'
+ - 'ee/app/controllers/projects/security/dast_profiles_controller.rb'
+ - 'ee/app/controllers/projects/security/dast_scanner_profiles_controller.rb'
+ - 'ee/app/controllers/projects/security/dast_site_profiles_controller.rb'
+ - 'ee/app/controllers/projects/security/sast_configuration_controller.rb'
+ - 'ee/app/controllers/projects/settings/slacks_controller.rb'
+ - 'ee/app/controllers/registrations/company_controller.rb'
+ - 'ee/app/controllers/registrations/verification_controller.rb'
+ - 'ee/app/controllers/subscriptions/groups_controller.rb'
+ - 'ee/app/controllers/trial_registrations_controller.rb'
+ - 'ee/app/controllers/trials_controller.rb'
+ - 'ee/app/experiments/cart_abandonment_modal_experiment.rb'
+ - 'ee/app/models/ee/epic.rb'
+ - 'ee/app/services/feature_flag_issues/destroy_service.rb'
+ - 'ee/db/geo/migrate/20170906174622_remove_duplicates_from_project_registry.rb'
+ - 'lib/api/helpers/packages/conan/api_helpers.rb'
+ - 'lib/api/helpers/projects_helpers.rb'
+ - 'lib/api/projects_relation_builder.rb'
+ - 'lib/backup/task.rb'
+ - 'lib/banzai/filter/inline_embeds_filter.rb'
+ - 'lib/feature.rb'
+ - 'lib/gitlab/alert_management/payload/base.rb'
+ - 'lib/gitlab/background_migration/backfill_iteration_cadence_id_for_boards.rb'
+ - 'lib/gitlab/background_migration/create_security_setting.rb'
+ - 'lib/gitlab/background_migration/drop_invalid_remediations.rb'
+ - 'lib/gitlab/background_migration/fix_incorrect_max_seats_used.rb'
+ - 'lib/gitlab/background_migration/migrate_approver_to_approval_rules.rb'
+ - 'lib/gitlab/background_migration/migrate_approver_to_approval_rules_check_progress.rb'
+ - 'lib/gitlab/background_migration/migrate_approver_to_approval_rules_in_batch.rb'
+ - 'lib/gitlab/background_migration/migrate_job_artifact_registry_to_ssf.rb'
+ - 'lib/gitlab/background_migration/migrate_requirements_to_work_items.rb'
+ - 'lib/gitlab/background_migration/recalculate_vulnerability_finding_signatures_for_findings.rb'
+ - 'lib/gitlab/background_migration/update_vulnerability_occurrences_location.rb'
+ - 'lib/gitlab/ci/config/entry/need.rb'
+ - 'lib/gitlab/ci/config/entry/rules/rule.rb'
+ - 'lib/gitlab/ci/limit.rb'
+ - 'lib/gitlab/ci/pipeline/chain/validate/after_config.rb'
+ - 'lib/gitlab/config/entry/node.rb'
+ - 'lib/gitlab/config/entry/simplifiable.rb'
+ - 'lib/gitlab/email/message/in_product_marketing/experience.rb'
+ - 'lib/gitlab/empty_search_results.rb'
+ - 'lib/gitlab/git_access.rb'
+ - 'lib/gitlab/import_export/json/ndjson_writer.rb'
+ - 'lib/gitlab/null_request_store.rb'
+ - 'lib/gitlab/usage_data_non_sql_metrics.rb'
+ - 'lib/mattermost/session.rb'
+ - 'qa/qa/resource/clusters/agent.rb'
+ - 'qa/qa/resource/clusters/agent_token.rb'
+ - 'qa/qa/resource/job.rb'
+ - 'qa/qa/resource/package.rb'
+ - 'qa/qa/resource/registry_repository.rb'
+ - 'qa/qa/resource/runner.rb'
+ - 'qa/qa/service/cluster_provider/k3d.rb'
+ - 'qa/qa/service/cluster_provider/k3s.rb'
+ - 'qa/qa/service/cluster_provider/minikube.rb'
+ - 'spec/controllers/concerns/check_rate_limit_spec.rb'
+ - 'spec/controllers/concerns/issuable_actions_spec.rb'
+ - 'spec/initializers/forbid_sidekiq_in_transactions_spec.rb'
+ - 'spec/lib/api/helpers/rate_limiter_spec.rb'
+ - 'spec/lib/gitlab/database/load_balancing/sidekiq_client_middleware_spec.rb'
+ - 'spec/lib/gitlab/database/load_balancing/sidekiq_server_middleware_spec.rb'
+ - 'spec/lib/gitlab/database/migration_helpers/restrict_gitlab_schema_spec.rb'
+ - 'spec/lib/gitlab/database/migrations/background_migration_helpers_spec.rb'
+ - 'spec/lib/gitlab/database/partitioning/sliding_list_strategy_spec.rb'
+ - 'spec/lib/gitlab/database/postgresql_adapter/dump_schema_versions_mixin_spec.rb'
+ - 'spec/lib/gitlab/database/postgresql_database_tasks/load_schema_versions_mixin_spec.rb'
+ - 'spec/lib/gitlab/git/rugged_impl/use_rugged_spec.rb'
+ - 'spec/lib/gitlab/repository_archive_rate_limiter_spec.rb'
+ - 'spec/lib/gitlab/repository_cache_adapter_spec.rb'
+ - 'spec/lib/gitlab/sidekiq_middleware/client_metrics_spec.rb'
+ - 'spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/client_spec.rb'
+ - 'spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/server_spec.rb'
+ - 'spec/lib/gitlab/sidekiq_middleware/instrumentation_logger_spec.rb'
+ - 'spec/lib/gitlab/sidekiq_middleware/query_analyzer_spec.rb'
+ - 'spec/lib/gitlab/sidekiq_middleware/server_metrics_spec.rb'
+ - 'spec/lib/gitlab/sidekiq_middleware/worker_context/client_spec.rb'
+ - 'spec/lib/gitlab/sidekiq_middleware/worker_context/server_spec.rb'
+ - 'spec/lib/gitlab/ssh_public_key_spec.rb'
+ - 'spec/lib/gitlab/utils/delegator_override/validator_spec.rb'
+ - 'spec/lib/gitlab/utils/delegator_override_spec.rb'
+ - 'spec/lib/gitlab/utils/override_spec.rb'
+ - 'spec/workers/concerns/waitable_worker_spec.rb'
diff --git a/app/assets/javascripts/api/integrations_api.js b/app/assets/javascripts/api/integrations_api.js
new file mode 100644
index 00000000000..692aae21a4f
--- /dev/null
+++ b/app/assets/javascripts/api/integrations_api.js
@@ -0,0 +1,21 @@
+import axios from '../lib/utils/axios_utils';
+import { buildApiUrl } from './api_utils';
+
+const JIRA_CONNECT_SUBSCRIPTIONS_PATH = '/api/:version/integrations/jira_connect/subscriptions';
+
+export function addJiraConnectSubscription(namespacePath, { jwt, accessToken }) {
+ const url = buildApiUrl(JIRA_CONNECT_SUBSCRIPTIONS_PATH);
+
+ return axios.post(
+ url,
+ {
+ jwt,
+ namespace_path: namespacePath,
+ },
+ {
+ headers: {
+ Authorization: `Bearer ${accessToken}`, // eslint-disable-line @gitlab/require-i18n-strings
+ },
+ },
+ );
+}
diff --git a/app/assets/javascripts/diffs/components/app.vue b/app/assets/javascripts/diffs/components/app.vue
index 2fc981f24b7..c3436159cea 100644
--- a/app/assets/javascripts/diffs/components/app.vue
+++ b/app/assets/javascripts/diffs/components/app.vue
@@ -371,7 +371,7 @@ export default {
events.push(TRACKING_MULTIPLE_FILES_MODE);
}
- queueRedisHllEvents(events);
+ queueRedisHllEvents(events, { verifyCap: true });
this.subscribeToVirtualScrollingEvents();
},
diff --git a/app/assets/javascripts/diffs/components/diff_file.vue b/app/assets/javascripts/diffs/components/diff_file.vue
index 289a6e605bd..0b82be7140c 100644
--- a/app/assets/javascripts/diffs/components/diff_file.vue
+++ b/app/assets/javascripts/diffs/components/diff_file.vue
@@ -379,6 +379,53 @@ export default {
:class="hasBodyClasses.contentByHash"
data-testid="content-area"
>
+ <gl-alert
+ v-if="!showLoadingIcon && file.conflict_type"
+ variant="danger"
+ :dismissible="false"
+ data-testid="conflictsAlert"
+ >
+ {{ $options.CONFLICT_TEXT[file.conflict_type] }}
+ <template v-if="!canMerge">
+ {{ __('Ask someone with write access to resolve it.') }}
+ </template>
+ <gl-sprintf
+ v-else-if="conflictResolutionPath"
+ :message="
+ __(
+ 'You can %{gitlabLinkStart}resolve conflicts on GitLab%{gitlabLinkEnd} or %{resolveLocallyStart}resolve it locally%{resolveLocallyEnd}.',
+ )
+ "
+ >
+ <template #gitlabLink="{ content }">
+ <gl-button
+ :href="conflictResolutionPath"
+ variant="link"
+ class="gl-vertical-align-text-bottom"
+ >{{ content }}</gl-button
+ >
+ </template>
+ <template #resolveLocally="{ content }">
+ <gl-button
+ variant="link"
+ class="gl-vertical-align-text-bottom js-check-out-modal-trigger"
+ >{{ content }}</gl-button
+ >
+ </template>
+ </gl-sprintf>
+ <gl-sprintf
+ v-else
+ :message="__('You can %{resolveLocallyStart}resolve it locally%{resolveLocallyEnd}.')"
+ >
+ <template #resolveLocally="{ content }">
+ <gl-button
+ variant="link"
+ class="gl-vertical-align-text-bottom js-check-out-modal-trigger"
+ >{{ content }}</gl-button
+ >
+ </template>
+ </gl-sprintf>
+ </gl-alert>
<gl-loading-icon
v-if="showLoadingIcon"
size="sm"
@@ -402,53 +449,6 @@ export default {
<div v-else v-safe-html="errorMessage" class="nothing-here-block"></div>
</div>
<template v-else>
- <gl-alert
- v-if="file.conflict_type"
- variant="danger"
- :dismissible="false"
- data-testid="conflictsAlert"
- >
- {{ $options.CONFLICT_TEXT[file.conflict_type] }}
- <template v-if="!canMerge">
- {{ __('Ask someone with write access to resolve it.') }}
- </template>
- <gl-sprintf
- v-else-if="conflictResolutionPath"
- :message="
- __(
- 'You can %{gitlabLinkStart}resolve conflicts on GitLab%{gitlabLinkEnd} or %{resolveLocallyStart}resolve it locally%{resolveLocallyEnd}.',
- )
- "
- >
- <template #gitlabLink="{ content }">
- <gl-button
- :href="conflictResolutionPath"
- variant="link"
- class="gl-vertical-align-text-bottom"
- >{{ content }}</gl-button
- >
- </template>
- <template #resolveLocally="{ content }">
- <gl-button
- variant="link"
- class="gl-vertical-align-text-bottom js-check-out-modal-trigger"
- >{{ content }}</gl-button
- >
- </template>
- </gl-sprintf>
- <gl-sprintf
- v-else
- :message="__('You can %{resolveLocallyStart}resolve it locally%{resolveLocallyEnd}.')"
- >
- <template #resolveLocally="{ content }">
- <gl-button
- variant="link"
- class="gl-vertical-align-text-bottom js-check-out-modal-trigger"
- >{{ content }}</gl-button
- >
- </template>
- </gl-sprintf>
- </gl-alert>
<div
v-if="showWarning"
class="collapsed-file-warning gl-p-7 gl-bg-orange-50 gl-text-center gl-rounded-bottom-left-base gl-rounded-bottom-right-base"
diff --git a/app/assets/javascripts/diffs/constants.js b/app/assets/javascripts/diffs/constants.js
index f4b6bd85b84..6c0c9c4e1d0 100644
--- a/app/assets/javascripts/diffs/constants.js
+++ b/app/assets/javascripts/diffs/constants.js
@@ -102,6 +102,8 @@ export const CONFLICT_MARKER_THEIR = 'conflict_marker_their';
// Tracking events
export const DEFER_DURATION = 750;
+export const TRACKING_CAP_KEY = 'code_review_events_dispatched';
+export const TRACKING_CAP_LENGTH = 86400000; // 24 hours
export const TRACKING_CLICK_DIFF_VIEW_SETTING = 'i_code_review_click_diff_view_setting';
export const TRACKING_DIFF_VIEW_INLINE = 'i_code_review_diff_view_inline';
diff --git a/app/assets/javascripts/diffs/utils/queue_events.js b/app/assets/javascripts/diffs/utils/queue_events.js
index 08fcc98d45f..cc7141df622 100644
--- a/app/assets/javascripts/diffs/utils/queue_events.js
+++ b/app/assets/javascripts/diffs/utils/queue_events.js
@@ -1,13 +1,31 @@
import { delay } from 'lodash';
import api from '~/api';
-import { DEFER_DURATION } from '../constants';
+import { DEFER_DURATION, TRACKING_CAP_KEY, TRACKING_CAP_LENGTH } from '../constants';
-function trackRedisHllUserEvent(event, deferDuration = 0) {
+function shouldDispatchEvent() {
+ const timestamp = parseInt(localStorage.getItem(TRACKING_CAP_KEY), 10);
+
+ if (Number.isNaN(timestamp)) {
+ return true;
+ }
+
+ return timestamp + TRACKING_CAP_LENGTH < Date.now();
+}
+
+export function dispatchRedisHllUserEvent(event, deferDuration = 0) {
delay(() => api.trackRedisHllUserEvent(event), deferDuration);
}
-export function queueRedisHllEvents(events) {
+export function queueRedisHllEvents(events, { verifyCap = false } = {}) {
+ if (verifyCap) {
+ if (!shouldDispatchEvent()) {
+ return;
+ }
+
+ localStorage.setItem(TRACKING_CAP_KEY, Date.now());
+ }
+
events.forEach((event, index) => {
- trackRedisHllUserEvent(event, DEFER_DURATION * (index + 1));
+ dispatchRedisHllUserEvent(event, DEFER_DURATION * (index + 1));
});
}
diff --git a/app/assets/javascripts/jira_connect/subscriptions/components/add_namespace_modal/groups_list_item.vue b/app/assets/javascripts/jira_connect/subscriptions/components/add_namespace_modal/groups_list_item.vue
index d77fd5652b2..fa1c2e1912c 100644
--- a/app/assets/javascripts/jira_connect/subscriptions/components/add_namespace_modal/groups_list_item.vue
+++ b/app/assets/javascripts/jira_connect/subscriptions/components/add_namespace_modal/groups_list_item.vue
@@ -1,20 +1,30 @@
<script>
+import { mapActions } from 'vuex';
import { GlButton } from '@gitlab/ui';
-import { helpPagePath } from '~/helpers/help_page_helper';
import { addSubscription } from '~/jira_connect/subscriptions/api';
import { persistAlert, reloadPage } from '~/jira_connect/subscriptions/utils';
-import { s__ } from '~/locale';
+import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import GroupItemName from '../group_item_name.vue';
+import {
+ INTEGRATIONS_DOC_LINK,
+ I18N_ADD_SUBSCRIPTION_SUCCESS_ALERT_TITLE,
+ I18N_ADD_SUBSCRIPTION_SUCCESS_ALERT_MESSAGE,
+ I18N_ADD_SUBSCRIPTIONS_ERROR_MESSAGE,
+} from '../../constants';
export default {
components: {
GlButton,
GroupItemName,
},
+ mixins: [glFeatureFlagMixin()],
inject: {
addSubscriptionsPath: {
default: '',
},
+ subscriptionsPath: {
+ default: '',
+ },
},
props: {
group: {
@@ -32,31 +42,41 @@ export default {
isLoading: false,
};
},
+ computed: {
+ oauthEnabled() {
+ return this.glFeatures.jiraConnectOauth;
+ },
+ },
methods: {
- onClick() {
+ ...mapActions(['addSubscription']),
+ async onClick() {
+ if (this.oauthEnabled) {
+ this.isLoading = true;
+ await this.addSubscription({
+ namespacePath: this.group.full_path,
+ subscriptionsPath: this.subscriptionsPath,
+ });
+ this.isLoading = false;
+ } else {
+ this.deprecatedAddSubscription();
+ }
+ },
+ deprecatedAddSubscription() {
this.isLoading = true;
addSubscription(this.addSubscriptionsPath, this.group.full_path)
.then(() => {
persistAlert({
- title: s__('Integrations|Namespace successfully linked'),
- message: s__(
- 'Integrations|You should now see GitLab.com activity inside your Jira Cloud issues. %{linkStart}Learn more%{linkEnd}',
- ),
- linkUrl: helpPagePath('integration/jira_development_panel.html', {
- anchor: 'use-the-integration',
- }),
+ title: I18N_ADD_SUBSCRIPTION_SUCCESS_ALERT_TITLE,
+ message: I18N_ADD_SUBSCRIPTION_SUCCESS_ALERT_MESSAGE,
+ linkUrl: INTEGRATIONS_DOC_LINK,
variant: 'success',
});
reloadPage();
})
.catch((error) => {
- this.$emit(
- 'error',
- error?.response?.data?.error ||
- s__('Integrations|Failed to link namespace. Please try again.'),
- );
+ this.$emit('error', error?.response?.data?.error || I18N_ADD_SUBSCRIPTIONS_ERROR_MESSAGE);
this.isLoading = false;
});
},
diff --git a/app/assets/javascripts/jira_connect/subscriptions/components/app.vue b/app/assets/javascripts/jira_connect/subscriptions/components/app.vue
index f8e0a406c6f..22422872183 100644
--- a/app/assets/javascripts/jira_connect/subscriptions/components/app.vue
+++ b/app/assets/javascripts/jira_connect/subscriptions/components/app.vue
@@ -34,12 +34,8 @@ export default {
default: '',
},
},
- data() {
- return {
- user: null,
- };
- },
computed: {
+ ...mapState(['currentUser']),
...mapState(['alert', 'subscriptions']),
shouldShowAlert() {
return Boolean(this.alert?.message);
@@ -48,7 +44,11 @@ export default {
return !isEmpty(this.subscriptions);
},
userSignedIn() {
- return Boolean(!this.usersPath || this.user);
+ if (this.isOauthEnabled) {
+ return Boolean(this.currentUser);
+ }
+
+ return Boolean(!this.usersPath);
},
isOauthEnabled() {
return this.glFeatures.jiraConnectOauth;
@@ -85,8 +85,7 @@ export default {
const { linkUrl, title, message, variant } = retrieveAlert() || {};
this.setAlert({ linkUrl, title, message, variant });
},
- onSignInOauth(user) {
- this.user = user;
+ onSignInOauth() {
this.fetchSubscriptionsOauth();
},
onSignInError() {
@@ -123,7 +122,11 @@ export default {
</template>
</gl-alert>
- <user-link :user-signed-in="userSignedIn" :has-subscriptions="hasSubscriptions" :user="user" />
+ <user-link
+ :user-signed-in="userSignedIn"
+ :has-subscriptions="hasSubscriptions"
+ :user="currentUser"
+ />
<div class="gl-layout-w-limited gl-mx-auto gl-px-5 gl-mb-7">
<sign-in-page
diff --git a/app/assets/javascripts/jira_connect/subscriptions/components/sign_in_oauth_button.vue b/app/assets/javascripts/jira_connect/subscriptions/components/sign_in_oauth_button.vue
index 3ee243aad47..b9e8bab019f 100644
--- a/app/assets/javascripts/jira_connect/subscriptions/components/sign_in_oauth_button.vue
+++ b/app/assets/javascripts/jira_connect/subscriptions/components/sign_in_oauth_button.vue
@@ -1,4 +1,5 @@
<script>
+import { mapActions, mapMutations } from 'vuex';
import { GlButton } from '@gitlab/ui';
import axios from '~/lib/utils/axios_utils';
import {
@@ -8,8 +9,8 @@ import {
} from '~/jira_connect/subscriptions/constants';
import { setUrlParams } from '~/lib/utils/url_utility';
import AccessorUtilities from '~/lib/utils/accessor';
-import { getCurrentUser } from '~/rest_api';
import { createCodeVerifier, createCodeChallenge } from '../pkce';
+import { SET_ACCESS_TOKEN } from '../store/mutation_types';
export default {
components: {
@@ -31,6 +32,10 @@ export default {
window.removeEventListener('message', this.handleWindowMessage);
},
methods: {
+ ...mapActions(['loadCurrentUser']),
+ ...mapMutations({
+ setAccessToken: SET_ACCESS_TOKEN,
+ }),
async startOAuthFlow() {
this.loading = true;
@@ -58,7 +63,6 @@ export default {
async handleWindowMessage(event) {
if (window.origin !== event.origin) {
this.loading = false;
- this.handleError();
return;
}
@@ -74,8 +78,10 @@ export default {
const code = event.data?.code;
try {
const accessToken = await this.getOAuthToken(code);
+ await this.loadCurrentUser(accessToken);
- await this.loadUser(accessToken);
+ this.setAccessToken(accessToken);
+ this.$emit('sign-in');
} catch (e) {
this.handleError();
} finally {
@@ -98,13 +104,6 @@ export default {
return data.access_token;
},
- async loadUser(accessToken) {
- const { data } = await getCurrentUser({
- headers: { Authorization: `Bearer ${accessToken}` },
- });
-
- this.$emit('sign-in', data);
- },
},
i18n: {
defaultButtonText: I18N_DEFAULT_SIGN_IN_BUTTON_TEXT,
diff --git a/app/assets/javascripts/jira_connect/subscriptions/constants.js b/app/assets/javascripts/jira_connect/subscriptions/constants.js
index df3cf5b1381..8faafb1b0d0 100644
--- a/app/assets/javascripts/jira_connect/subscriptions/constants.js
+++ b/app/assets/javascripts/jira_connect/subscriptions/constants.js
@@ -1,4 +1,5 @@
import { s__ } from '~/locale';
+import { helpPagePath } from '~/helpers/help_page_helper';
export const DEFAULT_GROUPS_PER_PAGE = 10;
export const ALERT_LOCALSTORAGE_KEY = 'gitlab_alert';
@@ -11,6 +12,19 @@ export const I18N_DEFAULT_SIGN_IN_ERROR_MESSAGE = s__('Integrations|Failed to si
export const I18N_DEFAULT_SUBSCRIPTIONS_ERROR_MESSAGE = s__(
'Integrations|Failed to load subscriptions.',
);
+export const I18N_ADD_SUBSCRIPTION_SUCCESS_ALERT_TITLE = s__(
+ 'Integrations|Namespace successfully linked',
+);
+export const I18N_ADD_SUBSCRIPTION_SUCCESS_ALERT_MESSAGE = s__(
+ 'Integrations|You should now see GitLab.com activity inside your Jira Cloud issues. %{linkStart}Learn more%{linkEnd}',
+);
+export const INTEGRATIONS_DOC_LINK = helpPagePath('integration/jira_development_panel', {
+ anchor: 'use-the-integration',
+});
+
+export const I18N_ADD_SUBSCRIPTIONS_ERROR_MESSAGE = s__(
+ 'Integrations|Failed to link namespace. Please try again.',
+);
const OAUTH_WINDOW_SIZE = 800;
export const OAUTH_WINDOW_OPTIONS = [
diff --git a/app/assets/javascripts/jira_connect/subscriptions/pages/sign_in/sign_in_page.vue b/app/assets/javascripts/jira_connect/subscriptions/pages/sign_in/sign_in_page.vue
index 555f095f496..f4c59b2184e 100644
--- a/app/assets/javascripts/jira_connect/subscriptions/pages/sign_in/sign_in_page.vue
+++ b/app/assets/javascripts/jira_connect/subscriptions/pages/sign_in/sign_in_page.vue
@@ -29,7 +29,7 @@ export default {
<sign-in-gitlab-com
v-else
:has-subscriptions="hasSubscriptions"
- @sign-in-oauth="$emit('sign-in-oauth', $event)"
+ @sign-in-oauth="$emit('sign-in-oauth')"
@error="$emit('error', $event)"
/>
</template>
diff --git a/app/assets/javascripts/jira_connect/subscriptions/store/actions.js b/app/assets/javascripts/jira_connect/subscriptions/store/actions.js
index 44241535e76..4a83ee8671d 100644
--- a/app/assets/javascripts/jira_connect/subscriptions/store/actions.js
+++ b/app/assets/javascripts/jira_connect/subscriptions/store/actions.js
@@ -1,10 +1,22 @@
import { fetchSubscriptions as fetchSubscriptionsREST } from '~/jira_connect/subscriptions/api';
-import { I18N_DEFAULT_SUBSCRIPTIONS_ERROR_MESSAGE } from '../constants';
+import { getCurrentUser } from '~/rest_api';
+import { addJiraConnectSubscription } from '~/api/integrations_api';
+import {
+ I18N_ADD_SUBSCRIPTION_SUCCESS_ALERT_TITLE,
+ I18N_ADD_SUBSCRIPTION_SUCCESS_ALERT_MESSAGE,
+ INTEGRATIONS_DOC_LINK,
+ I18N_DEFAULT_SUBSCRIPTIONS_ERROR_MESSAGE,
+} from '../constants';
+import { getJwt } from '../utils';
import {
SET_SUBSCRIPTIONS,
SET_SUBSCRIPTIONS_LOADING,
SET_SUBSCRIPTIONS_ERROR,
+ ADD_SUBSCRIPTION_LOADING,
+ ADD_SUBSCRIPTION_ERROR,
SET_ALERT,
+ SET_CURRENT_USER,
+ SET_CURRENT_USER_ERROR,
} from './mutation_types';
export const fetchSubscriptions = async ({ commit }, subscriptionsPath) => {
@@ -20,3 +32,42 @@ export const fetchSubscriptions = async ({ commit }, subscriptionsPath) => {
commit(SET_SUBSCRIPTIONS_LOADING, false);
}
};
+
+export const loadCurrentUser = async ({ commit }, accessToken) => {
+ try {
+ const { data: user } = await getCurrentUser({
+ headers: { Authorization: `Bearer ${accessToken}` },
+ });
+
+ commit(SET_CURRENT_USER, user);
+ } catch (e) {
+ commit(SET_CURRENT_USER_ERROR, e);
+ }
+};
+
+export const addSubscription = async (
+ { commit, state, dispatch },
+ { namespacePath, subscriptionsPath },
+) => {
+ try {
+ commit(ADD_SUBSCRIPTION_LOADING, true);
+
+ await addJiraConnectSubscription(namespacePath, {
+ jwt: await getJwt(),
+ accessToken: state.accessToken,
+ });
+
+ commit(SET_ALERT, {
+ title: I18N_ADD_SUBSCRIPTION_SUCCESS_ALERT_TITLE,
+ message: I18N_ADD_SUBSCRIPTION_SUCCESS_ALERT_MESSAGE,
+ linkUrl: INTEGRATIONS_DOC_LINK,
+ variant: 'success',
+ });
+
+ dispatch('fetchSubscriptions', subscriptionsPath);
+ } catch (e) {
+ commit(ADD_SUBSCRIPTION_ERROR, e);
+ } finally {
+ commit(ADD_SUBSCRIPTION_LOADING, false);
+ }
+};
diff --git a/app/assets/javascripts/jira_connect/subscriptions/store/mutation_types.js b/app/assets/javascripts/jira_connect/subscriptions/store/mutation_types.js
index f954c22c906..d4893fbcaf6 100644
--- a/app/assets/javascripts/jira_connect/subscriptions/store/mutation_types.js
+++ b/app/assets/javascripts/jira_connect/subscriptions/store/mutation_types.js
@@ -1,4 +1,13 @@
export const SET_ALERT = 'SET_ALERT';
+
export const SET_SUBSCRIPTIONS = 'SET_SUBSCRIPTIONS';
export const SET_SUBSCRIPTIONS_LOADING = 'SET_SUBSCRIPTIONS_LOADING';
export const SET_SUBSCRIPTIONS_ERROR = 'SET_SUBSCRIPTIONS_ERROR';
+
+export const ADD_SUBSCRIPTION_LOADING = 'ADD_SUBSCRIPTION_LOADING';
+export const ADD_SUBSCRIPTION_ERROR = 'ADD_SUBSCRIPTION_ERROR';
+
+export const SET_CURRENT_USER = 'SET_CURRENT_USER';
+export const SET_CURRENT_USER_ERROR = 'SET_CURRENT_USER_ERROR';
+
+export const SET_ACCESS_TOKEN = 'SET_ACCESS_TOKEN';
diff --git a/app/assets/javascripts/jira_connect/subscriptions/store/mutations.js b/app/assets/javascripts/jira_connect/subscriptions/store/mutations.js
index d5c4864243b..60076c918fd 100644
--- a/app/assets/javascripts/jira_connect/subscriptions/store/mutations.js
+++ b/app/assets/javascripts/jira_connect/subscriptions/store/mutations.js
@@ -3,12 +3,18 @@ import {
SET_SUBSCRIPTIONS,
SET_SUBSCRIPTIONS_LOADING,
SET_SUBSCRIPTIONS_ERROR,
+ ADD_SUBSCRIPTION_LOADING,
+ ADD_SUBSCRIPTION_ERROR,
+ SET_CURRENT_USER,
+ SET_CURRENT_USER_ERROR,
+ SET_ACCESS_TOKEN,
} from './mutation_types';
export default {
[SET_ALERT](state, { title, message, variant, linkUrl } = {}) {
state.alert = { title, message, variant, linkUrl };
},
+
[SET_SUBSCRIPTIONS](state, subscriptions = []) {
state.subscriptions = subscriptions;
},
@@ -18,4 +24,22 @@ export default {
[SET_SUBSCRIPTIONS_ERROR](state, subscriptionsError) {
state.subscriptionsError = subscriptionsError;
},
+
+ [ADD_SUBSCRIPTION_LOADING](state, loading) {
+ state.addSubscriptionLoading = loading;
+ },
+ [ADD_SUBSCRIPTION_ERROR](state, error) {
+ state.addSubscriptionError = error;
+ },
+
+ [SET_CURRENT_USER](state, currentUser) {
+ state.currentUser = currentUser;
+ },
+ [SET_CURRENT_USER_ERROR](state, currentUserError) {
+ state.currentUserError = currentUserError;
+ },
+
+ [SET_ACCESS_TOKEN](state, accessToken) {
+ state.accessToken = accessToken;
+ },
};
diff --git a/app/assets/javascripts/jira_connect/subscriptions/store/state.js b/app/assets/javascripts/jira_connect/subscriptions/store/state.js
index 2243e70afb1..03a83f18b4c 100644
--- a/app/assets/javascripts/jira_connect/subscriptions/store/state.js
+++ b/app/assets/javascripts/jira_connect/subscriptions/store/state.js
@@ -1,8 +1,17 @@
export default function createState({ subscriptions = [], subscriptionsLoading = false } = {}) {
return {
alert: undefined,
+
subscriptions,
subscriptionsLoading,
subscriptionsError: false,
+
+ addSubscriptionLoading: false,
+ addSubscriptionError: false,
+
+ currentUser: null,
+ currentUserError: null,
+
+ accessToken: null,
};
}
diff --git a/app/assets/javascripts/notes/components/discussion_counter.vue b/app/assets/javascripts/notes/components/discussion_counter.vue
index 717ebcbe993..f746f7ed0ed 100644
--- a/app/assets/javascripts/notes/components/discussion_counter.vue
+++ b/app/assets/javascripts/notes/components/discussion_counter.vue
@@ -60,15 +60,15 @@ export default {
<div
class="gl-display-flex gl-align-items-center gl-pl-4 gl-rounded-base gl-mr-3"
:class="{
- 'gl-bg-orange-50': blocksMerge,
- 'gl-bg-gray-50': !blocksMerge,
+ 'gl-bg-orange-50': blocksMerge && !allResolved,
+ 'gl-bg-gray-50': !blocksMerge || allResolved,
'gl-pr-4': allResolved,
'gl-pr-2': !allResolved,
}"
data-testid="discussions-counter-text"
>
<template v-if="allResolved">
- {{ __('All threads resolved') }}
+ {{ __('All threads resolved!') }}
</template>
<template v-else>
{{ n__('%d unresolved thread', '%d unresolved threads', unresolvedDiscussionsCount) }}
diff --git a/app/assets/stylesheets/page_bundles/jira_connect.scss b/app/assets/stylesheets/page_bundles/jira_connect.scss
index e898e70ce15..f153569f99b 100644
--- a/app/assets/stylesheets/page_bundles/jira_connect.scss
+++ b/app/assets/stylesheets/page_bundles/jira_connect.scss
@@ -44,9 +44,3 @@ $header-height: 40px;
height: calc(100% - #{$header-height});
max-width: 1000px;
}
-
-// needed for external_link
-svg.s16 {
- width: 16px;
- height: 16px;
-}
diff --git a/app/graphql/types/concerns/gitlab_style_deprecations.rb b/app/graphql/types/concerns/gitlab_style_deprecations.rb
index 802562ed958..cd8e393b235 100644
--- a/app/graphql/types/concerns/gitlab_style_deprecations.rb
+++ b/app/graphql/types/concerns/gitlab_style_deprecations.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
# Concern for handling deprecation arguments.
-# https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#deprecating-fields-and-enum-values
+# https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#deprecating-schema-items
module GitlabStyleDeprecations
extend ActiveSupport::Concern
@@ -11,7 +11,7 @@ module GitlabStyleDeprecations
def gitlab_deprecation(kwargs)
if kwargs[:deprecation_reason].present?
raise ArgumentError, 'Use `deprecated` property instead of `deprecation_reason`. ' \
- 'See https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#deprecating-fields-arguments-and-enum-values'
+ 'See https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#deprecating-schema-items'
end
deprecation = ::Gitlab::Graphql::Deprecation.parse(kwargs.delete(:deprecated))
diff --git a/app/helpers/namespaces_helper.rb b/app/helpers/namespaces_helper.rb
index 8914c974f6c..a50629b7996 100644
--- a/app/helpers/namespaces_helper.rb
+++ b/app/helpers/namespaces_helper.rb
@@ -88,7 +88,7 @@ module NamespacesHelper
}.to_json
end
- def pipeline_usage_quota_app_data(namespace)
+ def pipeline_usage_app_data(namespace)
{
namespace_actual_plan_name: namespace.actual_plan_name,
namespace_path: namespace.full_path,
diff --git a/app/views/jira_connect/users/show.html.haml b/app/views/jira_connect/users/show.html.haml
index 29805a2c42d..569c4587f14 100644
--- a/app/views/jira_connect/users/show.html.haml
+++ b/app/views/jira_connect/users/show.html.haml
@@ -11,7 +11,7 @@
= s_('JiraService|You can now close this window and%{br}return to the GitLab for Jira application.').html_safe % { br: '<br>'.html_safe }
- if @jira_app_link
- %p= external_link s_('Integrations|Return to GitLab for Jira'), @jira_app_link, class: 'gl-button btn btn-confirm'
+ %p= link_to s_('Integrations|Return to GitLab for Jira'), @jira_app_link, class: 'gl-button btn btn-confirm'
%p= link_to _('Sign out'), destroy_user_session_path, method: :post
diff --git a/app/views/projects/merge_requests/_mr_title.html.haml b/app/views/projects/merge_requests/_mr_title.html.haml
index 81f413f5143..70b0a7dc650 100644
--- a/app/views/projects/merge_requests/_mr_title.html.haml
+++ b/app/views/projects/merge_requests/_mr_title.html.haml
@@ -31,11 +31,11 @@
= sprite_icon('chevron-double-lg-left')
.detail-page-header-actions.js-issuable-actions{ class: "#{'gl-align-self-start is-merge-request' if updated_mr_header_enabled}" }
- - if @merge_request.source_project
- = render 'projects/merge_requests/code_dropdown'
-
- if can_update_merge_request
= link_to _('Edit'), edit_project_merge_request_path(@project, @merge_request), class: "gl-display-none gl-md-display-block btn gl-button btn-default btn-grouped js-issuable-edit", data: { qa_selector: "edit_button" }
+ - if @merge_request.source_project
+ = render 'projects/merge_requests/code_dropdown'
+
- if current_user
= render 'projects/merge_requests/close_reopen_draft_report_toggle'
diff --git a/app/views/projects/tags/_tag.html.haml b/app/views/projects/tags/_tag.html.haml
index cac4a771d51..0ee3b89b629 100644
--- a/app/views/projects/tags/_tag.html.haml
+++ b/app/views/projects/tags/_tag.html.haml
@@ -21,7 +21,7 @@
.text-secondary
= sprite_icon("rocket", size: 12)
= _("Release")
- = link_to release.name, project_release_path(@project, release.tag), class: 'gl-text-blue-600!'
+ = link_to release.name, project_releases_path(@project, anchor: release.tag), class: 'gl-text-blue-600!'
- if tag.message.present?
%pre.wrap
diff --git a/config/feature_categories.yml b/config/feature_categories.yml
index 1749ce63016..473cf240864 100644
--- a/config/feature_categories.yml
+++ b/config/feature_categories.yml
@@ -33,6 +33,7 @@
- credential_management
- database
- dataops
+- dedicated
- delivery
- dependency_firewall
- dependency_proxy
@@ -52,7 +53,6 @@
- experimentation_conversion
- experimentation_expansion
- feature_flags
-- free_user_caps_conversion
- five_minute_production_app
- fulfillment_platform
- fuzz_testing
@@ -62,7 +62,6 @@
- gitlab_docs
- global_search
- helm_chart_registry
-- horse
- importers
- incident_management
- infrastructure_as_code
@@ -101,6 +100,7 @@
- redis
- release_evidence
- release_orchestration
+- remote_development
- requirements_management
- review_apps
- runbooks
diff --git a/config/feature_flags/development/delayed_project_import_schedule_worker.yml b/config/feature_flags/development/delayed_project_import_schedule_worker.yml
new file mode 100644
index 00000000000..cdf42fbb8ec
--- /dev/null
+++ b/config/feature_flags/development/delayed_project_import_schedule_worker.yml
@@ -0,0 +1,8 @@
+---
+name: delayed_project_import_schedule_worker
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/87438
+rollout_issue_url: https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/1681
+milestone: '15.0'
+type: development
+group: group::scalability
+default_enabled: false
diff --git a/data/removals/15_0/15-0-tracing.yml b/data/removals/15_0/15-0-tracing.yml
new file mode 100644
index 00000000000..b2ad2e525c0
--- /dev/null
+++ b/data/removals/15_0/15-0-tracing.yml
@@ -0,0 +1,16 @@
+- name: "Jaeger integration removed in GitLab 15.0" # The headline announcing the removal. i.e. "`CI_PROJECT_CONFIG_PATH` removed in Gitlab 14.0"
+ announcement_milestone: "14.7" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2022-01-22"
+ removal_milestone: "15.0" # The milestone when this feature is being removed.
+ removal_date: "2022-05-22" # This should almost always be the 22nd of a month (YYYY-MM-DD), the date of the milestone release when this feature will be removed.
+ breaking_change: true # Change to true if this removal is a breaking change.
+ reporter: kbychu # GitLab username of the person reporting the removal
+ body: | # Do not modify this line, instead modify the lines below.
+ Tracing in GitLab is an integration with Jaeger, an open-source end-to-end distributed tracing system. GitLab users could previously navigate to their Jaeger instance to gain insight into the performance of a deployed application, tracking each function or microservice that handles a given request. Tracing in GitLab was deprecated in GitLab 14.7, and removed in 15.0. To track work on a possible replacement, see the issue for [Opstrace integration with GitLab](https://gitlab.com/groups/gitlab-org/-/epics/6976).
+# The following items are not published on the docs page, but may be used in the future.
+ stage: Monitor # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
+ tiers: [Free] # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/346540 # (optional) This is a link to the deprecation issue in GitLab
+ documentation_url: https://docs.gitlab.com/ee/operations/tracing.html # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/doc/ci/yaml/index.md b/doc/ci/yaml/index.md
index 5313b575272..3bf76676aeb 100644
--- a/doc/ci/yaml/index.md
+++ b/doc/ci/yaml/index.md
@@ -561,7 +561,7 @@ This same warning is displayed when:
The default value for `allow_failure` is:
- `true` for [manual jobs](../jobs/job_control.md#create-a-job-that-must-be-run-manually).
-- `false` for manual jobs that also use [`rules`](#rules).
+- `false` for jobs that use `when: manual` inside [`rules`](#rules).
- `false` in all other cases.
**Keyword type**: Job keyword. You can use it only as part of a job.
diff --git a/doc/development/api_graphql_styleguide.md b/doc/development/api_graphql_styleguide.md
index 4f27e811b11..be56a187022 100644
--- a/doc/development/api_graphql_styleguide.md
+++ b/doc/development/api_graphql_styleguide.md
@@ -97,7 +97,7 @@ discussed in [Nullable fields](#nullable-fields).
Fields that use the [`feature_flag` property](#feature_flag-property) and the flag is disabled by default are exempt
from the deprecation process, and can be removed at any time without notice.
-See the [deprecating fields, arguments, and enum values](#deprecating-fields-arguments-and-enum-values) section for how to deprecate items.
+See the [deprecating schema items](#deprecating-schema-items) section for how to deprecate items.
## Global IDs
@@ -540,18 +540,18 @@ def foo
end
```
-## Deprecating fields, arguments, and enum values
+## Deprecating schema items
The GitLab GraphQL API is versionless, which means we maintain backwards
compatibility with older versions of the API with every change.
-Rather than removing fields, arguments, or [enum values](#enums), they
-must be _deprecated_ instead.
+Rather than removing fields, arguments, [enum values](#enums), or [mutations](#mutations),
+they must be _deprecated_ instead.
The deprecated parts of the schema can then be removed in a future release
in accordance with the [GitLab deprecation process](../api/graphql/index.md#deprecation-and-removal-process).
-Fields, arguments, and enum values are deprecated using the `deprecated` property.
+Fields, arguments, enum values, and mutations are deprecated using the `deprecated` property.
The value of the property is a `Hash` of:
- `reason` - Reason for the deprecation.
@@ -748,7 +748,7 @@ end
```
Enum values can be deprecated using the
-[`deprecated` keyword](#deprecating-fields-arguments-and-enum-values).
+[`deprecated` keyword](#deprecating-schema-items).
### Defining GraphQL enums dynamically from Rails enums
@@ -1713,7 +1713,7 @@ mount_aliased_mutation 'BarMutation', Mutations::FooMutation
```
This allows us to rename a mutation and continue to support the old name,
-when coupled with the [`deprecated`](#deprecating-fields-arguments-and-enum-values)
+when coupled with the [`deprecated`](#deprecating-schema-items)
argument.
Example:
diff --git a/doc/development/documentation/versions.md b/doc/development/documentation/versions.md
index 106567e6d3f..6c404fdbfb1 100644
--- a/doc/development/documentation/versions.md
+++ b/doc/development/documentation/versions.md
@@ -85,7 +85,7 @@ voters to agree.
When features are deprecated and removed, update the related documentation.
API documentation follows these guidelines, but the GraphQL docs use
-a [separate process](../api_graphql_styleguide.md#deprecating-fields-arguments-and-enum-values).
+a [separate process](../api_graphql_styleguide.md#deprecating-schema-items).
### Deprecate a page or topic
diff --git a/doc/install/requirements.md b/doc/install/requirements.md
index 8006b886414..b2899063cb4 100644
--- a/doc/install/requirements.md
+++ b/doc/install/requirements.md
@@ -132,7 +132,7 @@ GitLab database. [Read more about this requirement, and troubleshooting](postgre
| `plpgsql` | 11.7 |
NOTE:
-Support for [PostgreSQL 9.6 and 10 was removed in GitLab 13.0](https://about.gitlab.com/releases/2020/05/22/gitlab-13-0-released/#postgresql-11-is-now-the-minimum-required-version-to-install-gitlab) so that GitLab can benefit from PostgreSQL 11 improvements, such as partitioning. For the schedule of transitioning to PostgreSQL 12, see [the related epic](https://gitlab.com/groups/gitlab-org/-/epics/2184).
+Support for [PostgreSQL 9.6 and 10 was removed in GitLab 13.0](https://about.gitlab.com/releases/2020/05/22/gitlab-13-0-released/#postgresql-11-is-now-the-minimum-required-version-to-install-gitlab) so that GitLab can benefit from PostgreSQL 11 improvements, such as partitioning.
#### Additional requirements for GitLab Geo
diff --git a/doc/raketasks/backup_restore.md b/doc/raketasks/backup_restore.md
index 4befb9f62d4..7ff03989c61 100644
--- a/doc/raketasks/backup_restore.md
+++ b/doc/raketasks/backup_restore.md
@@ -405,6 +405,27 @@ Incremental backups can also be created from [an untarred backup](#skipping-tar-
sudo gitlab-backup create INCREMENTAL=yes SKIP=tar
```
+#### Back up specific repository storages
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/86896) in GitLab 15.0.
+
+When using [multiple repository storages](../administration/repository_storage_paths.md),
+repositories from specific repository storages can be backed up separately
+using the `REPOSITORIES_STORAGES` option. The option accepts a comma-separated list of
+storage names.
+
+For example, for Omnibus GitLab installations:
+
+```shell
+sudo gitlab-backup create REPOSITORIES_STORAGES=storage1,storage2
+```
+
+For example, for installations from source:
+
+```shell
+sudo -u git -H bundle exec rake gitlab:backup:create REPOSITORIES_STORAGES=storage1,storage2
+```
+
#### Uploading backups to a remote (cloud) storage
You can let the backup script upload (using the [Fog library](http://fog.io/))
@@ -1217,6 +1238,27 @@ For installations from source:
sudo -u git -H bundle exec rake gitlab:backup:restore BACKUP=timestamp_of_backup SKIP=db,uploads RAILS_ENV=production
```
+#### Restore specific repository storages
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/86896) in GitLab 15.0.
+
+When using [multiple repository storages](../administration/repository_storage_paths.md),
+repositories from specific repository storages can be restored separately
+using the `REPOSITORIES_STORAGES` option. The option accepts a comma-separated list of
+storage names.
+
+For example, for Omnibus GitLab installations:
+
+```shell
+sudo gitlab-backup restore BACKUP=timestamp_of_backup REPOSITORIES_STORAGES=storage1,storage2
+```
+
+For example, for installations from source:
+
+```shell
+sudo -u git -H bundle exec rake gitlab:backup:restore BACKUP=timestamp_of_backup REPOSITORIES_STORAGES=storage1,storage2
+```
+
## Alternative backup strategies
If your GitLab instance contains a lot of Git repository data, you may find the
diff --git a/doc/update/removals.md b/doc/update/removals.md
index 507adcb3233..50cbe9d707f 100644
--- a/doc/update/removals.md
+++ b/doc/update/removals.md
@@ -233,6 +233,16 @@ The permissions model for GraphQL is being updated. After 15.0, users with the G
The issue for this removal is [GitLab-#350682](https://gitlab.com/gitlab-org/gitlab/-/issues/350682)
+### Jaeger integration removed in GitLab 15.0
+
+WARNING:
+This feature was changed or removed in 15.0
+as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#breaking-changes).
+Before updating GitLab, review the details carefully to determine if you need to make any
+changes to your code, settings, or workflow.
+
+Tracing in GitLab is an integration with Jaeger, an open-source end-to-end distributed tracing system. GitLab users could previously navigate to their Jaeger instance to gain insight into the performance of a deployed application, tracking each function or microservice that handles a given request. Tracing in GitLab was deprecated in GitLab 14.7, and removed in 15.0. To track work on a possible replacement, see the issue for [Opstrace integration with GitLab](https://gitlab.com/groups/gitlab-org/-/epics/6976).
+
### Legacy Geo Admin UI routes
In GitLab 13.0, we introduced new project and design replication details routes in the Geo Admin UI. These routes are `/admin/geo/replication/projects` and `/admin/geo/replication/designs`. We kept the legacy routes and redirected them to the new routes. These legacy routes `/admin/geo/projects` and `/admin/geo/designs` have been removed in GitLab 15.0. Please update any bookmarks or scripts that may use the legacy routes.
diff --git a/doc/user/application_security/dependency_scanning/index.md b/doc/user/application_security/dependency_scanning/index.md
index 189cde4e1c1..ecb149d61c8 100644
--- a/doc/user/application_security/dependency_scanning/index.md
+++ b/doc/user/application_security/dependency_scanning/index.md
@@ -243,8 +243,8 @@ table.supported-languages ul {
<td>C#</td>
</tr>
<tr>
- <td rowspan="3">Python</td>
- <td rowspan="3">3.9</td>
+ <td rowspan="4">Python</td>
+ <td rowspan="4">3.9</td>
<td><a href="https://setuptools.readthedocs.io/en/latest/">setuptools</a></td>
<td><code>setup.py</code></td>
<td><a href="https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium">Gemnasium</a></td>
@@ -274,6 +274,12 @@ table.supported-languages ul {
<td>N</td>
</tr>
<tr>
+ <td><a href="https://python-poetry.org/">Poetry</a><sup><b><a href="#notes-regarding-supported-languages-and-package-managers-4">4</a></b></sup></td>
+ <td><code>poetry.lock</code></td>
+ <td><a href="https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium">Gemnasium</a></td>
+ <td>N</td>
+ </tr>
+ <tr>
<td>Scala</td>
<td>N/A</td>
<td><a href="https://www.scala-sbt.org/">sbt</a><sup><b><a href="#notes-regarding-supported-languages-and-package-managers-3">3</a></b></sup></td>
@@ -312,6 +318,14 @@ table.supported-languages ul {
Support for <a href="https://www.scala-sbt.org/">sbt</a> 1.3 and above was added in GitLab 13.9.
</p>
</li>
+ <li>
+ <a id="notes-regarding-supported-languages-and-package-managers-4"></a>
+ <p>
+ Support for <a href="https://python-poetry.org/">Poetry</a> projects with a <code>poetry.lock</code> file was [added in GitLab 15.0](https://gitlab.com/gitlab-org/gitlab/-/issues/7006).
+ Support for projects without a <code>poetry.lock</code> file is tracked in issue:
+ <a href="https://gitlab.com/gitlab-org/gitlab/-/issues/32774">Poetry's pyproject.toml support for dependency scanning.</a>
+ </p>
+ </li>
</ol>
<!-- markdownlint-enable MD044 -->
@@ -328,13 +342,13 @@ The following package managers use lockfiles that GitLab analyzers are capable o
| Package Manager | Supported File Format Versions | Tested Versions |
| ------ | ------ | ------ |
-| Bundler | N/A | [1.17.3](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/-/blob/master/qa/fixtures/ruby-bundler/main/Gemfile.lock#L118), [2.1.4](https://gitlab.com/gitlab-org/security-products/tests/ruby-bundler/-/blob/bundler2-FREEZE/Gemfile.lock#L118) |
-| Composer | N/A | [1.x](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/-/blob/master/qa/fixtures/php-composer/main/composer.lock) |
-| Conan | 0.4 | [1.x](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/-/blob/master/qa/fixtures/c-conan/main/conan.lock) |
-| Go | N/A | [1.x](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/-/blob/master/qa/fixtures/go-modules/main/go.sum) |
-| NuGet | v1 | [4.9](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/-/blob/master/qa/fixtures/csharp-nuget-dotnetcore/main/src/web.api/packages.lock.json#L2) |
-| npm | v1, v2 | [6.x](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/-/blob/master/qa/fixtures/js-npm/main/package-lock.json#L4), [7.x](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/-/blob/master/qa/fixtures/js-npm/lockfileVersion2/package-lock.json#L4) |
-| yarn | v1 | [1.x](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/-/blob/master/qa/fixtures/js-yarn/main/yarn.lock#L2) |
+| Bundler | N/A | [1.17.3](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/-/blob/master/qa/fixtures/ruby-bundler/default/Gemfile.lock#L118), [2.1.4](https://gitlab.com/gitlab-org/security-products/tests/ruby-bundler/-/blob/bundler2-FREEZE/Gemfile.lock#L118) |
+| Composer | N/A | [1.x](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/-/blob/master/qa/fixtures/php-composer/default/composer.lock) |
+| Conan | 0.4 | [1.x](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/-/blob/master/qa/fixtures/c-conan/default/conan.lock) |
+| Go | N/A | [1.x](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/-/blob/master/qa/fixtures/go-modules/default/go.sum) |
+| NuGet | v1 | [4.9](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/-/blob/master/qa/fixtures/csharp-nuget-dotnetcore/default/src/web.api/packages.lock.json#L2) |j
+| npm | v1, v2 | [6.x](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/-/blob/master/qa/fixtures/js-npm/default/package-lock.json#L4), [7.x](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/-/blob/master/qa/fixtures/js-npm/lockfileVersion2/package-lock.json#L4) |
+| yarn | v1 | [1.x](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/-/blob/master/qa/fixtures/js-yarn/default/yarn.lock#L2) |
#### Obtaining dependency information by running a package manager to generate a parsable file
@@ -413,8 +427,14 @@ If you've run into problems while scanning multiple files, please contribute a c
#### Python
-We only execute one installation in the directory where a requirements file has been detected, such as `requirements.txt` or any
-variation of this file (for example, `requirements.pip` or `requires.txt`).
+We only execute one installation in the directory where either a requirements file or a lock file has been detected. Dependencies are only analyzed by `gemnasium-python` for the first file that is detected. Files are searched for in the following order:
+
+1. `requirements.txt`, `requirements.pip`, or `requires.txt` for projects using Pip.
+1. `Pipfile` or `Pipfile.lock` for projects using Pipenv.
+1. `poetry.lock` for projects using Poetry.
+1. `setup.py` for project using Setuptools.
+
+The search begins with the root directory and then continues with subdirectories if no builds are found in the root directory. Consequently a Poetry lock file in the root directory would be detected before a Pipenv file in a subdirectory.
#### Java and Scala
@@ -448,15 +468,13 @@ From GitLab 14.8 the `gemnasium` analyzer scans supported JavaScript projects fo
The analyzer for these languages supports multiple lockfiles.
-### Support for additional languages
+#### Support for additional languages
Support for additional languages, dependency managers, and dependency files are tracked in the following issues:
| Package Managers | Languages | Supported files | Scan tools | Issue |
| ------------------- | --------- | --------------- | ---------- | ----- |
-| [Poetry](https://python-poetry.org/) | Python | `poetry.lock` | [Gemnasium](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium) | [GitLab#7006](https://gitlab.com/gitlab-org/gitlab/-/issues/7006) |
-
-For workarounds, see the [Troubleshooting section](#troubleshooting).
+| [Poetry](https://python-poetry.org/) | Python | `pyproject.toml` | [Gemnasium](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium) | [GitLab#32774](https://gitlab.com/gitlab-org/gitlab/-/issues/32774) |
## Contribute your scanner
@@ -1088,9 +1106,8 @@ Generally, the approach is the following:
1. Add [`dependencies: [<your-converter-job>]`](../../../ci/yaml/index.md#dependencies)
to your `dependency_scanning` job to make use of the converted definitions files.
-For example, the unsupported `poetry.lock` file can be
-[converted](https://python-poetry.org/docs/cli/#export)
-to the supported `requirements.txt` as follows.
+For example, Poetry projects that _only_ have a `pyproject.toml`
+file can generate the `poetry.lock` file as follows.
```yaml
include:
@@ -1099,15 +1116,11 @@ include:
stages:
- test
-variables:
- PIP_REQUIREMENTS_FILE: "requirements-converted.txt"
-
gemnasium-python-dependency_scanning:
- # Work around https://gitlab.com/gitlab-org/gitlab/-/issues/7006
+ # Work around https://gitlab.com/gitlab-org/gitlab/-/issues/32774
before_script:
- - pip install poetry # Or via another method: https://python-poetry.org/docs/#installation
- - poetry export --output="$PIP_REQUIREMENTS_FILE"
- - rm poetry.lock pyproject.toml
+ - pip install "poetry>=1,<2" # Or via another method: https://python-poetry.org/docs/#installation
+ - poetry update --lock # Generates the lock file to be analyzed.
```
### `Error response from daemon: error processing tar file: docker-tar: relocation error`
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index 0ef1541ee55..44b1acaca88 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -714,6 +714,17 @@ module API
end
end
+ desc 'Start a task to recalculate repository size for a project' do
+ detail 'This feature was introduced in GitLab 15.0.'
+ end
+ post ':id/repository_size', feature_category: :source_code_management do
+ authorize_admin_project
+
+ user_project.repository.expire_statistics_caches
+
+ ::Projects::UpdateStatisticsService.new(user_project, nil, statistics: [:repository_size, :lfs_objects_size]).execute
+ end
+
desc 'Transfer a project to a new namespace'
params do
requires :namespace, type: String, desc: 'The ID or path of the new namespace'
diff --git a/lib/backup/manager.rb b/lib/backup/manager.rb
index baff68d503f..0991177d044 100644
--- a/lib/backup/manager.rb
+++ b/lib/backup/manager.rb
@@ -9,6 +9,11 @@ module Backup
# if some of these files are still there, we don't need them in the backup
LEGACY_PAGES_TMP_PATH = '@pages.tmp'
+ LIST_ENVS = {
+ skipped: 'SKIP',
+ repositories_storages: 'REPOSITORIES_STORAGES'
+ }.freeze
+
TaskDefinition = Struct.new(
:enabled, # `true` if the task can be used. Treated as `true` when not specified.
:human_name, # Name of the task used for logging.
@@ -32,7 +37,7 @@ module Backup
Feature.enabled?(:incremental_repository_backup) &&
Gitlab::Utils.to_boolean(ENV['INCREMENTAL'], default: false)
- @definitions = definitions || build_definitions
+ @definitions = definitions
end
def create
@@ -43,7 +48,9 @@ module Backup
update_backup_information
end
- @definitions.keys.each do |task_name|
+ build_backup_information
+
+ definitions.keys.each do |task_name|
run_create_task(task_name)
end
@@ -65,10 +72,10 @@ module Backup
end
def run_create_task(task_name)
- definition = @definitions[task_name]
-
build_backup_information
+ definition = definitions[task_name]
+
unless definition.enabled?
puts_time "Dumping #{definition.human_name} ... ".color(:blue) + "[DISABLED]".color(:cyan)
return
@@ -92,7 +99,7 @@ module Backup
read_backup_information
verify_backup_version
- @definitions.keys.each do |task_name|
+ definitions.keys.each do |task_name|
run_restore_task(task_name) if !skipped?(task_name) && enabled_task?(task_name)
end
@@ -111,7 +118,9 @@ module Backup
end
def run_restore_task(task_name)
- definition = @definitions[task_name]
+ read_backup_information
+
+ definition = definitions[task_name]
unless definition.enabled?
puts_time "Restoring #{definition.human_name} ... ".color(:blue) + "[DISABLED]".color(:cyan)
@@ -143,6 +152,10 @@ module Backup
private
+ def definitions
+ @definitions ||= build_definitions
+ end
+
def build_definitions
{
'db' => TaskDefinition.new(
@@ -212,7 +225,7 @@ module Backup
max_storage_concurrency = ENV['GITLAB_BACKUP_MAX_STORAGE_CONCURRENCY'].presence
strategy = Backup::GitalyBackup.new(progress, incremental: incremental?, max_parallelism: max_concurrency, storage_parallelism: max_storage_concurrency)
- Repositories.new(progress, strategy: strategy)
+ Repositories.new(progress, strategy: strategy, storages: repositories_storages)
end
def build_files_task(app_files_dir, excludes: [])
@@ -245,7 +258,8 @@ module Backup
gitlab_version: Gitlab::VERSION,
tar_version: tar_version,
installation_type: Gitlab::INSTALLATION_TYPE,
- skipped: ENV["SKIP"]
+ skipped: ENV['SKIP'],
+ repositories_storages: ENV['REPOSITORIES_STORAGES']
}
end
@@ -256,7 +270,9 @@ module Backup
backup_created_at: Time.zone.now,
gitlab_version: Gitlab::VERSION,
tar_version: tar_version,
- installation_type: Gitlab::INSTALLATION_TYPE
+ installation_type: Gitlab::INSTALLATION_TYPE,
+ skipped: list_env(:skipped).join(','),
+ repositories_storages: list_env(:repositories_storages).join(',')
)
end
@@ -309,7 +325,7 @@ module Backup
puts_time "Deleting tar staging files ... ".color(:blue)
remove_backup_path(MANIFEST_NAME)
- @definitions.each do |_, definition|
+ definitions.each do |_, definition|
remove_backup_path(definition.cleanup_path || definition.destination_path)
end
@@ -443,12 +459,26 @@ module Backup
end
def skipped?(item)
- ENV.fetch('SKIP', '').include?(item) ||
- backup_information[:skipped] && backup_information[:skipped].include?(item)
+ skipped.include?(item)
+ end
+
+ def skipped
+ @skipped ||= list_env(:skipped)
+ end
+
+ def repositories_storages
+ @repositories_storages ||= list_env(:repositories_storages)
+ end
+
+ def list_env(name)
+ list = ENV.fetch(LIST_ENVS[name], '').split(',')
+ list += backup_information[name].split(',') if backup_information[name]
+ list.uniq!
+ list
end
def enabled_task?(task_name)
- @definitions[task_name].enabled?
+ definitions[task_name].enabled?
end
def backup_file?(file)
@@ -503,7 +533,7 @@ module Backup
end
def backup_contents
- [MANIFEST_NAME] + @definitions.reject do |name, definition|
+ [MANIFEST_NAME] + definitions.reject do |name, definition|
skipped?(name) || !enabled_task?(name) ||
(definition.destination_optional && !File.exist?(File.join(backup_path, definition.destination_path)))
end.values.map(&:destination_path)
diff --git a/lib/backup/repositories.rb b/lib/backup/repositories.rb
index 11bed84e356..4a31e87b969 100644
--- a/lib/backup/repositories.rb
+++ b/lib/backup/repositories.rb
@@ -6,10 +6,11 @@ module Backup
class Repositories < Task
extend ::Gitlab::Utils::Override
- def initialize(progress, strategy:)
+ def initialize(progress, strategy:, storages: [])
super(progress)
@strategy = strategy
+ @storages = storages
end
override :dump
@@ -35,7 +36,7 @@ module Backup
private
- attr_reader :strategy
+ attr_reader :strategy, :storages
def enqueue_consecutive
enqueue_consecutive_projects
@@ -49,7 +50,7 @@ module Backup
end
def enqueue_consecutive_snippets
- Snippet.find_each(batch_size: 1000) { |snippet| enqueue_snippet(snippet) }
+ snippet_relation.find_each(batch_size: 1000) { |snippet| enqueue_snippet(snippet) }
end
def enqueue_project(project)
@@ -63,7 +64,15 @@ module Backup
end
def project_relation
- Project.includes(:route, :group, namespace: :owner)
+ scope = Project.includes(:route, :group, namespace: :owner)
+ scope = scope.id_in(ProjectRepository.for_repository_storage(storages).select(:project_id)) if storages.any?
+ scope
+ end
+
+ def snippet_relation
+ scope = Snippet.all
+ scope = scope.id_in(SnippetRepository.for_repository_storage(storages).select(:snippet_id)) if storages.any?
+ scope
end
def restore_object_pools
@@ -88,7 +97,7 @@ module Backup
def cleanup_snippets_without_repositories
invalid_snippets = []
- Snippet.find_each(batch_size: 1000).each do |snippet|
+ snippet_relation.find_each(batch_size: 1000).each do |snippet|
response = Snippets::RepositoryValidationService.new(nil, snippet).execute
next if response.success?
diff --git a/lib/gitlab/ci/templates/Jobs/Dependency-Scanning.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Dependency-Scanning.gitlab-ci.yml
index f2b9cb82e22..e4b66c88ba7 100644
--- a/lib/gitlab/ci/templates/Jobs/Dependency-Scanning.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Dependency-Scanning.gitlab-ci.yml
@@ -120,6 +120,7 @@ gemnasium-maven-dependency_scanning:
- '{Pipfile,*/Pipfile,*/*/Pipfile}'
- '{requires.txt,*/requires.txt,*/*/requires.txt}'
- '{setup.py,*/setup.py,*/*/setup.py}'
+ - '{poetry.lock,*/poetry.lock,*/*/poetry.lock}'
gemnasium-python-dependency_scanning:
extends:
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 9047ba30b5f..94d0165aead 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -3705,7 +3705,7 @@ msgstr ""
msgid "All protected branches"
msgstr ""
-msgid "All threads resolved"
+msgid "All threads resolved!"
msgstr ""
msgid "All users must accept the Terms of Service and Privacy Policy to access GitLab"
@@ -11318,6 +11318,12 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Change scanner profile"
+msgstr ""
+
+msgid "DastProfiles|Change site profile"
+msgstr ""
+
msgid "DastProfiles|Choose a scan method"
msgstr ""
@@ -11432,9 +11438,6 @@ msgstr ""
msgid "DastProfiles|No scanner profile selected"
msgstr ""
-msgid "DastProfiles|No scanner profile selected."
-msgstr ""
-
msgid "DastProfiles|No scanner profiles created yet"
msgstr ""
@@ -11489,9 +11492,6 @@ msgstr ""
msgid "DastProfiles|Scanner name"
msgstr ""
-msgid "DastProfiles|Scanner profile"
-msgstr ""
-
msgid "DastProfiles|Scanner profiles define the configuration details of a security scanner. %{linkStart}Learn more%{linkEnd}."
msgstr ""
@@ -39027,18 +39027,12 @@ msgstr ""
msgid "ThreatMonitoring|Alerts"
msgstr ""
-msgid "ThreatMonitoring|All Environments"
-msgstr ""
-
msgid "ThreatMonitoring|Date and time"
msgstr ""
msgid "ThreatMonitoring|Dismissed"
msgstr ""
-msgid "ThreatMonitoring|Environment"
-msgstr ""
-
msgid "ThreatMonitoring|Events"
msgstr ""
@@ -39066,9 +39060,6 @@ msgstr ""
msgid "ThreatMonitoring|Resolved"
msgstr ""
-msgid "ThreatMonitoring|Something went wrong, unable to fetch environments"
-msgstr ""
-
msgid "ThreatMonitoring|Status"
msgstr ""
diff --git a/qa/qa/page/project/pipeline/show.rb b/qa/qa/page/project/pipeline/show.rb
index f499b748fb4..3f1cc2f1257 100644
--- a/qa/qa/page/project/pipeline/show.rb
+++ b/qa/qa/page/project/pipeline/show.rb
@@ -74,7 +74,11 @@ module QA
end
def has_linked_pipeline?(title: nil)
- title ? find_linked_pipeline_by_title(title) : has_element?(:linked_pipeline_container)
+ # If the pipeline page has loaded linked pipelines should appear, but it can take a little while,
+ # especially on busier environments.
+ retry_until(reload: true, message: 'Waiting for linked pipeline to appear') do
+ title ? find_linked_pipeline_by_title(title) : has_element?(:linked_pipeline_container)
+ end
end
alias_method :has_child_pipeline?, :has_linked_pipeline?
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/multi-project_pipelines_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/multi-project_pipelines_spec.rb
index 0d8756fc9a3..c5408f30d16 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/multi-project_pipelines_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/multi-project_pipelines_spec.rb
@@ -44,7 +44,7 @@ module QA
end
it(
- 'creates a multi-project pipeline',
+ 'creates a multi-project pipeline with artifact download',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/358064'
) do
Page::Project::Pipeline::Show.perform do |show|
@@ -78,7 +78,10 @@ module QA
job1:
stage: test
tags: ["#{executor}"]
- script: echo 'done'
+ script: echo 'done' > output.txt
+ artifacts:
+ paths:
+ - output.txt
staging:
stage: deploy
@@ -96,7 +99,12 @@ module QA
"#{downstream_job_name}":
stage: test
tags: ["#{executor}"]
- script: echo 'done'
+ needs:
+ - project: #{upstream_project.path_with_namespace}
+ job: job1
+ ref: main
+ artifacts: true
+ script: cat output.txt
YAML
}
end
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/parent_child_pipelines_dependent_relationship_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/parent_child_pipelines_dependent_relationship_spec.rb
index 5b7a569fa8a..f2278c7bf6d 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/parent_child_pipelines_dependent_relationship_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/parent_child_pipelines_dependent_relationship_spec.rb
@@ -60,7 +60,14 @@ module QA
child_job:
stage: test
tags: ["#{project.name}"]
- script: echo "Child job done!"
+ needs:
+ - project: #{project.path_with_namespace}
+ job: job1
+ ref: main
+ artifacts: true
+ script:
+ - cat output.txt
+ - echo "Child job done!"
YAML
}
@@ -84,18 +91,28 @@ module QA
file_path: '.gitlab-ci.yml',
content: <<~YAML
stages:
+ - build
- test
- deploy
+ default:
+ tags: ["#{project.name}"]
+
job1:
+ stage: build
+ script: echo "build success" > output.txt
+ artifacts:
+ paths:
+ - output.txt
+
+ job2:
stage: test
trigger:
include: ".child-ci.yml"
strategy: depend
- job2:
+ job3:
stage: deploy
- tags: ["#{project.name}"]
script: echo "parent deploy done"
YAML
diff --git a/rubocop/cop/gitlab/namespaced_class.rb b/rubocop/cop/gitlab/namespaced_class.rb
index 1f1fd280922..914cc8720b9 100644
--- a/rubocop/cop/gitlab/namespaced_class.rb
+++ b/rubocop/cop/gitlab/namespaced_class.rb
@@ -5,33 +5,76 @@ module RuboCop
module Gitlab
# Cop that enforces use of namespaced classes in order to better identify
# high level domains within the codebase.
-
+ #
# @example
# # bad
# class MyClass
# end
#
+ # module Gitlab
+ # class MyClass
+ # end
+ # end
+ #
+ # class Gitlab::MyClass
+ # end
+ #
# # good
# module MyDomain
# class MyClass
# end
# end
-
+ #
+ # module Gitlab
+ # module MyDomain
+ # class MyClass
+ # end
+ # end
+ # end
+ #
+ # class Gitlab::MyDomain::MyClass
+ # end
class NamespacedClass < RuboCop::Cop::Cop
MSG = 'Classes must be declared inside a module indicating a product domain namespace. For more info: https://gitlab.com/gitlab-org/gitlab/-/issues/212156'
- def_node_matcher :compact_namespaced_class?, <<~PATTERN
- (class (const (const ...) ...) ...)
- PATTERN
+ # These namespaces are considered top-level semantically.
+ # Note: Nested namespace like Foo::Bar are also supported.
+ PSEUDO_TOPLEVEL = %w[Gitlab]
+ .map { _1.split('::') }.freeze
def on_module(node)
- @namespaced = true
+ add_potential_domain_namespace(node)
end
def on_class(node)
- return if @namespaced
+ # Add potential namespaces from compact definitions like `class Foo::Bar`.
+ # Remove class name because it's not a domain namespace.
+ add_potential_domain_namespace(node) { _1.pop }
+
+ add_offense(node) if domain_namespaces.none?
+ end
+
+ private
+
+ def domain_namespaces
+ @domain_namespaces ||= []
+ end
+
+ def add_potential_domain_namespace(node)
+ return if domain_namespaces.any?
+
+ identifiers = identifiers_for(node)
+ yield(identifiers) if block_given?
+
+ PSEUDO_TOPLEVEL.each do |namespaces|
+ identifiers.shift(namespaces.size) if namespaces == identifiers.first(namespaces.size)
+ end
+
+ domain_namespaces.concat(identifiers)
+ end
- add_offense(node) unless compact_namespaced_class?(node)
+ def identifiers_for(node)
+ node.identifier.source.sub(/^::/, '').split('::')
end
end
end
diff --git a/spec/features/merge_request/user_posts_diff_notes_spec.rb b/spec/features/merge_request/user_posts_diff_notes_spec.rb
index d803aec5895..64715f9234a 100644
--- a/spec/features/merge_request/user_posts_diff_notes_spec.rb
+++ b/spec/features/merge_request/user_posts_diff_notes_spec.rb
@@ -239,7 +239,7 @@ RSpec.describe 'Merge request > User posts diff notes', :js do
def should_allow_dismissing_a_comment(line_holder, diff_side = nil)
write_comment_on_line(line_holder, diff_side)
- accept_gl_confirm(s_('Notes|Are you sure you want to cancel creating this comment?')) do
+ accept_gl_confirm(s_('Notes|Are you sure you want to cancel creating this comment?'), button_text: _('Discard changes')) do
find('.js-close-discussion-note-form').click
end
diff --git a/spec/frontend/diffs/utils/queue_events_spec.js b/spec/frontend/diffs/utils/queue_events_spec.js
index 007748d8b2c..ad2745f5188 100644
--- a/spec/frontend/diffs/utils/queue_events_spec.js
+++ b/spec/frontend/diffs/utils/queue_events_spec.js
@@ -1,11 +1,15 @@
import api from '~/api';
-import { DEFER_DURATION } from '~/diffs/constants';
+import { DEFER_DURATION, TRACKING_CAP_KEY, TRACKING_CAP_LENGTH } from '~/diffs/constants';
import { queueRedisHllEvents } from '~/diffs/utils/queue_events';
jest.mock('~/api', () => ({
trackRedisHllUserEvent: jest.fn(),
}));
+beforeAll(() => {
+ localStorage.clear();
+});
+
describe('diffs events queue', () => {
describe('queueRedisHllEvents', () => {
it('does not dispatch the event immediately', () => {
@@ -17,6 +21,7 @@ describe('diffs events queue', () => {
queueRedisHllEvents(['know_event']);
jest.advanceTimersByTime(DEFER_DURATION + 1);
expect(api.trackRedisHllUserEvent).toHaveBeenCalled();
+ expect(localStorage.getItem(TRACKING_CAP_KEY)).toBe(null);
});
it('increase defer duration based on the provided events count', () => {
@@ -32,5 +37,35 @@ describe('diffs events queue', () => {
deferDuration *= index + 1;
});
});
+
+ describe('with tracking cap verification', () => {
+ const currentTimestamp = Date.now();
+
+ beforeEach(() => {
+ localStorage.clear();
+ });
+
+ it('dispatches the event if cap value is not found', () => {
+ queueRedisHllEvents(['know_event'], { verifyCap: true });
+ jest.advanceTimersByTime(DEFER_DURATION + 1);
+ expect(api.trackRedisHllUserEvent).toHaveBeenCalled();
+ expect(localStorage.getItem(TRACKING_CAP_KEY)).toBe(currentTimestamp.toString());
+ });
+
+ it('dispatches the event if cap value is less than limit', () => {
+ localStorage.setItem(TRACKING_CAP_KEY, 1);
+ queueRedisHllEvents(['know_event'], { verifyCap: true });
+ jest.advanceTimersByTime(DEFER_DURATION + 1);
+ expect(api.trackRedisHllUserEvent).toHaveBeenCalled();
+ expect(localStorage.getItem(TRACKING_CAP_KEY)).toBe(currentTimestamp.toString());
+ });
+
+ it('does not dispatch the event if cap value is greater than limit', () => {
+ localStorage.setItem(TRACKING_CAP_KEY, currentTimestamp - (TRACKING_CAP_LENGTH + 1));
+ queueRedisHllEvents(['know_event'], { verifyCap: true });
+ jest.advanceTimersByTime(DEFER_DURATION + 1);
+ expect(api.trackRedisHllUserEvent).toHaveBeenCalled();
+ });
+ });
});
});
diff --git a/spec/frontend/jira_connect/subscriptions/components/add_namespace_modal/groups_list_item_spec.js b/spec/frontend/jira_connect/subscriptions/components/add_namespace_modal/groups_list_item_spec.js
index 3cdb21dbe95..5df54abfc05 100644
--- a/spec/frontend/jira_connect/subscriptions/components/add_namespace_modal/groups_list_item_spec.js
+++ b/spec/frontend/jira_connect/subscriptions/components/add_namespace_modal/groups_list_item_spec.js
@@ -7,21 +7,35 @@ import * as JiraConnectApi from '~/jira_connect/subscriptions/api';
import GroupItemName from '~/jira_connect/subscriptions/components/group_item_name.vue';
import GroupsListItem from '~/jira_connect/subscriptions/components/add_namespace_modal/groups_list_item.vue';
import { persistAlert, reloadPage } from '~/jira_connect/subscriptions/utils';
+import {
+ I18N_ADD_SUBSCRIPTION_SUCCESS_ALERT_TITLE,
+ I18N_ADD_SUBSCRIPTION_SUCCESS_ALERT_MESSAGE,
+ INTEGRATIONS_DOC_LINK,
+} from '~/jira_connect/subscriptions/constants';
+import createStore from '~/jira_connect/subscriptions/store';
import { mockGroup1 } from '../../mock_data';
jest.mock('~/jira_connect/subscriptions/utils');
describe('GroupsListItem', () => {
let wrapper;
+ let store;
+
const mockAddSubscriptionsPath = '/addSubscriptionsPath';
- const createComponent = ({ mountFn = shallowMount } = {}) => {
+ const createComponent = ({ mountFn = shallowMount, provide } = {}) => {
+ store = createStore();
+
+ jest.spyOn(store, 'dispatch').mockImplementation();
+
wrapper = mountFn(GroupsListItem, {
+ store,
propsData: {
group: mockGroup1,
},
provide: {
addSubscriptionsPath: mockAddSubscriptionsPath,
+ ...provide,
},
});
};
@@ -51,65 +65,88 @@ describe('GroupsListItem', () => {
});
describe('on Link button click', () => {
- let addSubscriptionSpy;
+ describe('when jiraConnectOauth feature flag is disabled', () => {
+ let addSubscriptionSpy;
- beforeEach(() => {
- createComponent({ mountFn: mount });
+ beforeEach(() => {
+ createComponent({ mountFn: mount });
- addSubscriptionSpy = jest.spyOn(JiraConnectApi, 'addSubscription').mockResolvedValue();
- });
+ addSubscriptionSpy = jest.spyOn(JiraConnectApi, 'addSubscription').mockResolvedValue();
+ });
- it('sets button to loading and sends request', async () => {
- expect(findLinkButton().props('loading')).toBe(false);
+ it('sets button to loading and sends request', async () => {
+ expect(findLinkButton().props('loading')).toBe(false);
+
+ clickLinkButton();
+ await nextTick();
- clickLinkButton();
+ expect(findLinkButton().props('loading')).toBe(true);
+ await waitForPromises();
- await nextTick();
+ expect(addSubscriptionSpy).toHaveBeenCalledWith(
+ mockAddSubscriptionsPath,
+ mockGroup1.full_path,
+ );
+ expect(persistAlert).toHaveBeenCalledWith({
+ linkUrl: INTEGRATIONS_DOC_LINK,
+ message: I18N_ADD_SUBSCRIPTION_SUCCESS_ALERT_MESSAGE,
+ title: I18N_ADD_SUBSCRIPTION_SUCCESS_ALERT_TITLE,
+ variant: 'success',
+ });
+ });
- expect(findLinkButton().props('loading')).toBe(true);
+ describe('when request is successful', () => {
+ it('reloads the page', async () => {
+ clickLinkButton();
- await waitForPromises();
+ await waitForPromises();
- expect(addSubscriptionSpy).toHaveBeenCalledWith(
- mockAddSubscriptionsPath,
- mockGroup1.full_path,
- );
- expect(persistAlert).toHaveBeenCalledWith({
- linkUrl: '/help/integration/jira_development_panel.html#use-the-integration',
- message:
- 'You should now see GitLab.com activity inside your Jira Cloud issues. %{linkStart}Learn more%{linkEnd}',
- title: 'Namespace successfully linked',
- variant: 'success',
+ expect(reloadPage).toHaveBeenCalled();
+ });
});
- });
- describe('when request is successful', () => {
- it('reloads the page', async () => {
- clickLinkButton();
+ describe('when request has errors', () => {
+ const mockErrorMessage = 'error message';
+ const mockError = { response: { data: { error: mockErrorMessage } } };
- await waitForPromises();
+ beforeEach(() => {
+ addSubscriptionSpy = jest
+ .spyOn(JiraConnectApi, 'addSubscription')
+ .mockRejectedValue(mockError);
+ });
- expect(reloadPage).toHaveBeenCalled();
+ it('emits `error` event', async () => {
+ clickLinkButton();
+
+ await waitForPromises();
+
+ expect(reloadPage).not.toHaveBeenCalled();
+ expect(wrapper.emitted('error')[0][0]).toBe(mockErrorMessage);
+ });
});
});
- describe('when request has errors', () => {
- const mockErrorMessage = 'error message';
- const mockError = { response: { data: { error: mockErrorMessage } } };
+ describe('when jiraConnectOauth feature flag is enabled', () => {
+ const mockSubscriptionsPath = '/subscriptions';
beforeEach(() => {
- addSubscriptionSpy = jest
- .spyOn(JiraConnectApi, 'addSubscription')
- .mockRejectedValue(mockError);
+ createComponent({
+ mountFn: mount,
+ provide: {
+ subscriptionsPath: mockSubscriptionsPath,
+ glFeatures: { jiraConnectOauth: true },
+ },
+ });
});
- it('emits `error` event', async () => {
+ it('dispatches `addSubscription` action', async () => {
clickLinkButton();
+ await nextTick();
- await waitForPromises();
-
- expect(reloadPage).not.toHaveBeenCalled();
- expect(wrapper.emitted('error')[0][0]).toBe(mockErrorMessage);
+ expect(store.dispatch).toHaveBeenCalledWith('addSubscription', {
+ namespacePath: mockGroup1.full_path,
+ subscriptionsPath: mockSubscriptionsPath,
+ });
});
});
});
diff --git a/spec/frontend/jira_connect/subscriptions/components/app_spec.js b/spec/frontend/jira_connect/subscriptions/components/app_spec.js
index a70c2f6c5f7..9894141be5a 100644
--- a/spec/frontend/jira_connect/subscriptions/components/app_spec.js
+++ b/spec/frontend/jira_connect/subscriptions/components/app_spec.js
@@ -161,32 +161,6 @@ describe('JiraConnectApp', () => {
});
describe('when user signed out', () => {
- describe('when sign in page emits `sign-in-oauth` event', () => {
- const mockUser = { name: 'test' };
- beforeEach(async () => {
- createComponent({
- provide: {
- usersPath: '/mock',
- },
- });
- findSignInPage().vm.$emit('sign-in-oauth', mockUser);
-
- await nextTick();
- });
-
- it('hides sign in page and renders subscriptions page', () => {
- expect(findSignInPage().exists()).toBe(false);
- expect(findSubscriptionsPage().exists()).toBe(true);
- });
-
- it('sets correct UserLink props', () => {
- expect(findUserLink().props()).toMatchObject({
- user: mockUser,
- userSignedIn: true,
- });
- });
- });
-
describe('when sign in page emits `error` event', () => {
beforeEach(async () => {
createComponent({
diff --git a/spec/frontend/jira_connect/subscriptions/components/sign_in_oauth_button_spec.js b/spec/frontend/jira_connect/subscriptions/components/sign_in_oauth_button_spec.js
index 1002c48afe0..8730e124ae7 100644
--- a/spec/frontend/jira_connect/subscriptions/components/sign_in_oauth_button_spec.js
+++ b/spec/frontend/jira_connect/subscriptions/components/sign_in_oauth_button_spec.js
@@ -12,6 +12,8 @@ import waitForPromises from 'helpers/wait_for_promises';
import httpStatus from '~/lib/utils/http_status';
import AccessorUtilities from '~/lib/utils/accessor';
import { getCurrentUser } from '~/rest_api';
+import createStore from '~/jira_connect/subscriptions/store';
+import { SET_ACCESS_TOKEN } from '~/jira_connect/subscriptions/store/mutation_types';
jest.mock('~/lib/utils/accessor');
jest.mock('~/jira_connect/subscriptions/utils');
@@ -31,9 +33,15 @@ const mockOauthMetadata = {
describe('SignInOauthButton', () => {
let wrapper;
let mockAxios;
+ let store;
const createComponent = ({ slots } = {}) => {
+ store = createStore();
+ jest.spyOn(store, 'dispatch').mockImplementation();
+ jest.spyOn(store, 'commit').mockImplementation();
+
wrapper = shallowMount(SignInOauthButton, {
+ store,
slots,
provide: {
oauthMetadata: mockOauthMetadata,
@@ -117,10 +125,6 @@ describe('SignInOauthButton', () => {
await waitForPromises();
});
- it('emits `error` event', () => {
- expect(wrapper.emitted('error')).toBeTruthy();
- });
-
it('does not emit `sign-in` event', () => {
expect(wrapper.emitted('sign-in')).toBeFalsy();
});
@@ -164,25 +168,25 @@ describe('SignInOauthButton', () => {
});
});
- it('executes GET request to fetch user data', () => {
- expect(getCurrentUser).toHaveBeenCalledWith({
- headers: { Authorization: `Bearer ${mockAccessToken}` },
- });
+ it('dispatches loadCurrentUser action', () => {
+ expect(store.dispatch).toHaveBeenCalledWith('loadCurrentUser', mockAccessToken);
+ });
+
+ it('commits SET_ACCESS_TOKEN mutation with correct access token', () => {
+ expect(store.commit).toHaveBeenCalledWith(SET_ACCESS_TOKEN, mockAccessToken);
});
it('emits `sign-in` event with user data', () => {
- expect(wrapper.emitted('sign-in')[0]).toEqual([mockUser]);
+ expect(wrapper.emitted('sign-in')[0]).toBeTruthy();
});
});
describe('when API requests fail', () => {
beforeEach(async () => {
jest.spyOn(axios, 'post');
- jest.spyOn(axios, 'get');
mockAxios
.onPost(mockOauthMetadata.oauth_token_url)
- .replyOnce(httpStatus.INTERNAL_SERVER_ERROR, { access_token: mockAccessToken });
- mockAxios.onGet('/api/v4/user').replyOnce(httpStatus.INTERNAL_SERVER_ERROR, mockUser);
+ .replyOnce(httpStatus.INTERNAL_SERVER_ERROR);
window.dispatchEvent(new MessageEvent('message', mockEvent));
@@ -190,7 +194,7 @@ describe('SignInOauthButton', () => {
});
it('emits `error` event', () => {
- expect(wrapper.emitted('error')).toBeTruthy();
+ expect(wrapper.emitted('error')[0]).toEqual([]);
});
it('does not emit `sign-in` event', () => {
diff --git a/spec/frontend/jira_connect/subscriptions/pages/sign_in/sign_in_page_spec.js b/spec/frontend/jira_connect/subscriptions/pages/sign_in/sign_in_page_spec.js
index 24aa6e2beaa..65b08fba592 100644
--- a/spec/frontend/jira_connect/subscriptions/pages/sign_in/sign_in_page_spec.js
+++ b/spec/frontend/jira_connect/subscriptions/pages/sign_in/sign_in_page_spec.js
@@ -74,8 +74,8 @@ describe('SignInPage', () => {
describe('when sign-in-oauth event is emitted', () => {
it('emits another sign-in-oauth event', () => {
- findSignInGitlabCom().vm.$emit('sign-in-oauth', 'test');
- expect(wrapper.emitted('sign-in-oauth')[0][0]).toBe('test');
+ findSignInGitlabCom().vm.$emit('sign-in-oauth');
+ expect(wrapper.emitted('sign-in-oauth')[0]).toEqual([]);
});
});
});
diff --git a/spec/frontend/jira_connect/subscriptions/store/actions_spec.js b/spec/frontend/jira_connect/subscriptions/store/actions_spec.js
index fbc814155b0..53b5d8e70af 100644
--- a/spec/frontend/jira_connect/subscriptions/store/actions_spec.js
+++ b/spec/frontend/jira_connect/subscriptions/store/actions_spec.js
@@ -1,10 +1,22 @@
import testAction from 'helpers/vuex_action_helper';
import * as types from '~/jira_connect/subscriptions/store/mutation_types';
-import { fetchSubscriptions } from '~/jira_connect/subscriptions/store/actions';
+import {
+ fetchSubscriptions,
+ loadCurrentUser,
+ addSubscription,
+} from '~/jira_connect/subscriptions/store/actions';
import state from '~/jira_connect/subscriptions/store/state';
import * as api from '~/jira_connect/subscriptions/api';
-import { I18N_DEFAULT_SUBSCRIPTIONS_ERROR_MESSAGE } from '~/jira_connect/subscriptions/constants';
+import * as userApi from '~/api/user_api';
+import * as integrationsApi from '~/api/integrations_api';
+import {
+ I18N_DEFAULT_SUBSCRIPTIONS_ERROR_MESSAGE,
+ I18N_ADD_SUBSCRIPTION_SUCCESS_ALERT_TITLE,
+ I18N_ADD_SUBSCRIPTION_SUCCESS_ALERT_MESSAGE,
+ INTEGRATIONS_DOC_LINK,
+} from '~/jira_connect/subscriptions/constants';
+import * as utils from '~/jira_connect/subscriptions/utils';
describe('JiraConnect actions', () => {
let mockedState;
@@ -60,4 +72,101 @@ describe('JiraConnect actions', () => {
});
});
});
+
+ describe('loadCurrentUser', () => {
+ const mockAccessToken = 'abcd1234';
+
+ describe('when API request succeeds', () => {
+ it('commits the SET_ACCESS_TOKEN and SET_CURRENT_USER mutations', async () => {
+ const mockUser = { name: 'root' };
+ jest.spyOn(userApi, 'getCurrentUser').mockResolvedValue({ data: mockUser });
+
+ await testAction(
+ loadCurrentUser,
+ mockAccessToken,
+ mockedState,
+ [{ type: types.SET_CURRENT_USER, payload: mockUser }],
+ [],
+ );
+
+ expect(userApi.getCurrentUser).toHaveBeenCalledWith({
+ headers: { Authorization: `Bearer ${mockAccessToken}` },
+ });
+ });
+ });
+
+ describe('when API request fails', () => {
+ it('commits the SET_CURRENT_USER_ERROR mutation', async () => {
+ jest.spyOn(userApi, 'getCurrentUser').mockRejectedValue();
+
+ await testAction(
+ loadCurrentUser,
+ mockAccessToken,
+ mockedState,
+ [{ type: types.SET_CURRENT_USER_ERROR }],
+ [],
+ );
+ });
+ });
+ });
+
+ describe('addSubscription', () => {
+ const mockNamespace = 'gitlab-org/gitlab';
+ const mockSubscriptionsPath = '/subscriptions';
+
+ beforeEach(() => {
+ jest.spyOn(utils, 'getJwt').mockReturnValue('1234');
+ });
+
+ describe('when API request succeeds', () => {
+ it('commits the SET_ACCESS_TOKEN and SET_CURRENT_USER mutations', async () => {
+ jest
+ .spyOn(integrationsApi, 'addJiraConnectSubscription')
+ .mockResolvedValue({ success: true });
+
+ await testAction(
+ addSubscription,
+ { namespacePath: mockNamespace, subscriptionsPath: mockSubscriptionsPath },
+ mockedState,
+ [
+ { type: types.ADD_SUBSCRIPTION_LOADING, payload: true },
+ {
+ type: types.SET_ALERT,
+ payload: {
+ title: I18N_ADD_SUBSCRIPTION_SUCCESS_ALERT_TITLE,
+ message: I18N_ADD_SUBSCRIPTION_SUCCESS_ALERT_MESSAGE,
+ linkUrl: INTEGRATIONS_DOC_LINK,
+ variant: 'success',
+ },
+ },
+ { type: types.ADD_SUBSCRIPTION_LOADING, payload: false },
+ ],
+ [{ type: 'fetchSubscriptions', payload: mockSubscriptionsPath }],
+ );
+
+ expect(integrationsApi.addJiraConnectSubscription).toHaveBeenCalledWith(mockNamespace, {
+ accessToken: null,
+ jwt: '1234',
+ });
+ });
+ });
+
+ describe('when API request fails', () => {
+ it('commits the SET_CURRENT_USER_ERROR mutation', async () => {
+ jest.spyOn(integrationsApi, 'addJiraConnectSubscription').mockRejectedValue();
+
+ await testAction(
+ addSubscription,
+ mockNamespace,
+ mockedState,
+ [
+ { type: types.ADD_SUBSCRIPTION_LOADING, payload: true },
+ { type: types.ADD_SUBSCRIPTION_ERROR },
+ { type: types.ADD_SUBSCRIPTION_LOADING, payload: false },
+ ],
+ [],
+ );
+ });
+ });
+ });
});
diff --git a/spec/frontend/jira_connect/subscriptions/store/mutations_spec.js b/spec/frontend/jira_connect/subscriptions/store/mutations_spec.js
index b5069a9b98d..aeb136a76b9 100644
--- a/spec/frontend/jira_connect/subscriptions/store/mutations_spec.js
+++ b/spec/frontend/jira_connect/subscriptions/store/mutations_spec.js
@@ -26,6 +26,15 @@ describe('JiraConnect store mutations', () => {
});
});
+ describe('SET_SUBSCRIPTIONS', () => {
+ it('sets subscriptions loading flag', () => {
+ const mockSubscriptions = [{ name: 'test' }];
+ mutations.SET_SUBSCRIPTIONS(localState, mockSubscriptions);
+
+ expect(localState.subscriptions).toBe(mockSubscriptions);
+ });
+ });
+
describe('SET_SUBSCRIPTIONS_LOADING', () => {
it('sets subscriptions loading flag', () => {
mutations.SET_SUBSCRIPTIONS_LOADING(localState, true);
@@ -34,12 +43,53 @@ describe('JiraConnect store mutations', () => {
});
});
- describe('SET_SUBSCRIPTIONS', () => {
- it('sets subscriptions loading flag', () => {
- const mockSubscriptions = [{ name: 'test' }];
- mutations.SET_SUBSCRIPTIONS(localState, mockSubscriptions);
+ describe('SET_SUBSCRIPTIONS_ERROR', () => {
+ it('sets subscriptions error', () => {
+ mutations.SET_SUBSCRIPTIONS_ERROR(localState, true);
- expect(localState.subscriptions).toBe(mockSubscriptions);
+ expect(localState.subscriptionsError).toBe(true);
+ });
+ });
+
+ describe('ADD_SUBSCRIPTION_LOADING', () => {
+ it('sets addSubscriptionLoading', () => {
+ mutations.ADD_SUBSCRIPTION_LOADING(localState, true);
+
+ expect(localState.addSubscriptionLoading).toBe(true);
+ });
+ });
+
+ describe('ADD_SUBSCRIPTION_ERROR', () => {
+ it('sets addSubscriptionError', () => {
+ mutations.ADD_SUBSCRIPTION_ERROR(localState, true);
+
+ expect(localState.addSubscriptionError).toBe(true);
+ });
+ });
+
+ describe('SET_CURRENT_USER', () => {
+ it('sets currentUser', () => {
+ const mockUser = { name: 'root' };
+ mutations.SET_CURRENT_USER(localState, mockUser);
+
+ expect(localState.currentUser).toBe(mockUser);
+ });
+ });
+
+ describe('SET_CURRENT_USER_ERROR', () => {
+ it('sets currentUserError', () => {
+ mutations.SET_CURRENT_USER_ERROR(localState, true);
+
+ expect(localState.currentUserError).toBe(true);
+ });
+ });
+
+ describe('SET_ACCESS_TOKEN', () => {
+ it('sets accessToken', () => {
+ const mockAccessToken = 'asdf1234';
+ mutations.SET_ACCESS_TOKEN(localState, mockAccessToken);
+
+ expect(localState.accessToken).toBe(mockAccessToken);
});
});
});
diff --git a/spec/frontend/notes/components/discussion_counter_spec.js b/spec/frontend/notes/components/discussion_counter_spec.js
index b83e3b1b715..f016cef18e6 100644
--- a/spec/frontend/notes/components/discussion_counter_spec.js
+++ b/spec/frontend/notes/components/discussion_counter_spec.js
@@ -88,6 +88,7 @@ describe('DiscussionCounter component', () => {
'changes background color to $color if blocksMerge is $blocksMerge',
({ blocksMerge, color }) => {
updateStore();
+ store.state.unresolvedDiscussionsCount = 1;
wrapper = shallowMount(DiscussionCounter, { store, propsData: { blocksMerge } });
expect(wrapper.find('[data-testid="discussions-counter-text"]').classes()).toContain(color);
diff --git a/spec/helpers/namespaces_helper_spec.rb b/spec/helpers/namespaces_helper_spec.rb
index cb09c2f89e1..39f0e1c15f5 100644
--- a/spec/helpers/namespaces_helper_spec.rb
+++ b/spec/helpers/namespaces_helper_spec.rb
@@ -269,9 +269,9 @@ RSpec.describe NamespacesHelper do
end
end
- describe '#pipeline_usage_quota_app_data' do
+ describe '#pipeline_usage_app_data' do
it 'returns a hash with necessary data for the frontend' do
- expect(helper.pipeline_usage_quota_app_data(user_group)).to eql({
+ expect(helper.pipeline_usage_app_data(user_group)).to eql({
namespace_actual_plan_name: user_group.actual_plan_name,
namespace_path: user_group.full_path,
namespace_id: user_group.id,
diff --git a/spec/lib/backup/manager_spec.rb b/spec/lib/backup/manager_spec.rb
index 81573b6140d..a2477834dde 100644
--- a/spec/lib/backup/manager_spec.rb
+++ b/spec/lib/backup/manager_spec.rb
@@ -853,6 +853,7 @@ RSpec.describe Backup::Manager do
]
)
allow(File).to receive(:exist?).with(File.join(Gitlab.config.backup.path, 'backup_information.yml')).and_return(true)
+ stub_env('SKIP', 'something')
end
after do
@@ -872,7 +873,7 @@ RSpec.describe Backup::Manager do
backup_created_at: backup_time,
full_backup_id: full_backup_id,
gitlab_version: Gitlab::VERSION,
- skipped: 'tar'
+ skipped: 'something,tar'
)
end
diff --git a/spec/lib/backup/repositories_spec.rb b/spec/lib/backup/repositories_spec.rb
index c6f611e727c..1581e4793e3 100644
--- a/spec/lib/backup/repositories_spec.rb
+++ b/spec/lib/backup/repositories_spec.rb
@@ -5,13 +5,15 @@ require 'spec_helper'
RSpec.describe Backup::Repositories do
let(:progress) { spy(:stdout) }
let(:strategy) { spy(:strategy) }
+ let(:storages) { [] }
let(:destination) { 'repositories' }
let(:backup_id) { 'backup_id' }
subject do
described_class.new(
progress,
- strategy: strategy
+ strategy: strategy,
+ storages: storages
)
end
@@ -67,17 +69,50 @@ RSpec.describe Backup::Repositories do
end.count
create_list(:project, 2, :repository)
+ create_list(:snippet, 2, :repository)
expect do
subject.dump(destination, backup_id)
end.not_to exceed_query_limit(control_count)
end
+
+ describe 'storages' do
+ let(:storages) { %w{default} }
+
+ let_it_be(:project) { create(:project, :repository) }
+
+ before do
+ stub_storage_settings('test_second_storage' => {
+ 'gitaly_address' => Gitlab.config.repositories.storages.default.gitaly_address,
+ 'path' => TestEnv::SECOND_STORAGE_PATH
+ })
+ end
+
+ it 'calls enqueue for all repositories on the specified storage', :aggregate_failures do
+ excluded_project = create(:project, :repository, repository_storage: 'test_second_storage')
+ excluded_project_snippet = create(:project_snippet, :repository, project: excluded_project)
+ excluded_project_snippet.track_snippet_repository('test_second_storage')
+ excluded_personal_snippet = create(:personal_snippet, :repository, author: excluded_project.first_owner)
+ excluded_personal_snippet.track_snippet_repository('test_second_storage')
+
+ subject.dump(destination, backup_id)
+
+ expect(strategy).to have_received(:start).with(:create, destination, backup_id: backup_id)
+ expect(strategy).not_to have_received(:enqueue).with(excluded_project, Gitlab::GlRepository::PROJECT)
+ expect(strategy).not_to have_received(:enqueue).with(excluded_project_snippet, Gitlab::GlRepository::SNIPPET)
+ expect(strategy).not_to have_received(:enqueue).with(excluded_personal_snippet, Gitlab::GlRepository::SNIPPET)
+ expect(strategy).to have_received(:enqueue).with(project, Gitlab::GlRepository::PROJECT)
+ expect(strategy).to have_received(:enqueue).with(project, Gitlab::GlRepository::WIKI)
+ expect(strategy).to have_received(:enqueue).with(project, Gitlab::GlRepository::DESIGN)
+ expect(strategy).to have_received(:finish!)
+ end
+ end
end
describe '#restore' do
- let_it_be(:project) { create(:project) }
- let_it_be(:personal_snippet) { create(:personal_snippet, author: project.first_owner) }
- let_it_be(:project_snippet) { create(:project_snippet, project: project, author: project.first_owner) }
+ let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:personal_snippet) { create(:personal_snippet, :repository, author: project.first_owner) }
+ let_it_be(:project_snippet) { create(:project_snippet, :repository, project: project, author: project.first_owner) }
it 'calls enqueue for each repository type', :aggregate_failures do
subject.restore(destination)
@@ -116,9 +151,6 @@ RSpec.describe Backup::Repositories do
context 'cleanup snippets' do
before do
- create(:snippet_repository, snippet: personal_snippet)
- create(:snippet_repository, snippet: project_snippet)
-
error_response = ServiceResponse.error(message: "Repository has more than one branch")
allow(Snippets::RepositoryValidationService).to receive_message_chain(:new, :execute).and_return(error_response)
end
@@ -146,5 +178,35 @@ RSpec.describe Backup::Repositories do
expect(gitlab_shell.repository_exists?(shard_name, path)).to eq false
end
end
+
+ context 'storages' do
+ let(:storages) { %w{default} }
+
+ before do
+ stub_storage_settings('test_second_storage' => {
+ 'gitaly_address' => Gitlab.config.repositories.storages.default.gitaly_address,
+ 'path' => TestEnv::SECOND_STORAGE_PATH
+ })
+ end
+
+ it 'calls enqueue for all repositories on the specified storage', :aggregate_failures do
+ excluded_project = create(:project, :repository, repository_storage: 'test_second_storage')
+ excluded_project_snippet = create(:project_snippet, :repository, project: excluded_project)
+ excluded_project_snippet.track_snippet_repository('test_second_storage')
+ excluded_personal_snippet = create(:personal_snippet, :repository, author: excluded_project.first_owner)
+ excluded_personal_snippet.track_snippet_repository('test_second_storage')
+
+ subject.restore(destination)
+
+ expect(strategy).to have_received(:start).with(:restore, destination)
+ expect(strategy).not_to have_received(:enqueue).with(excluded_project, Gitlab::GlRepository::PROJECT)
+ expect(strategy).not_to have_received(:enqueue).with(excluded_project_snippet, Gitlab::GlRepository::SNIPPET)
+ expect(strategy).not_to have_received(:enqueue).with(excluded_personal_snippet, Gitlab::GlRepository::SNIPPET)
+ expect(strategy).to have_received(:enqueue).with(project, Gitlab::GlRepository::PROJECT)
+ expect(strategy).to have_received(:enqueue).with(project, Gitlab::GlRepository::WIKI)
+ expect(strategy).to have_received(:enqueue).with(project, Gitlab::GlRepository::DESIGN)
+ expect(strategy).to have_received(:finish!)
+ end
+ end
end
end
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index 11ac10e9d6d..d2189ab02ea 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -4510,6 +4510,43 @@ RSpec.describe API::Projects do
end
end
+ describe 'POST /projects/:id/repository_size' do
+ let(:update_statistics_service) { Projects::UpdateStatisticsService.new(project, nil, statistics: [:repository_size, :lfs_objects_size]) }
+
+ before do
+ allow(Projects::UpdateStatisticsService).to receive(:new).with(project, nil, statistics: [:repository_size, :lfs_objects_size]).and_return(update_statistics_service)
+ end
+
+ context 'when authenticated as owner' do
+ it 'starts the housekeeping process' do
+ expect(update_statistics_service).to receive(:execute).once
+
+ post api("/projects/#{project.id}/repository_size", user)
+
+ expect(response).to have_gitlab_http_status(:created)
+ end
+ end
+
+ context 'when authenticated as developer' do
+ before do
+ project_member
+ end
+
+ it 'returns forbidden error' do
+ post api("/projects/#{project.id}/repository_size", user3)
+
+ expect(response).to have_gitlab_http_status(:forbidden)
+ end
+ end
+
+ context 'when unauthenticated' do
+ it 'returns authentication error' do
+ post api("/projects/#{project.id}/repository_size")
+
+ expect(response).to have_gitlab_http_status(:unauthorized)
+ end
+ end
+ end
describe 'PUT /projects/:id/transfer' do
context 'when authenticated as owner' do
let(:group) { create :group }
diff --git a/spec/rubocop/cop/gitlab/namespaced_class_spec.rb b/spec/rubocop/cop/gitlab/namespaced_class_spec.rb
index 824a1b8cef5..d9209a8672c 100644
--- a/spec/rubocop/cop/gitlab/namespaced_class_spec.rb
+++ b/spec/rubocop/cop/gitlab/namespaced_class_spec.rb
@@ -1,72 +1,125 @@
# frozen_string_literal: true
require 'fast_spec_helper'
-require 'rubocop/rspec/support'
require_relative '../../../../rubocop/cop/gitlab/namespaced_class'
RSpec.describe RuboCop::Cop::Gitlab::NamespacedClass do
subject(:cop) { described_class.new }
- it 'flags a class definition without namespace' do
- expect_offense(<<~SOURCE)
- class MyClass
- ^^^^^^^^^^^^^ #{described_class::MSG}
- end
- SOURCE
- end
+ shared_examples 'enforces namespaced classes' do
+ def namespaced(code)
+ return code unless namespace
- it 'flags a class definition with inheritance without namespace' do
- expect_offense(<<~SOURCE)
- class MyClass < ApplicationRecord
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{described_class::MSG}
- def some_method
- true
+ <<~SOURCE
+ module #{namespace}
+ #{code}
end
- end
- SOURCE
- end
+ SOURCE
+ end
+
+ it 'flags a class definition without additional namespace' do
+ expect_offense(namespaced(<<~SOURCE))
+ class MyClass
+ ^^^^^^^^^^^^^ #{described_class::MSG}
+ end
+ SOURCE
+ end
- it 'does not flag the class definition with namespace in separate lines' do
- expect_no_offenses(<<~SOURCE)
- module MyModule
+ it 'flags a compact class definition without additional namespace' do
+ expect_offense(<<~SOURCE, namespace: namespace)
+ class %{namespace}::MyClass
+ ^{namespace}^^^^^^^^^^^^^^^ #{described_class::MSG}
+ end
+ SOURCE
+ end
+
+ it 'flags a class definition with inheritance without additional namespace' do
+ expect_offense(namespaced(<<~SOURCE))
class MyClass < ApplicationRecord
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{described_class::MSG}
+ def some_method
+ true
+ end
end
+ SOURCE
+ end
- class MyOtherClass
- def other_method
- 1 + 1
+ it 'does not flag the class definition with namespace in separate lines' do
+ expect_no_offenses(namespaced(<<~SOURCE))
+ module MyModule
+ class MyClass < ApplicationRecord
+ end
+
+ class MyOtherClass
+ def other_method
+ 1 + 1
+ end
end
end
- end
- SOURCE
- end
+ SOURCE
+ end
- it 'does not flag the class definition with nested namespace in separate lines' do
- expect_no_offenses(<<~SOURCE)
- module TopLevelModule
- module NestedModule
- class MyClass
+ it 'does not flag the class definition with nested namespace in separate lines' do
+ expect_no_offenses(namespaced(<<~SOURCE))
+ module TopLevelModule
+ module NestedModule
+ class MyClass
+ end
end
end
- end
- SOURCE
- end
+ SOURCE
+ end
+
+ it 'does not flag the class definition nested inside namespaced class' do
+ expect_no_offenses(namespaced(<<~SOURCE))
+ module TopLevelModule
+ class TopLevelClass
+ class MyClass
+ end
+ end
+ end
+ SOURCE
+ end
- it 'does not flag the class definition nested inside namespaced class' do
- expect_no_offenses(<<~SOURCE)
- module TopLevelModule
- class TopLevelClass
+ it 'does not flag the class definition nested inside compact namespace' do
+ expect_no_offenses(<<~SOURCE)
+ module #{namespace}::TopLevelModule
class MyClass
end
end
- end
- SOURCE
+ SOURCE
+ end
+
+ it 'does not flag a compact namespaced class definition' do
+ expect_no_offenses(namespaced(<<~SOURCE))
+ class MyModule::MyClass < ApplicationRecord
+ end
+ SOURCE
+ end
+
+ it 'does not flag a truly compact namespaced class definition' do
+ expect_no_offenses(<<~SOURCE, namespace: namespace)
+ class %{namespace}::MyModule::MyClass < ApplicationRecord
+ end
+ SOURCE
+ end
end
- it 'does not flag a compact namespaced class definition' do
- expect_no_offenses(<<~SOURCE)
- class MyModule::MyClass < ApplicationRecord
- end
- SOURCE
+ context 'without top-level namespace' do
+ let(:namespace) { nil }
+
+ it_behaves_like 'enforces namespaced classes'
+ end
+
+ context 'with Gitlab namespace' do
+ let(:namespace) { 'Gitlab' }
+
+ it_behaves_like 'enforces namespaced classes'
+ end
+
+ context 'with ::Gitlab namespace' do
+ let(:namespace) { '::Gitlab' }
+
+ it_behaves_like 'enforces namespaced classes'
end
end
diff --git a/spec/support/shared_examples/graphql/types/gitlab_style_deprecations_shared_examples.rb b/spec/support/shared_examples/graphql/types/gitlab_style_deprecations_shared_examples.rb
index 3caf153c2fa..cf9c36fafe8 100644
--- a/spec/support/shared_examples/graphql/types/gitlab_style_deprecations_shared_examples.rb
+++ b/spec/support/shared_examples/graphql/types/gitlab_style_deprecations_shared_examples.rb
@@ -6,7 +6,7 @@ RSpec.shared_examples 'Gitlab-style deprecations' do
expect { subject(deprecation_reason: 'foo') }.to raise_error(
ArgumentError,
'Use `deprecated` property instead of `deprecation_reason`. ' \
- 'See https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#deprecating-fields-arguments-and-enum-values'
+ 'See https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#deprecating-schema-items'
)
end
diff --git a/spec/tasks/gitlab/backup_rake_spec.rb b/spec/tasks/gitlab/backup_rake_spec.rb
index 6080948403d..52a0a9a7385 100644
--- a/spec/tasks/gitlab/backup_rake_spec.rb
+++ b/spec/tasks/gitlab/backup_rake_spec.rb
@@ -377,21 +377,6 @@ RSpec.describe 'gitlab:app namespace rake task', :delete do
expect(tar_lines).to include(a_string_matching(repo_name))
end
end
-
- def move_repository_to_secondary(record)
- Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- default_shard_legacy_path = Gitlab.config.repositories.storages.default.legacy_disk_path
- secondary_legacy_path = Gitlab.config.repositories.storages[second_storage_name].legacy_disk_path
- dst_dir = File.join(secondary_legacy_path, File.dirname(record.disk_path))
-
- FileUtils.mkdir_p(dst_dir) unless Dir.exist?(dst_dir)
-
- FileUtils.mv(
- File.join(default_shard_legacy_path, record.disk_path + '.git'),
- File.join(secondary_legacy_path, record.disk_path + '.git')
- )
- end
- end
end
context 'no concurrency' do
@@ -405,6 +390,66 @@ RSpec.describe 'gitlab:app namespace rake task', :delete do
it_behaves_like 'includes repositories in all repository storages'
end
+
+ context 'REPOSITORIES_STORAGES set' do
+ before do
+ stub_env('REPOSITORIES_STORAGES', default_storage_name)
+ end
+
+ it 'includes repositories in default repository storage', :aggregate_failures do
+ project_a = create(:project, :repository)
+ project_snippet_a = create(:project_snippet, :repository, project: project_a, author: project_a.first_owner)
+ project_b = create(:project, :repository, repository_storage: second_storage_name)
+ project_snippet_b = create(:project_snippet, :repository, project: project_b, author: project_b.first_owner)
+ project_snippet_b.snippet_repository.update!(shard: project_b.project_repository.shard)
+ create(:wiki_page, container: project_a)
+ create(:design, :with_file, issue: create(:issue, project: project_a))
+
+ move_repository_to_secondary(project_b)
+ move_repository_to_secondary(project_snippet_b)
+
+ expect { run_rake_task('gitlab:backup:create') }.to output.to_stdout_from_any_process
+
+ tar_contents, exit_status = Gitlab::Popen.popen(
+ %W{tar -tvf #{backup_tar} repositories}
+ )
+
+ tar_lines = tar_contents.lines.grep(/\.bundle/)
+
+ expect(exit_status).to eq(0)
+
+ [
+ "#{project_a.disk_path}/.+/001.bundle",
+ "#{project_a.disk_path}.wiki/.+/001.bundle",
+ "#{project_a.disk_path}.design/.+/001.bundle",
+ "#{project_snippet_a.disk_path}/.+/001.bundle"
+ ].each do |repo_name|
+ expect(tar_lines).to include(a_string_matching(repo_name))
+ end
+
+ [
+ "#{project_b.disk_path}/.+/001.bundle",
+ "#{project_snippet_b.disk_path}/.+/001.bundle"
+ ].each do |repo_name|
+ expect(tar_lines).not_to include(a_string_matching(repo_name))
+ end
+ end
+ end
+
+ def move_repository_to_secondary(record)
+ Gitlab::GitalyClient::StorageSettings.allow_disk_access do
+ default_shard_legacy_path = Gitlab.config.repositories.storages.default.legacy_disk_path
+ secondary_legacy_path = Gitlab.config.repositories.storages[second_storage_name].legacy_disk_path
+ dst_dir = File.join(secondary_legacy_path, File.dirname(record.disk_path))
+
+ FileUtils.mkdir_p(dst_dir) unless Dir.exist?(dst_dir)
+
+ FileUtils.mv(
+ File.join(default_shard_legacy_path, record.disk_path + '.git'),
+ File.join(secondary_legacy_path, record.disk_path + '.git')
+ )
+ end
+ end
end
context 'concurrency settings' do
@@ -420,7 +465,7 @@ RSpec.describe 'gitlab:app namespace rake task', :delete do
stub_env('GITLAB_BACKUP_MAX_STORAGE_CONCURRENCY', 2)
expect(::Backup::Repositories).to receive(:new)
- .with(anything, strategy: anything)
+ .with(anything, strategy: anything, storages: [])
.and_call_original
expect(::Backup::GitalyBackup).to receive(:new).with(anything, max_parallelism: 5, storage_parallelism: 2, incremental: false).and_call_original
diff --git a/spec/views/projects/tags/index.html.haml_spec.rb b/spec/views/projects/tags/index.html.haml_spec.rb
index 664f05428f4..ae59c1aa4b2 100644
--- a/spec/views/projects/tags/index.html.haml_spec.rb
+++ b/spec/views/projects/tags/index.html.haml_spec.rb
@@ -27,7 +27,7 @@ RSpec.describe 'projects/tags/index.html.haml' do
it 'renders links to the Releases page for tags associated with a release' do
render
- expect(rendered).to have_link(release.name, href: project_release_path(project, release.tag))
+ expect(rendered).to have_link(release.name, href: project_releases_path(project, anchor: release.tag))
end
context 'when the most recent build for a tag has artifacts' do
diff --git a/spec/workers/every_sidekiq_worker_spec.rb b/spec/workers/every_sidekiq_worker_spec.rb
index ca858bcba19..2252b9a4ca2 100644
--- a/spec/workers/every_sidekiq_worker_spec.rb
+++ b/spec/workers/every_sidekiq_worker_spec.rb
@@ -383,7 +383,7 @@ RSpec.describe 'Every Sidekiq worker' do
'ProjectDailyStatisticsWorker' => 3,
'ProjectDestroyWorker' => 3,
'ProjectExportWorker' => false,
- 'ProjectImportScheduleWorker' => false,
+ 'ProjectImportScheduleWorker' => 1,
'ProjectScheduleBulkRepositoryShardMovesWorker' => 3,
'ProjectServiceWorker' => 3,
'ProjectTemplateExportWorker' => false,