diff options
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, |