diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-11-05 21:08:48 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-11-05 21:08:48 +0300 |
commit | 3e1c760141a27097d74d191a619fa6edecd86fe7 (patch) | |
tree | dc26e1842b355d2ebad6c8923077b0a016aa82c9 | |
parent | 74dd67ddea70f70830f3fe1ca65b06b604ec229f (diff) |
Add latest changes from gitlab-org/gitlab@master
84 files changed, 3016 insertions, 1687 deletions
diff --git a/.rubocop.yml b/.rubocop.yml index 13448a918b8..bcdc8251033 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -7,9 +7,11 @@ require: - rubocop-rspec inherit_from: + - .rubocop_manual_todo.yml - .rubocop_todo.yml - ./rubocop/rubocop-migrations.yml - ./rubocop/rubocop-usage-data.yml + - ./rubocop/rubocop-code_reuse.yml inherit_mode: merge: diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml new file mode 100644 index 00000000000..a236073c089 --- /dev/null +++ b/.rubocop_manual_todo.yml @@ -0,0 +1,755 @@ +FactoryBot/InlineAssociation: + Exclude: + - 'ee/spec/factories/analytics/cycle_analytics/group_stages.rb' + - 'ee/spec/factories/geo/event_log.rb' + - 'ee/spec/factories/groups.rb' + - 'ee/spec/factories/merge_request_blocks.rb' + - 'ee/spec/factories/vulnerabilities/feedback.rb' + - 'spec/factories/atlassian_identities.rb' + - 'spec/factories/design_management/design_at_version.rb' + - 'spec/factories/design_management/designs.rb' + - 'spec/factories/design_management/versions.rb' + - 'spec/factories/events.rb' + - 'spec/factories/git_wiki_commit_details.rb' + - 'spec/factories/gitaly/commit.rb' + - 'spec/factories/go_module_commits.rb' + - 'spec/factories/go_module_versions.rb' + - 'spec/factories/go_modules.rb' + - 'spec/factories/group_group_links.rb' + - 'spec/factories/import_export_uploads.rb' + - 'spec/factories/merge_requests.rb' + - 'spec/factories/notes.rb' + - 'spec/factories/packages.rb' + - 'spec/factories/packages/package_file.rb' + - 'spec/factories/sent_notifications.rb' + - 'spec/factories/uploads.rb' + - 'spec/factories/wiki_pages.rb' + +Graphql/IDType: + Exclude: + - 'ee/app/graphql/ee/mutations/issues/update.rb' + - 'ee/app/graphql/mutations/iterations/update.rb' + - 'ee/app/graphql/resolvers/iterations_resolver.rb' + - 'app/graphql/mutations/boards/issues/issue_move_list.rb' + - 'app/graphql/mutations/issues/update.rb' + - 'app/graphql/mutations/metrics/dashboard/annotations/delete.rb' + - 'app/graphql/mutations/snippets/destroy.rb' + - 'app/graphql/mutations/snippets/mark_as_spam.rb' + - 'app/graphql/mutations/snippets/update.rb' + - 'app/graphql/resolvers/design_management/design_at_version_resolver.rb' + - 'app/graphql/resolvers/design_management/design_resolver.rb' + - 'app/graphql/resolvers/design_management/designs_resolver.rb' + - 'app/graphql/resolvers/design_management/version/design_at_version_resolver.rb' + - 'app/graphql/resolvers/design_management/version_in_collection_resolver.rb' + - 'app/graphql/resolvers/design_management/version_resolver.rb' + - 'app/graphql/resolvers/design_management/versions_resolver.rb' + - 'app/graphql/resolvers/error_tracking/sentry_detailed_error_resolver.rb' + - 'app/graphql/resolvers/error_tracking/sentry_error_stack_trace_resolver.rb' + - 'app/graphql/resolvers/snippets_resolver.rb' + - 'app/graphql/resolvers/user_merge_requests_resolver.rb' + +Rails/SaveBang: + Exclude: + - 'ee/spec/controllers/projects/merge_requests_controller_spec.rb' + - 'ee/spec/controllers/subscriptions_controller_spec.rb' + - 'ee/spec/frontend/fixtures/analytics.rb' + - 'ee/spec/graphql/resolvers/vulnerabilities_resolver_spec.rb' + - 'ee/spec/initializers/fog_google_https_private_urls_spec.rb' + - 'ee/spec/lib/analytics/merge_request_metrics_calculator_spec.rb' + - 'ee/spec/lib/ee/gitlab/auth/ldap/sync/group_spec.rb' + - 'ee/spec/lib/ee/gitlab/checks/push_rules/commit_check_spec.rb' + - 'ee/spec/lib/ee/gitlab/ci/pipeline/quota/activity_spec.rb' + - 'ee/spec/lib/gitlab/auth/ldap/access_spec.rb' + - 'ee/spec/lib/gitlab/auth/o_auth/user_spec.rb' + - 'ee/spec/lib/gitlab/auth/saml/user_spec.rb' + - 'ee/spec/lib/gitlab/background_migration/fix_orphan_promoted_issues_spec.rb' + - 'ee/spec/lib/gitlab/elastic/search_results_spec.rb' + - 'ee/spec/lib/gitlab/email/handler/ee/service_desk_handler_spec.rb' + - 'ee/spec/lib/gitlab/geo_spec.rb' + - 'ee/spec/lib/gitlab/git_access_spec.rb' + - 'ee/spec/lib/gitlab/import_export/group/relation_factory_spec.rb' + - 'ee/spec/lib/gitlab/mirror_spec.rb' + - 'ee/spec/mailers/notify_spec.rb' + - 'ee/spec/migrations/fix_any_approver_rule_for_projects_spec.rb' + - 'ee/spec/migrations/geo/migrate_ci_job_artifacts_to_separate_registry_spec.rb' + - 'ee/spec/migrations/geo/migrate_lfs_objects_to_separate_registry_spec.rb' + - 'ee/spec/migrations/schedule_merge_request_any_approval_rule_migration_spec.rb' + - 'ee/spec/migrations/schedule_project_any_approval_rule_migration_spec.rb' + - 'ee/spec/models/application_setting_spec.rb' + - 'ee/spec/models/approval_merge_request_rule_spec.rb' + - 'ee/spec/models/approval_project_rule_spec.rb' + - 'ee/spec/models/burndown_spec.rb' + - 'ee/spec/models/ci/pipeline_spec.rb' + - 'ee/spec/models/ci/subscriptions/project_spec.rb' + - 'ee/spec/models/ee/appearance_spec.rb' + - 'ee/spec/models/ee/ci/job_artifact_spec.rb' + - 'ee/spec/models/ee/protected_branch_spec.rb' + - 'ee/spec/models/ee/protected_ref_access_spec.rb' + - 'ee/spec/models/ee/protected_ref_spec.rb' + - 'ee/spec/models/elasticsearch_indexed_namespace_spec.rb' + - 'ee/spec/models/environment_spec.rb' + - 'ee/spec/models/epic_spec.rb' + - 'ee/spec/models/geo/project_registry_spec.rb' + - 'ee/spec/models/geo_node_spec.rb' + - 'ee/spec/models/geo_node_status_spec.rb' + - 'ee/spec/models/gitlab_subscription_spec.rb' + - 'ee/spec/models/group_spec.rb' + - 'ee/spec/models/issue_spec.rb' + - 'ee/spec/models/label_note_spec.rb' + - 'ee/spec/models/lfs_object_spec.rb' + - 'ee/spec/models/license_spec.rb' + - 'ee/spec/models/merge_request_spec.rb' + - 'ee/spec/models/merge_train_spec.rb' + - 'spec/models/packages/package_spec.rb' + - 'ee/spec/models/project_ci_cd_setting_spec.rb' + - 'ee/spec/models/project_spec.rb' + - 'ee/spec/models/protected_environment_spec.rb' + - 'ee/spec/models/repository_spec.rb' + - 'ee/spec/models/scim_identity_spec.rb' + - 'ee/spec/models/scim_oauth_access_token_spec.rb' + - 'ee/spec/models/upload_spec.rb' + - 'ee/spec/models/user_preference_spec.rb' + - 'ee/spec/models/user_spec.rb' + - 'ee/spec/models/visible_approvable_spec.rb' + - 'ee/spec/models/vulnerabilities/feedback_spec.rb' + - 'ee/spec/models/vulnerabilities/issue_link_spec.rb' + - 'ee/spec/presenters/audit_event_presenter_spec.rb' + - 'ee/spec/presenters/epic_presenter_spec.rb' + - 'ee/spec/requests/api/boards_spec.rb' + - 'ee/spec/requests/api/epic_issues_spec.rb' + - 'ee/spec/requests/api/epic_links_spec.rb' + - 'ee/spec/requests/api/epics_spec.rb' + - 'ee/spec/requests/api/geo_nodes_spec.rb' + - 'ee/spec/requests/api/geo_spec.rb' + - 'ee/spec/requests/api/graphql/group/epics_spec.rb' + - 'ee/spec/requests/api/graphql/mutations/epic_tree/reorder_spec.rb' + - 'ee/spec/requests/api/groups_spec.rb' + - 'ee/spec/requests/api/issues_spec.rb' + - 'ee/spec/requests/api/ldap_group_links_spec.rb' + - 'ee/spec/requests/api/merge_request_approval_rules_spec.rb' + - 'ee/spec/requests/api/merge_request_approvals_spec.rb' + - 'ee/spec/requests/api/merge_requests_spec.rb' + - 'ee/spec/requests/api/project_approvals_spec.rb' + - 'ee/spec/requests/api/projects_spec.rb' + - 'ee/spec/requests/api/protected_branches_spec.rb' + - 'ee/spec/requests/api/scim_spec.rb' + - 'ee/spec/requests/api/todos_spec.rb' + - 'ee/spec/requests/lfs_http_spec.rb' + - 'ee/spec/services/approval_rules/finalize_service_spec.rb' + - 'ee/spec/services/approval_rules/update_service_spec.rb' + - 'ee/spec/services/ee/boards/issues/create_service_spec.rb' + - 'ee/spec/services/ee/boards/issues/list_service_spec.rb' + - 'ee/spec/services/ee/boards/lists/list_service_spec.rb' + - 'ee/spec/services/ee/issuable/clone/attributes_rewriter_spec.rb' + - 'ee/spec/services/ee/issuable/common_system_notes_service_spec.rb' + - 'ee/spec/services/ee/issues/update_service_spec.rb' + - 'ee/spec/services/ee/merge_requests/refresh_service_spec.rb' + - 'ee/spec/services/ee/merge_requests/update_service_spec.rb' + - 'ee/spec/services/ee/notes/quick_actions_service_spec.rb' + - 'ee/spec/services/ee/notification_service_spec.rb' + - 'ee/spec/services/epic_links/create_service_spec.rb' + - 'ee/spec/services/epics/close_service_spec.rb' + - 'ee/spec/services/epics/issue_promote_service_spec.rb' + - 'ee/spec/services/epics/reopen_service_spec.rb' + - 'ee/spec/services/epics/tree_reorder_service_spec.rb' + - 'ee/spec/services/epics/update_dates_service_spec.rb' + - 'ee/spec/services/epics/update_service_spec.rb' + - 'ee/spec/services/geo/blob_verification_secondary_service_spec.rb' + - 'ee/spec/services/geo/files_expire_service_spec.rb' + - 'ee/spec/services/geo/metrics_update_service_spec.rb' + - 'ee/spec/services/geo/registry_consistency_service_spec.rb' + - 'ee/spec/services/geo/repository_verification_secondary_service_spec.rb' + - 'ee/spec/services/groups/autocomplete_service_spec.rb' + - 'ee/spec/services/ldap_group_reset_service_spec.rb' + - 'ee/spec/services/lfs/unlock_file_service_spec.rb' + - 'ee/spec/services/merge_trains/refresh_merge_request_service_spec.rb' + - 'ee/spec/services/quick_actions/interpret_service_spec.rb' + - 'ee/spec/services/slash_commands/global_slack_handler_spec.rb' + - 'ee/spec/services/start_pull_mirroring_service_spec.rb' + - 'ee/spec/services/status_page/trigger_publish_service_spec.rb' + - 'ee/spec/services/todo_service_spec.rb' + - 'ee/spec/services/update_build_minutes_service_spec.rb' + - 'ee/spec/services/vulnerability_feedback/create_service_spec.rb' + - 'ee/spec/support/protected_tags/access_control_shared_examples.rb' + - 'ee/spec/support/shared_examples/features/protected_branches_access_control_shared_examples.rb' + - 'ee/spec/support/shared_examples/finders/geo/framework_registry_finder_shared_examples.rb' + - 'ee/spec/support/shared_examples/graphql/geo/geo_registries_resolver_shared_examples.rb' + - 'ee/spec/support/shared_examples/lib/analytics/common_merge_request_metrics_refresh_shared_examples.rb' + - 'ee/spec/support/shared_examples/policies/protected_environments_shared_examples.rb' + - 'ee/spec/workers/adjourned_project_deletion_worker_spec.rb' + - 'ee/spec/workers/clear_shared_runners_minutes_worker_spec.rb' + - 'ee/spec/workers/create_github_webhook_worker_spec.rb' + - 'ee/spec/workers/elastic_namespace_rollout_worker_spec.rb' + - 'ee/spec/workers/geo/container_repository_sync_dispatch_worker_spec.rb' + - 'ee/spec/workers/geo/file_download_dispatch_worker_spec.rb' + - 'ee/spec/workers/geo/prune_event_log_worker_spec.rb' + - 'ee/spec/workers/geo/registry_sync_worker_spec.rb' + - 'ee/spec/workers/geo/repository_shard_sync_worker_spec.rb' + - 'ee/spec/workers/repository_import_worker_spec.rb' + - 'ee/spec/workers/update_all_mirrors_worker_spec.rb' + - 'qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb' + - 'qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_lfs_over_http_spec.rb' + - 'qa/qa/specs/features/ee/browser_ui/3_create/repository/pull_mirroring_over_http_spec.rb' + - 'qa/qa/specs/features/ee/browser_ui/3_create/repository/pull_mirroring_over_ssh_with_key_spec.rb' + - 'spec/controllers/abuse_reports_controller_spec.rb' + - 'spec/controllers/admin/impersonations_controller_spec.rb' + - 'spec/controllers/admin/runners_controller_spec.rb' + - 'spec/controllers/admin/services_controller_spec.rb' + - 'spec/controllers/boards/issues_controller_spec.rb' + - 'spec/controllers/groups/milestones_controller_spec.rb' + - 'spec/controllers/groups/runners_controller_spec.rb' + - 'spec/controllers/groups/uploads_controller_spec.rb' + - 'spec/controllers/groups_controller_spec.rb' + - 'spec/controllers/oauth/authorizations_controller_spec.rb' + - 'spec/controllers/omniauth_callbacks_controller_spec.rb' + - 'spec/controllers/profiles/emails_controller_spec.rb' + - 'spec/controllers/profiles/notifications_controller_spec.rb' + - 'spec/controllers/projects/artifacts_controller_spec.rb' + - 'spec/controllers/projects/cycle_analytics/events_controller_spec.rb' + - 'spec/controllers/projects/cycle_analytics_controller_spec.rb' + - 'spec/controllers/projects/discussions_controller_spec.rb' + - 'spec/controllers/projects/forks_controller_spec.rb' + - 'spec/controllers/projects/group_links_controller_spec.rb' + - 'spec/controllers/projects/imports_controller_spec.rb' + - 'spec/controllers/projects/issues_controller_spec.rb' + - 'spec/controllers/projects/labels_controller_spec.rb' + - 'spec/controllers/projects/milestones_controller_spec.rb' + - 'spec/controllers/projects/notes_controller_spec.rb' + - 'spec/controllers/projects/pipelines_controller_spec.rb' + - 'spec/controllers/projects/releases/evidences_controller_spec.rb' + - 'spec/controllers/projects/runners_controller_spec.rb' + - 'spec/controllers/projects/starrers_controller_spec.rb' + - 'spec/controllers/projects/uploads_controller_spec.rb' + - 'spec/controllers/projects_controller_spec.rb' + - 'spec/controllers/sent_notifications_controller_spec.rb' + - 'spec/controllers/sessions_controller_spec.rb' + - 'spec/controllers/users_controller_spec.rb' + - 'spec/factories_spec.rb' + - 'spec/features/admin/admin_appearance_spec.rb' + - 'spec/features/admin/admin_labels_spec.rb' + - 'spec/features/admin/admin_mode/login_spec.rb' + - 'spec/features/admin/admin_runners_spec.rb' + - 'spec/features/admin/admin_sees_project_statistics_spec.rb' + - 'spec/features/admin/admin_sees_projects_statistics_spec.rb' + - 'spec/features/admin/admin_users_impersonation_tokens_spec.rb' + - 'spec/features/admin/admin_users_spec.rb' + - 'spec/features/boards/sidebar_spec.rb' + - 'spec/features/calendar_spec.rb' + - 'spec/features/commits_spec.rb' + - 'spec/features/dashboard/datetime_on_tooltips_spec.rb' + - 'spec/features/dashboard/issuables_counter_spec.rb' + - 'spec/features/dashboard/project_member_activity_index_spec.rb' + - 'spec/features/dashboard/projects_spec.rb' + - 'spec/features/error_tracking/user_sees_error_index_spec.rb' + - 'spec/features/groups/members/request_access_spec.rb' + - 'spec/features/issuables/close_reopen_report_toggle_spec.rb' + - 'spec/features/issues/bulk_assignment_labels_spec.rb' + - 'spec/features/issues/gfm_autocomplete_spec.rb' + - 'spec/features/issues/issue_sidebar_spec.rb' + - 'spec/features/issues/note_polling_spec.rb' + - 'spec/features/issues/user_creates_branch_and_merge_request_spec.rb' + - 'spec/features/issues/user_creates_confidential_merge_request_spec.rb' + - 'spec/features/issues/user_edits_issue_spec.rb' + - 'spec/features/issues/user_filters_issues_spec.rb' + - 'spec/features/issues/user_sees_live_update_spec.rb' + - 'spec/features/issues/user_sorts_issues_spec.rb' + - 'spec/features/profiles/emails_spec.rb' + - 'spec/features/profiles/password_spec.rb' + - 'spec/features/profiles/personal_access_tokens_spec.rb' + - 'spec/features/projects/features_visibility_spec.rb' + - 'spec/features/projects/fork_spec.rb' + - 'spec/features/projects/jobs/permissions_spec.rb' + - 'spec/features/projects/jobs_spec.rb' + - 'spec/features/projects/members/user_requests_access_spec.rb' + - 'spec/features/projects/pages_lets_encrypt_spec.rb' + - 'spec/features/projects/pages_spec.rb' + - 'spec/features/projects/pipelines/pipeline_spec.rb' + - 'spec/features/projects/pipelines/pipelines_spec.rb' + - 'spec/features/projects/remote_mirror_spec.rb' + - 'spec/features/projects/services/user_activates_slack_notifications_spec.rb' + - 'spec/features/projects/settings/access_tokens_spec.rb' + - 'spec/features/projects/show/user_sees_deletion_failure_message_spec.rb' + - 'spec/features/projects/user_sees_sidebar_spec.rb' + - 'spec/features/projects/wiki/user_updates_wiki_page_spec.rb' + - 'spec/features/projects/wiki/user_views_wiki_page_spec.rb' + - 'spec/features/projects/wiki/users_views_asciidoc_page_with_includes_spec.rb' + - 'spec/features/runners_spec.rb' + - 'spec/features/security/project/internal_access_spec.rb' + - 'spec/features/security/project/private_access_spec.rb' + - 'spec/features/security/project/public_access_spec.rb' + - 'spec/features/users/login_spec.rb' + - 'spec/features/users/show_spec.rb' + - 'spec/frontend/fixtures/issues.rb' + - 'spec/frontend/fixtures/merge_requests.rb' + - 'spec/graphql/mutations/merge_requests/set_locked_spec.rb' + - 'spec/graphql/mutations/merge_requests/set_wip_spec.rb' + - 'spec/graphql/resolvers/boards_resolver_spec.rb' + - 'spec/initializers/active_record_locking_spec.rb' + - 'spec/initializers/fog_google_https_private_urls_spec.rb' + - 'spec/lib/after_commit_queue_spec.rb' + - 'spec/lib/backup/manager_spec.rb' + - 'spec/lib/banzai/reference_parser/external_issue_parser_spec.rb' + - 'spec/lib/banzai/reference_redactor_spec.rb' + - 'spec/lib/gitlab/alerting/alert_spec.rb' + - 'spec/lib/gitlab/analytics/cycle_analytics/records_fetcher_spec.rb' + - 'spec/lib/gitlab/auth/ldap/user_spec.rb' + - 'spec/lib/gitlab/auth/o_auth/user_spec.rb' + - 'spec/lib/gitlab/auth/saml/user_spec.rb' + - 'spec/lib/gitlab/auth_spec.rb' + - 'spec/lib/gitlab/authorized_keys_spec.rb' + - 'spec/lib/gitlab/background_migration/backfill_deployment_clusters_from_deployments_spec.rb' + - 'spec/lib/gitlab/background_migration/backfill_project_repositories_spec.rb' + - 'spec/lib/gitlab/background_migration/backfill_project_settings_spec.rb' + - 'spec/lib/gitlab/background_migration/backfill_push_rules_id_in_projects_spec.rb' + - 'spec/lib/gitlab/background_migration/backfill_snippet_repositories_spec.rb' + - 'spec/lib/gitlab/background_migration/digest_column_spec.rb' + - 'spec/lib/gitlab/background_migration/encrypt_columns_spec.rb' + - 'spec/lib/gitlab/background_migration/fix_cross_project_label_links_spec.rb' + - 'spec/lib/gitlab/background_migration/fix_projects_without_project_feature_spec.rb' + - 'spec/lib/gitlab/background_migration/fix_projects_without_prometheus_service_spec.rb' + - 'spec/lib/gitlab/background_migration/fix_user_namespace_names_spec.rb' + - 'spec/lib/gitlab/background_migration/fix_user_project_route_names_spec.rb' + - 'spec/lib/gitlab/background_migration/legacy_upload_mover_spec.rb' + - 'spec/lib/gitlab/background_migration/legacy_uploads_migrator_spec.rb' + - 'spec/lib/gitlab/background_migration/link_lfs_objects_projects_spec.rb' + - 'spec/lib/gitlab/background_migration/migrate_issue_trackers_sensitive_data_spec.rb' + - 'spec/lib/gitlab/background_migration/migrate_stage_index_spec.rb' + - 'spec/lib/gitlab/background_migration/migrate_users_bio_to_user_details_spec.rb' + - 'spec/lib/gitlab/background_migration/populate_canonical_emails_spec.rb' + - 'spec/lib/gitlab/background_migration/populate_merge_request_assignees_table_spec.rb' + - 'spec/lib/gitlab/background_migration/populate_user_highest_roles_table_spec.rb' + - 'spec/lib/gitlab/background_migration/recalculate_project_authorizations_spec.rb' + - 'spec/lib/gitlab/background_migration/remove_restricted_todos_spec.rb' + - 'spec/lib/gitlab/background_migration/reset_merge_status_spec.rb' + - 'spec/lib/gitlab/background_migration/set_confidential_note_events_on_services_spec.rb' + - 'spec/lib/gitlab/background_migration/set_confidential_note_events_on_webhooks_spec.rb' + - 'spec/lib/gitlab/bitbucket_server_import/importer_spec.rb' + - 'spec/lib/gitlab/ci/ansi2json/style_spec.rb' + - 'spec/lib/gitlab/ci/status/build/common_spec.rb' + - 'spec/lib/gitlab/cycle_analytics/base_event_fetcher_spec.rb' + - 'spec/lib/gitlab/database/custom_structure_spec.rb' + - 'spec/lib/gitlab/database/partitioning_migration_helpers/table_management_helpers_spec.rb' + - 'spec/lib/gitlab/database_importers/self_monitoring/project/create_service_spec.rb' + - 'spec/lib/gitlab/email/handler/create_note_handler_spec.rb' + - 'spec/lib/gitlab/email/handler/unsubscribe_handler_spec.rb' + - 'spec/lib/gitlab/gfm/reference_rewriter_spec.rb' + - 'spec/lib/gitlab/git_access_spec.rb' + - 'spec/lib/gitlab/gitaly_client/object_pool_service_spec.rb' + - 'spec/lib/gitlab/gitaly_client/repository_service_spec.rb' + - 'spec/lib/gitlab/import_export/avatar_saver_spec.rb' + - 'spec/lib/gitlab/import_export/base/relation_factory_spec.rb' + - 'spec/lib/gitlab/import_export/design_repo_restorer_spec.rb' + - 'spec/lib/gitlab/import_export/fast_hash_serializer_spec.rb' + - 'spec/lib/gitlab/import_export/fork_spec.rb' + - 'spec/lib/gitlab/import_export/group/legacy_tree_saver_spec.rb' + - 'spec/lib/gitlab/import_export/group/relation_factory_spec.rb' + - 'spec/lib/gitlab/import_export/group/tree_saver_spec.rb' + - 'spec/lib/gitlab/import_export/importer_spec.rb' + - 'spec/lib/gitlab/import_export/lfs_restorer_spec.rb' + - 'spec/lib/gitlab/import_export/lfs_saver_spec.rb' + - 'spec/lib/gitlab/import_export/members_mapper_spec.rb' + - 'spec/lib/gitlab/import_export/project/relation_factory_spec.rb' + - 'spec/lib/gitlab/import_export/project/tree_restorer_spec.rb' + - 'spec/lib/gitlab/import_export/project/tree_saver_spec.rb' + - 'spec/lib/gitlab/import_export/repo_restorer_spec.rb' + - 'spec/lib/gitlab/import_export/saver_spec.rb' + - 'spec/lib/gitlab/import_export/snippet_repo_restorer_spec.rb' + - 'spec/lib/gitlab/import_export/snippet_repo_saver_spec.rb' + - 'spec/lib/gitlab/import_export/snippets_repo_restorer_spec.rb' + - 'spec/lib/gitlab/import_export/snippets_repo_saver_spec.rb' + - 'spec/lib/gitlab/import_export/uploads_manager_spec.rb' + - 'spec/lib/gitlab/import_export/uploads_saver_spec.rb' + - 'spec/lib/gitlab/import_export/wiki_restorer_spec.rb' + - 'spec/lib/gitlab/legacy_github_import/importer_spec.rb' + - 'spec/lib/gitlab/legacy_github_import/issue_formatter_spec.rb' + - 'spec/lib/gitlab/legacy_github_import/milestone_formatter_spec.rb' + - 'spec/lib/gitlab/legacy_github_import/pull_request_formatter_spec.rb' + - 'spec/lib/gitlab/lets_encrypt/client_spec.rb' + - 'spec/lib/gitlab/markdown_cache/active_record/extension_spec.rb' + - 'spec/lib/gitlab/markdown_cache/redis/store_spec.rb' + - 'spec/lib/gitlab/middleware/go_spec.rb' + - 'spec/lib/gitlab/shard_health_cache_spec.rb' + - 'spec/lib/mattermost/command_spec.rb' + - 'spec/lib/mattermost/session_spec.rb' + - 'spec/lib/mattermost/team_spec.rb' + - 'spec/mailers/notify_spec.rb' + - 'spec/migrations/20190924152703_migrate_issue_trackers_data_spec.rb' + - 'spec/migrations/20200122123016_backfill_project_settings_spec.rb' + - 'spec/migrations/20200123155929_remove_invalid_jira_data_spec.rb' + - 'spec/migrations/20200127090233_remove_invalid_issue_tracker_data_spec.rb' + - 'spec/migrations/20200130145430_reschedule_migrate_issue_trackers_data_spec.rb' + - 'spec/migrations/20200313203550_remove_orphaned_chat_names_spec.rb' + - 'spec/migrations/20200406102120_backfill_deployment_clusters_from_deployments_spec.rb' + - 'spec/migrations/20200526115436_dedup_mr_metrics_spec.rb' + - 'spec/migrations/add_deploy_token_type_to_deploy_tokens_spec.rb' + - 'spec/migrations/add_incident_settings_to_all_existing_projects_spec.rb' + - 'spec/migrations/add_unique_constraint_to_approvals_user_id_and_merge_request_id_spec.rb' + - 'spec/migrations/backfill_and_add_not_null_constraint_to_released_at_column_on_releases_table_spec.rb' + - 'spec/migrations/backfill_imported_snippet_repositories_spec.rb' + - 'spec/migrations/backfill_releases_table_updated_at_and_add_not_null_constraints_to_timestamps_spec.rb' + - 'spec/migrations/backfill_snippet_repositories_spec.rb' + - 'spec/migrations/encrypt_plaintext_attributes_on_application_settings_spec.rb' + - 'spec/migrations/enqueue_reset_merge_status_second_run_spec.rb' + - 'spec/migrations/enqueue_reset_merge_status_spec.rb' + - 'spec/migrations/fill_file_store_lfs_objects_spec.rb' + - 'spec/migrations/fill_store_uploads_spec.rb' + - 'spec/migrations/fix_null_type_labels_spec.rb' + - 'spec/migrations/fix_pool_repository_source_project_id_spec.rb' + - 'spec/migrations/fix_projects_without_project_feature_spec.rb' + - 'spec/migrations/fix_projects_without_prometheus_services_spec.rb' + - 'spec/migrations/fix_wrong_pages_access_level_spec.rb' + - 'spec/migrations/insert_project_hooks_plan_limits_spec.rb' + - 'spec/migrations/migrate_auto_dev_ops_domain_to_cluster_domain_spec.rb' + - 'spec/migrations/move_limits_from_plans_spec.rb' + - 'spec/migrations/populate_project_statistics_packages_size_spec.rb' + - 'spec/migrations/schedule_link_lfs_objects_projects_spec.rb' + - 'spec/migrations/schedule_populate_merge_request_assignees_table_spec.rb' + - 'spec/migrations/seed_repository_storages_weighted_spec.rb' + - 'spec/models/appearance_spec.rb' + - 'spec/models/application_record_spec.rb' + - 'spec/models/application_setting_spec.rb' + - 'spec/models/clusters/applications/helm_spec.rb' + - 'spec/models/commit_spec.rb' + - 'spec/models/commit_status_spec.rb' + - 'spec/models/container_repository_spec.rb' + - 'spec/models/deploy_keys_project_spec.rb' + - 'spec/models/deploy_token_spec.rb' + - 'spec/models/deployment_spec.rb' + - 'spec/models/design_management/version_spec.rb' + - 'spec/models/diff_discussion_spec.rb' + - 'spec/models/diff_note_spec.rb' + - 'spec/models/email_spec.rb' + - 'spec/models/environment_spec.rb' + - 'spec/models/event_spec.rb' + - 'spec/models/fork_network_spec.rb' + - 'spec/models/generic_commit_status_spec.rb' + - 'spec/models/grafana_integration_spec.rb' + - 'spec/models/group_spec.rb' + - 'spec/models/hooks/system_hook_spec.rb' + - 'spec/models/hooks/web_hook_spec.rb' + - 'spec/models/identity_spec.rb' + - 'spec/models/issue/metrics_spec.rb' + - 'spec/models/issue_spec.rb' + - 'spec/models/jira_import_state_spec.rb' + - 'spec/models/key_spec.rb' + - 'spec/models/lfs_objects_project_spec.rb' + - 'spec/models/member_spec.rb' + - 'spec/models/members/group_member_spec.rb' + - 'spec/models/members/project_member_spec.rb' + - 'spec/models/merge_request_spec.rb' + - 'spec/models/milestone_spec.rb' + - 'spec/models/namespace_spec.rb' + - 'spec/models/note_spec.rb' + - 'spec/models/notification_setting_spec.rb' + - 'spec/models/operations/feature_flag_scope_spec.rb' + - 'spec/models/operations/feature_flags/strategy_spec.rb' + - 'spec/models/operations/feature_flags/user_list_spec.rb' + - 'spec/models/pages_domain_spec.rb' + - 'spec/models/project_auto_devops_spec.rb' + - 'spec/models/project_feature_spec.rb' + - 'spec/models/project_spec.rb' + - 'spec/models/project_team_spec.rb' + - 'spec/models/protectable_dropdown_spec.rb' + - 'spec/models/redirect_route_spec.rb' + - 'spec/models/release_spec.rb' + - 'spec/models/remote_mirror_spec.rb' + - 'spec/models/resource_milestone_event_spec.rb' + - 'spec/models/route_spec.rb' + - 'spec/models/sentry_issue_spec.rb' + - 'spec/models/service_spec.rb' + - 'spec/models/snippet_spec.rb' + - 'spec/models/upload_spec.rb' + - 'spec/models/user_preference_spec.rb' + - 'spec/models/user_spec.rb' + - 'spec/models/user_status_spec.rb' + - 'spec/models/wiki_page/meta_spec.rb' + - 'spec/models/wiki_page_spec.rb' + - 'spec/presenters/ci/build_runner_presenter_spec.rb' + - 'spec/presenters/ci/trigger_presenter_spec.rb' + - 'spec/presenters/packages/conan/package_presenter_spec.rb' + - 'spec/requests/api/ci/runner_spec.rb' + - 'spec/requests/api/commit_statuses_spec.rb' + - 'spec/requests/api/conan_packages_spec.rb' + - 'spec/requests/api/deployments_spec.rb' + - 'spec/requests/api/environments_spec.rb' + - 'spec/requests/api/go_proxy_spec.rb' + - 'spec/requests/api/graphql/mutations/merge_requests/set_labels_spec.rb' + - 'spec/requests/api/graphql/user_query_spec.rb' + - 'spec/requests/api/graphql_spec.rb' + - 'spec/requests/api/group_import_spec.rb' + - 'spec/requests/api/group_milestones_spec.rb' + - 'spec/requests/api/internal/base_spec.rb' + - 'spec/requests/api/issues/get_group_issues_spec.rb' + - 'spec/requests/api/issues/post_projects_issues_spec.rb' + - 'spec/requests/api/jobs_spec.rb' + - 'spec/requests/api/labels_spec.rb' + - 'spec/requests/api/project_import_spec.rb' + - 'spec/requests/projects/cycle_analytics_events_spec.rb' + +Rails/TimeZone: + Enabled: true + Exclude: + - 'lib/gitlab/popen.rb' + - 'ee/lib/delay.rb' + - 'ee/lib/gitlab/elastic/helper.rb' + - 'ee/lib/gitlab/elastic/indexer.rb' + - 'ee/lib/gitlab/geo/base_request.rb' + - 'ee/lib/gitlab/geo/event_gap_tracking.rb' + - 'ee/lib/gitlab/geo/log_cursor/events/design_repository_updated_event.rb' + - 'ee/lib/gitlab/geo/log_cursor/events/repository_updated_event.rb' + - 'ee/lib/gitlab/geo/log_cursor/logger.rb' + - 'ee/lib/gitlab/geo/oauth/login_state.rb' + - 'ee/lib/gitlab/prometheus/queries/cluster_query.rb' + - 'ee/lib/gitlab/prometheus/queries/packet_flow_query.rb' + - 'ee/spec/lib/ee/gitlab/checks/push_rules/commit_check_spec.rb' + - 'ee/spec/lib/ee/gitlab/ci/pipeline/quota/job_activity_spec.rb' + - 'ee/spec/lib/gitlab/analytics/cycle_analytics/data_collector_spec.rb' + - 'ee/spec/lib/gitlab/analytics/cycle_analytics/summary/group/stage_summary_spec.rb' + - 'ee/spec/lib/gitlab/analytics/cycle_analytics/summary/group/stage_time_summary_spec.rb' + - 'ee/spec/lib/gitlab/auth/ldap/access_spec.rb' + - 'ee/spec/lib/gitlab/auth/smartcard/san_extension_spec.rb' + - 'ee/spec/lib/gitlab/auth/smartcard/session_spec.rb' + - 'ee/spec/lib/gitlab/background_migration/fix_orphan_promoted_issues_spec.rb' + - 'ee/spec/lib/gitlab/ci/pipeline/chain/limit/job_activity_spec.rb' + - 'ee/spec/lib/gitlab/elastic/client_spec.rb' + - 'ee/spec/lib/gitlab/geo/base_request_spec.rb' + - 'ee/spec/lib/gitlab/geo/log_cursor/events/cache_invalidation_event_spec.rb' + - 'ee/spec/lib/gitlab/geo/log_cursor/events/container_repository_updated_event_spec.rb' + - 'ee/spec/lib/gitlab/geo/log_cursor/events/design_repository_updated_event_spec.rb' + - 'ee/spec/lib/gitlab/geo/log_cursor/events/event_spec.rb' + - 'ee/spec/lib/gitlab/geo/log_cursor/events/hashed_storage_attachments_event_spec.rb' + - 'ee/spec/lib/gitlab/geo/log_cursor/events/hashed_storage_migrated_event_spec.rb' + - 'ee/spec/lib/gitlab/geo/log_cursor/events/job_artifact_deleted_event_spec.rb' + - 'ee/spec/lib/gitlab/geo/log_cursor/events/lfs_object_deleted_event_spec.rb' + - 'ee/spec/lib/gitlab/geo/log_cursor/events/repositories_changed_event_spec.rb' + - 'ee/spec/lib/gitlab/geo/log_cursor/events/repository_created_event_spec.rb' + - 'ee/spec/lib/gitlab/geo/log_cursor/events/repository_deleted_event_spec.rb' + - 'ee/spec/lib/gitlab/geo/log_cursor/events/repository_renamed_event_spec.rb' + - 'ee/spec/lib/gitlab/geo/log_cursor/events/repository_updated_event_spec.rb' + - 'ee/spec/lib/gitlab/geo/log_cursor/events/reset_checksum_event_spec.rb' + - 'ee/spec/lib/gitlab/geo/log_cursor/events/upload_deleted_event_spec.rb' + - 'ee/spec/lib/gitlab/geo/log_cursor/logger_spec.rb' + - 'ee/spec/lib/gitlab/git_access_spec.rb' + - 'ee/spec/lib/gitlab/prometheus/queries/additional_metrics_deployment_query_spec.rb' + - 'ee/spec/lib/gitlab/prometheus/queries/cluster_query_spec.rb' + - 'ee/spec/lib/gitlab/prometheus/queries/packet_flow_query_spec.rb' + - 'lib/api/helpers.rb' + - 'lib/api/sidekiq_metrics.rb' + - 'lib/backup/manager.rb' + - 'lib/bitbucket_server/representation/base.rb' + - 'lib/gitlab/auth/current_user_mode.rb' + - 'lib/gitlab/auth/ldap/access.rb' + - 'lib/gitlab/chaos.rb' + - 'lib/gitlab/checks/timed_logger.rb' + - 'lib/gitlab/ci/ansi2json/line.rb' + - 'lib/gitlab/ci/pipeline/chain/sequence.rb' + - 'lib/gitlab/ci/pipeline/duration.rb' + - 'lib/gitlab/cycle_analytics/summary/deployment_frequency.rb' + - 'lib/gitlab/database.rb' + - 'lib/gitlab/external_authorization/access.rb' + - 'lib/gitlab/external_authorization/cache.rb' + - 'lib/gitlab/gitaly_client.rb' + - 'lib/gitlab/gitaly_client/ref_service.rb' + - 'lib/gitlab/github_import/representation.rb' + - 'lib/gitlab/grape_logging/loggers/queue_duration_logger.rb' + - 'lib/gitlab/health_checks/base_abstract_check.rb' + - 'lib/gitlab/import_export.rb' + - 'lib/gitlab/instrumentation/elasticsearch_transport.rb' + - 'lib/gitlab/instrumentation/redis_interceptor.rb' + - 'lib/gitlab/instrumentation_helper.rb' + - 'lib/gitlab/kubernetes/helm/certificate.rb' + - 'lib/gitlab/lfs_token.rb' + - 'lib/gitlab/loop_helpers.rb' + - 'lib/gitlab/phabricator_import/representation/task.rb' + - 'lib/gitlab/prometheus/queries/additional_metrics_environment_query.rb' + - 'lib/gitlab/prometheus/queries/matched_metric_query.rb' + - 'lib/gitlab/prometheus_client.rb' + - 'lib/gitlab/sherlock/transaction.rb' + - 'lib/gitlab/task_helpers.rb' + - 'lib/gitlab/x509/tag.rb' + - 'lib/grafana/time_window.rb' + - 'lib/json_web_token/token.rb' + - 'lib/object_storage/direct_upload.rb' + - 'lib/quality/seeders/issues.rb' + - 'lib/rspec_flaky/flaky_example.rb' + - 'lib/rspec_flaky/report.rb' + - 'lib/tasks/gitlab/assets.rake' + - 'lib/tasks/gitlab/backup.rake' + - 'lib/tasks/gitlab/cleanup.rake' + - 'lib/tasks/gitlab/list_repos.rake' + - 'spec/lib/api/helpers_spec.rb' + - 'spec/lib/gitlab/analytics/cycle_analytics/base_query_builder_spec.rb' + - 'spec/lib/gitlab/app_json_logger_spec.rb' + - 'spec/lib/gitlab/app_text_logger_spec.rb' + - 'spec/lib/gitlab/auth/current_user_mode_spec.rb' + - 'spec/lib/gitlab/background_migration/recalculate_project_authorizations_spec.rb' + - 'spec/lib/gitlab/background_migration/wrongfully_confirmed_email_unconfirmer_spec.rb' + - 'spec/lib/gitlab/bitbucket_import/importer_spec.rb' + - 'spec/lib/gitlab/bitbucket_server_import/importer_spec.rb' + - 'spec/lib/gitlab/checks/timed_logger_spec.rb' + - 'spec/lib/gitlab/ci/cron_parser_spec.rb' + - 'spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb' + - 'spec/lib/gitlab/cycle_analytics/usage_data_spec.rb' + - 'spec/lib/gitlab/data_builder/note_spec.rb' + - 'spec/lib/gitlab/database/background_migration_job_spec.rb' + - 'spec/lib/gitlab/database_spec.rb' + - 'spec/lib/gitlab/discussions_diff/file_collection_spec.rb' + - 'spec/lib/gitlab/external_authorization/access_spec.rb' + - 'spec/lib/gitlab/external_authorization/cache_spec.rb' + - 'spec/lib/gitlab/external_authorization/logger_spec.rb' + - 'spec/lib/gitlab/fogbugz_import/importer_spec.rb' + - 'spec/lib/gitlab/git/branch_spec.rb' + - 'spec/lib/gitlab/git/commit_spec.rb' + - 'spec/lib/gitlab/git/repository_spec.rb' + - 'spec/lib/gitlab/git_access_spec.rb' + - 'spec/lib/gitlab/github_import/importer/diff_note_importer_spec.rb' + - 'spec/lib/gitlab/github_import/importer/issue_importer_spec.rb' + - 'spec/lib/gitlab/github_import/importer/issues_importer_spec.rb' + - 'spec/lib/gitlab/github_import/importer/milestones_importer_spec.rb' + - 'spec/lib/gitlab/github_import/importer/note_importer_spec.rb' + - 'spec/lib/gitlab/github_import/importer/pull_request_importer_spec.rb' + - 'spec/lib/gitlab/github_import/importer/releases_importer_spec.rb' + - 'spec/lib/gitlab/github_import/representation/diff_note_spec.rb' + - 'spec/lib/gitlab/github_import/representation/issue_spec.rb' + - 'spec/lib/gitlab/github_import/representation/note_spec.rb' + - 'spec/lib/gitlab/github_import/representation/pull_request_spec.rb' + - 'spec/lib/gitlab/grape_logging/formatters/lograge_with_timestamp_spec.rb' + - 'spec/lib/gitlab/grape_logging/loggers/cloudflare_logger_spec.rb' + - 'spec/lib/gitlab/grape_logging/loggers/queue_duration_logger_spec.rb' + - 'spec/lib/gitlab/graphql_logger_spec.rb' + - 'spec/lib/gitlab/graphs/commits_spec.rb' + - 'spec/lib/gitlab/import_export/project/relation_factory_spec.rb' + - 'spec/lib/gitlab/instrumentation_helper_spec.rb' + - 'spec/lib/gitlab/json_logger_spec.rb' + - 'spec/lib/gitlab/lfs_token_spec.rb' + - 'spec/lib/gitlab/log_timestamp_formatter_spec.rb' + - 'spec/lib/gitlab/middleware/rails_queue_duration_spec.rb' + - 'spec/lib/gitlab/omniauth_logging/json_formatter_spec.rb' + - 'spec/lib/gitlab/phabricator_import/issues/task_importer_spec.rb' + - 'spec/lib/gitlab/phabricator_import/representation/task_spec.rb' + - 'spec/lib/gitlab/prometheus/queries/additional_metrics_deployment_query_spec.rb' + - 'spec/lib/gitlab/prometheus/queries/deployment_query_spec.rb' + - 'spec/lib/gitlab/prometheus/queries/validate_query_spec.rb' + - 'spec/lib/gitlab/sherlock/transaction_spec.rb' + - 'spec/lib/gitlab/sidekiq_logging/json_formatter_spec.rb' + - 'spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/until_executing_spec.rb' + - 'spec/lib/gitlab/updated_notes_paginator_spec.rb' + - 'spec/lib/gitlab/utils/json_size_estimator_spec.rb' + - 'spec/lib/gitlab/x509/signature_spec.rb' + - 'spec/lib/grafana/time_window_spec.rb' + - 'spec/lib/json_web_token/hmac_token_spec.rb' + - 'spec/lib/rspec_flaky/flaky_example_spec.rb' + - 'spec/lib/rspec_flaky/listener_spec.rb' + - 'spec/lib/rspec_flaky/report_spec.rb' + +RSpec/TimecopFreeze: + Exclude: + - 'ee/spec/controllers/admin/application_settings_controller_spec.rb' + - 'ee/spec/controllers/projects/security/network_policies_controller_spec.rb' + - 'ee/spec/features/admin/admin_reset_pipeline_minutes_spec.rb' + - 'ee/spec/features/boards/sidebar_spec.rb' + - 'ee/spec/features/groups/analytics/cycle_analytics/filters_and_data_spec.rb' + - 'ee/spec/features/groups/iteration_spec.rb' + - 'ee/spec/features/projects/mirror_spec.rb' + - 'ee/spec/features/projects/services/prometheus_custom_metrics_spec.rb' + - 'ee/spec/finders/productivity_analytics_finder_spec.rb' + - 'ee/spec/frontend/fixtures/analytics.rb' + - 'ee/spec/helpers/vulnerabilities_helper_spec.rb' + - 'ee/spec/lib/analytics/merge_request_metrics_refresh_spec.rb' + - 'ee/spec/lib/analytics/productivity_analytics_request_params_spec.rb' + - 'ee/spec/lib/ee/gitlab/background_migration/populate_vulnerability_historical_statistics_spec.rb' + - 'ee/spec/lib/gitlab/analytics/cycle_analytics/data_collector_spec.rb' + - 'ee/spec/lib/gitlab/analytics/cycle_analytics/group_stage_time_summary_spec.rb' + - 'ee/spec/lib/gitlab/analytics/cycle_analytics/summary/group/stage_time_summary_spec.rb' + - 'ee/spec/lib/gitlab/analytics/type_of_work/tasks_by_type_spec.rb' + - 'ee/spec/lib/gitlab/auth/group_saml/sso_enforcer_spec.rb' + - 'ee/spec/lib/gitlab/database/load_balancing/host_spec.rb' + - 'ee/spec/lib/gitlab/geo/base_request_spec.rb' + - 'ee/spec/lib/gitlab/geo/event_gap_tracking_spec.rb' + - 'ee/spec/lib/gitlab/geo/git_push_http_spec.rb' + - 'ee/spec/lib/gitlab/geo/log_cursor/daemon_spec.rb' + - 'ee/spec/lib/gitlab/geo/log_cursor/events/repository_updated_event_spec.rb' + - 'ee/spec/lib/gitlab/geo/oauth/login_state_spec.rb' + - 'ee/spec/lib/gitlab/insights/reducers/count_per_period_reducer_spec.rb' + - 'ee/spec/lib/gitlab/prometheus/queries/additional_metrics_environment_query_spec.rb' + - 'ee/spec/lib/gitlab/prometheus/queries/cluster_query_spec.rb' + - 'ee/spec/migrations/populate_vulnerability_historical_statistics_for_year_spec.rb' + - 'ee/spec/migrations/remove_duplicated_cs_findings_spec.rb' + - 'ee/spec/migrations/remove_duplicated_cs_findings_without_vulnerability_id_spec.rb' + - 'ee/spec/migrations/schedule_fix_orphan_promoted_issues_spec.rb' + - 'ee/spec/migrations/schedule_merge_request_any_approval_rule_migration_spec.rb' + - 'ee/spec/migrations/schedule_populate_resolved_on_default_branch_column_spec.rb' + - 'ee/spec/migrations/schedule_populate_vulnerability_historical_statistics_spec.rb' + - 'ee/spec/migrations/schedule_project_any_approval_rule_migration_spec.rb' + - 'ee/spec/migrations/set_resolved_state_on_vulnerabilities_spec.rb' + - 'ee/spec/migrations/20190926180443_schedule_epic_issues_after_epics_move_spec.rb' + - 'ee/spec/models/analytics/cycle_analytics/group_level_spec.rb' + - 'ee/spec/models/burndown_spec.rb' + - 'ee/spec/models/ee/namespace_spec.rb' + - 'ee/spec/models/geo/project_registry_spec.rb' + - 'ee/spec/models/merge_train_spec.rb' + - 'ee/spec/models/productivity_analytics_spec.rb' + - 'ee/spec/models/project_spec.rb' + - 'ee/spec/models/vulnerabilities/export_spec.rb' + - 'ee/spec/requests/api/vulnerabilities_spec.rb' + - 'ee/spec/services/geo/file_download_service_spec.rb' + - 'ee/spec/services/vulnerabilities/confirm_service_spec.rb' + - 'ee/spec/services/vulnerabilities/dismiss_service_spec.rb' + - 'ee/spec/services/vulnerabilities/resolve_service_spec.rb' + - 'ee/spec/services/vulnerabilities/revert_to_detected_service_spec.rb' + - 'ee/spec/services/vulnerability_exports/export_service_spec.rb' + - 'ee/spec/support/shared_contexts/lib/gitlab/insights/reducers/reducers_shared_contexts.rb' + - 'qa/spec/support/repeater_spec.rb' + - 'spec/features/profiles/active_sessions_spec.rb' + - 'spec/features/projects/environments/environment_metrics_spec.rb' + - 'spec/features/users/active_sessions_spec.rb' + - 'spec/lib/atlassian/jira_connect/client_spec.rb' + - 'spec/lib/gitlab/analytics/cycle_analytics/base_query_builder_spec.rb' + - 'spec/lib/gitlab/analytics/cycle_analytics/median_spec.rb' + - 'spec/lib/gitlab/analytics/cycle_analytics/records_fetcher_spec.rb' + - 'spec/lib/gitlab/anonymous_session_spec.rb' + - 'spec/lib/gitlab/auth/unique_ips_limiter_spec.rb' + - 'spec/lib/gitlab/checks/timed_logger_spec.rb' + - 'spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb' + - 'spec/lib/gitlab/cycle_analytics/usage_data_spec.rb' + - 'spec/lib/gitlab/instrumentation_helper_spec.rb' + - 'spec/lib/gitlab/omniauth_logging/json_formatter_spec.rb' + - 'spec/lib/gitlab/puma_logging/json_formatter_spec.rb' + - 'spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb' + - 'spec/lib/json_web_token/hmac_token_spec.rb' + - 'spec/lib/rspec_flaky/flaky_example_spec.rb' + - 'spec/lib/rspec_flaky/listener_spec.rb' + - 'spec/models/active_session_spec.rb' + - 'spec/models/container_repository_spec.rb' + - 'spec/models/pages/lookup_path_spec.rb' + - 'spec/models/project_feature_usage_spec.rb' + - 'spec/requests/api/v3/github_spec.rb' + - 'spec/serializers/entity_date_helper_spec.rb' + - 'spec/support/cycle_analytics_helpers/test_generation.rb' + - 'spec/support/helpers/cycle_analytics_helpers.rb' + - 'spec/support/helpers/javascript_fixtures_helpers.rb' + - 'spec/support/shared_contexts/rack_attack_shared_context.rb' + - 'spec/support/shared_examples/workers/concerns/reenqueuer_shared_examples.rb' + - 'spec/workers/concerns/reenqueuer_spec.rb' + - 'spec/workers/metrics/dashboard/prune_old_annotations_worker_spec.rb' + +RSpec/TimecopTravel: + Exclude: + - 'ee/spec/lib/gitlab/geo/event_gap_tracking_spec.rb' + - 'ee/spec/lib/gitlab/geo/git_push_http_spec.rb' + - 'ee/spec/lib/gitlab/geo/jwt_request_decoder_spec.rb' + - 'ee/spec/lib/gitlab/geo/log_cursor/daemon_spec.rb' + - 'ee/spec/models/broadcast_message_spec.rb' + - 'ee/spec/models/burndown_spec.rb' + - 'qa/spec/support/repeater_spec.rb' + - 'spec/features/users/terms_spec.rb' + - 'spec/lib/feature_spec.rb' + - 'spec/models/broadcast_message_spec.rb' + - 'spec/models/concerns/issuable_spec.rb' + - 'spec/requests/api/ci/runner/jobs_trace_spec.rb' + - 'spec/requests/api/issues/put_projects_issues_spec.rb' + - 'spec/support/shared_contexts/cache_allowed_users_in_namespace_shared_context.rb' + - 'spec/support/shared_examples/requests/api/time_tracking_shared_examples.rb' + - 'spec/support/shared_examples/workers/concerns/reenqueuer_shared_examples.rb' + - 'spec/workers/concerns/reenqueuer_spec.rb' + - 'spec/lib/gitlab/analytics/cycle_analytics/median_spec.rb' diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index bba84800d52..ba6ee058218 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,38 +1,49 @@ # This configuration was generated by -# `rubocop --auto-gen-config --exclude-limit 10000` -# on 2020-08-17 21:05:54 +1200 using RuboCop version 0.82.0. +# `rubocop --auto-gen-config` +# on 2020-10-29 17:35:37 UTC using RuboCop version 0.89.1. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 308 +# Offense count: 310 # Cop supports --auto-correct. Capybara/CurrentPathExpectation: Enabled: false -# Offense count: 1715 +# Offense count: 210 +Capybara/VisibilityMatcher: + Enabled: false + +# Offense count: 1903 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, IndentationWidth. # SupportedStyles: with_first_argument, with_fixed_indentation Layout/ArgumentAlignment: Enabled: false -# Offense count: 413 +# Offense count: 49 +# Cop supports --auto-correct. +# Configuration parameters: AllowAliasSyntax, AllowedMethods. +# AllowedMethods: alias_method, public, protected, private +Layout/EmptyLinesAroundAttributeAccessor: + Enabled: false + +# Offense count: 610 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, IndentationWidth. # SupportedStyles: special_inside_parentheses, consistent, align_brackets Layout/FirstArrayElementIndentation: Enabled: false -# Offense count: 1218 +# Offense count: 1535 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, IndentationWidth. # SupportedStyles: special_inside_parentheses, consistent, align_braces Layout/FirstHashElementIndentation: Enabled: false -# Offense count: 2164 +# Offense count: 2754 # Cop supports --auto-correct. # Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle. # SupportedHashRocketStyles: key, separator, table @@ -41,33 +52,33 @@ Layout/FirstHashElementIndentation: Layout/HashAlignment: Enabled: false -# Offense count: 9396 +# Offense count: 64 # Cop supports --auto-correct. # Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. # URISchemes: http, https Layout/LineLength: Max: 1313 -# Offense count: 94 +# Offense count: 118 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, IndentationWidth. # SupportedStyles: aligned, indented Layout/MultilineOperationIndentation: Enabled: false -# Offense count: 36 +# Offense count: 52 # Cop supports --auto-correct. Layout/SpaceAroundMethodCallOperator: Enabled: false -# Offense count: 642 +# Offense count: 790 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: require_no_space, require_space Layout/SpaceInLambdaLiteral: Enabled: false -# Offense count: 926 +# Offense count: 1110 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters. # SupportedStyles: space, no_space @@ -75,24 +86,90 @@ Layout/SpaceInLambdaLiteral: Layout/SpaceInsideBlockBraces: Enabled: false -# Offense count: 401 +# Offense count: 501 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: space, no_space Layout/SpaceInsideParens: Enabled: false +# Offense count: 18 +Lint/BinaryOperatorWithIdenticalOperands: + Exclude: + - 'app/finders/concerns/time_frame_filter.rb' + - 'ee/spec/lib/ee/gitlab/application_context_spec.rb' + - 'spec/helpers/visibility_level_helper_spec.rb' + - 'spec/lib/gitlab/conan_token_spec.rb' + - 'spec/lib/gitlab/danger/sidekiq_queues_spec.rb' + - 'spec/lib/gitlab/git/conflict/parser_spec.rb' + - 'spec/lib/gitlab/graphql/lazy_spec.rb' + - 'spec/models/ci/build_trace_chunk_spec.rb' + - 'spec/models/clusters/platforms/kubernetes_spec.rb' + - 'spec/models/concerns/where_composite_spec.rb' + - 'spec/models/metrics/dashboard/annotation_spec.rb' + - 'spec/models/repository_spec.rb' + - 'spec/models/ssh_host_key_spec.rb' + +# Offense count: 9 +# Cop supports --auto-correct. +Lint/DeprecatedOpenSSLConstant: + Exclude: + - 'app/services/clusters/kubernetes/configure_istio_ingress_service.rb' + - 'ee/lib/gitlab/geo/oauth/logout_state.rb' + - 'lib/gitlab/conan_token.rb' + - 'lib/gitlab/gitaly_client.rb' + - 'lib/gitlab/kubernetes/helm/certificate.rb' + - 'lib/gitlab/kubernetes/helm/v2/certificate.rb' + - 'spec/lib/gitlab/conan_token_spec.rb' + - 'spec/services/pages_domains/obtain_lets_encrypt_certificate_service_spec.rb' + - 'spec/support/helpers/smime_helper.rb' + - 'spec/support/shared_contexts/requests/api/conan_packages_shared_context.rb' + +# Offense count: 1 +Lint/FloatComparison: + Exclude: + - 'ee/app/models/ee/namespace.rb' + # Offense count: 157 # Configuration parameters: MaximumRangeSize. Lint/MissingCopEnableDirective: Enabled: false -# Offense count: 27 +# Offense count: 14 +Lint/MixedRegexpCaptureTypes: + Exclude: + - 'app/models/alert_management/alert.rb' + - 'app/models/project_services/ewm_service.rb' + - 'app/uploaders/file_uploader.rb' + - 'ee/lib/gitlab/code_owners/reference_extractor.rb' + - 'lib/gitlab/ci/pipeline/expression/lexeme/string.rb' + - 'lib/gitlab/dependency_linker/gemfile_linker.rb' + - 'lib/gitlab/diff/inline_diff.rb' + - 'lib/gitlab/diff/suggestions_parser.rb' + - 'lib/gitlab/github_import/representation/note.rb' + - 'lib/gitlab/metrics/system.rb' + - 'lib/gitlab/request_profiler/profile.rb' + - 'lib/gitlab/slash_commands/issue_move.rb' + - 'lib/gitlab/slash_commands/issue_new.rb' + - 'lib/gitlab/slash_commands/run.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +Lint/NonDeterministicRequireOrder: + Exclude: + - 'rubocop/rubocop.rb' + +# Offense count: 118 # Cop supports --auto-correct. Lint/RedundantCopDisableDirective: Enabled: false # Offense count: 1 +Lint/SelfAssignment: + Exclude: + - 'spec/lib/gitlab/search_context/builder_spec.rb' + +# Offense count: 1 # Cop supports --auto-correct. Lint/SendWithMixinArgument: Exclude: @@ -105,13 +182,34 @@ Lint/StructNewOverride: - 'app/serializers/environment_serializer.rb' - 'lib/gitlab/ci/pipeline/duration.rb' -# Offense count: 65 +# Offense count: 1 +Lint/UnreachableLoop: + Exclude: + - 'qa/qa/runtime/feature.rb' + +# Offense count: 5 +# Configuration parameters: IgnoredMethods. +Metrics/AbcSize: + Max: 59 + +# Offense count: 13 +# Configuration parameters: IgnoredMethods. +Metrics/CyclomaticComplexity: + Max: 25 + +# Offense count: 13 +# Configuration parameters: IgnoredMethods. +Metrics/PerceivedComplexity: + Max: 25 + +# Offense count: 1 # Cop supports --auto-correct. Migration/DepartmentName: - Enabled: false + Exclude: + - 'app/models/commit.rb' -# Offense count: 156 -# Configuration parameters: ExpectMatchingDefinition, Regex, IgnoreExecutableScripts, AllowedAcronyms. +# Offense count: 171 +# Configuration parameters: ExpectMatchingDefinition, CheckDefinitionPathHierarchy, Regex, IgnoreExecutableScripts, AllowedAcronyms. # AllowedAcronyms: CLI, DSL, ACL, API, ASCII, CPU, CSS, DNS, EOF, GUID, HTML, HTTP, HTTPS, ID, IP, JSON, LHS, QPS, RAM, RHS, RPC, SLA, SMTP, SQL, SSH, TCP, TLS, TTL, UDP, UI, UID, UUID, URI, URL, UTF8, VM, XML, XMPP, XSRF, XSS Naming/FileName: Enabled: false @@ -127,7 +225,7 @@ Naming/HeredocDelimiterCase: - 'spec/support/helpers/repo_helpers.rb' - 'spec/support/helpers/seed_repo.rb' -# Offense count: 239 +# Offense count: 263 # Configuration parameters: ForbiddenDelimiters. # ForbiddenDelimiters: (?-mix:(^|\s)(EO[A-Z]{1}|END)(\s|$)) Naming/HeredocDelimiterNaming: @@ -135,19 +233,30 @@ Naming/HeredocDelimiterNaming: # Offense count: 5 # Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames. -# AllowedNames: io, id, to, by, on, in, at, ip, db, os, pp +# AllowedNames: at, by, db, id, in, io, ip, of, on, os, pp, to Naming/MethodParameterName: Exclude: - 'lib/gitlab/diff/inline_diff.rb' - 'spec/support/helpers/key_generator_helper.rb' -# Offense count: 162 +# Offense count: 191 # Cop supports --auto-correct. # Configuration parameters: PreferredName. Naming/RescuedExceptionsVariableName: Enabled: false -# Offense count: 20 +# Offense count: 1 +# Cop supports --auto-correct. +Performance/AncestorsInclude: + Exclude: + - 'lib/gitlab/ci/config/extendable/entry.rb' + +# Offense count: 28 +# Configuration parameters: MinSize. +Performance/CollectionLiteralInLoop: + Enabled: false + +# Offense count: 19 # Cop supports --auto-correct. Performance/Count: Exclude: @@ -159,49 +268,157 @@ Performance/Count: - 'spec/lib/gitlab/git/tree_spec.rb' - 'spec/models/ci/build_spec.rb' - 'spec/support/matchers/exceed_query_limit.rb' + - 'spec/support_specs/helpers/active_record/query_recorder_spec.rb' -# Offense count: 25 +# Offense count: 15 +# Cop supports --auto-correct. +# Configuration parameters: SafeMultiline. +Performance/DeletePrefix: + Exclude: + - 'app/helpers/submodule_helper.rb' + - 'app/workers/concerns/application_worker.rb' + - 'ee/lib/gitlab/geo/git_ssh_proxy.rb' + - 'lib/banzai/filter/repository_link_filter.rb' + - 'lib/gitlab/auth/ldap/dn.rb' + - 'lib/gitlab/gfm/uploads_rewriter.rb' + - 'lib/gitlab/git/ref.rb' + - 'lib/gitlab/project_template.rb' + - 'lib/gitlab/repo_path.rb' + - 'lib/gitlab/setup_helper.rb' + - 'lib/gitlab/time_tracking_formatter.rb' + - 'spec/controllers/projects/artifacts_controller_spec.rb' + - 'spec/lib/gitlab/gfm/uploads_rewriter_spec.rb' + - 'spec/support/helpers/test_env.rb' + +# Offense count: 6 +# Cop supports --auto-correct. +# Configuration parameters: SafeMultiline. +Performance/DeleteSuffix: + Exclude: + - 'app/helpers/submodule_helper.rb' + - 'app/workers/concerns/application_worker.rb' + - 'ee/app/models/geo/upload_registry.rb' + - 'ee/app/workers/geo/file_download_dispatch_worker/attachment_job_finder.rb' + - 'lib/gitlab/repo_path.rb' + - 'lib/sentry/client/issue.rb' + +# Offense count: 13 # Cop supports --auto-correct. Performance/Detect: Exclude: - 'ee/spec/controllers/projects/dependencies_controller_spec.rb' + - 'ee/spec/requests/api/dependencies_spec.rb' + - 'qa/qa/runtime/feature.rb' - 'spec/lib/gitlab/git/tree_spec.rb' - 'spec/lib/gitlab/import_export/project/tree_restorer_spec.rb' - 'spec/models/event_spec.rb' - - 'spec/requests/api/jobs_spec.rb' -# Offense count: 11832 +# Offense count: 19 +# Cop supports --auto-correct. +# Configuration parameters: AutoCorrect. +Performance/StringInclude: + Exclude: + - 'app/helpers/groups_helper.rb' + - 'app/models/snippet_repository.rb' + - 'config/initializers/macos.rb' + - 'config/spring.rb' + - 'ee/app/models/ee/container_registry/event.rb' + - 'ee/lib/gitlab/auth/smartcard/certificate.rb' + - 'lib/gitlab/database/migration_helpers.rb' + - 'lib/kramdown/parser/atlassian_document_format.rb' + - 'lib/prometheus/pid_provider.rb' + - 'qa/qa/ee/page/merge_request/show.rb' + - 'qa/qa/specs/runner.rb' + - 'spec/features/projects/jobs_spec.rb' + - 'spec/lib/gitlab/import_export/project/tree_restorer_spec.rb' + - 'spec/spec_helper.rb' + - 'spec/support_specs/helpers/active_record/query_recorder_spec.rb' + +# Offense count: 9 +# Cop supports --auto-correct. +Performance/Sum: + Exclude: + - 'app/models/application_setting_implementation.rb' + - 'app/models/ci/pipeline.rb' + - 'ee/spec/lib/gitlab/elastic/bulk_indexer_spec.rb' + - 'lib/declarative_policy/rule.rb' + - 'lib/declarative_policy/runner.rb' + - 'lib/gitlab/sherlock/transaction.rb' + - 'lib/gitlab/usage_data.rb' + +# Offense count: 13879 # Configuration parameters: Prefixes. # Prefixes: when, with, without RSpec/ContextWording: Enabled: false -# Offense count: 1121 +# Offense count: 4 +# Configuration parameters: CustomIncludeMethods. +RSpec/EmptyExampleGroup: + Exclude: + - 'ee/spec/services/personal_access_tokens/revoke_invalid_tokens_spec.rb' + - 'spec/services/projects/prometheus/alerts/notify_service_spec.rb' + +# Offense count: 176 +# Cop supports --auto-correct. +RSpec/EmptyLineAfterLetBlock: + Enabled: false + +# Offense count: 1310 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: method_call, block RSpec/ExpectChange: Enabled: false -# Offense count: 751 +RSpec/ExpectGitlabTracking: + Exclude: + - 'ee/spec/requests/api/visual_review_discussions_spec.rb' + - 'ee/spec/services/epics/issue_promote_service_spec.rb' + - 'spec/controllers/groups/registry/repositories_controller_spec.rb' + - 'spec/controllers/projects/registry/repositories_controller_spec.rb' + - 'spec/controllers/projects/registry/tags_controller_spec.rb' + - 'spec/controllers/projects/settings/operations_controller_spec.rb' + - 'spec/lib/api/helpers_spec.rb' + - 'spec/requests/api/project_container_repositories_spec.rb' + - 'spec/support/shared_examples/controllers/trackable_shared_examples.rb' + - 'spec/support/shared_examples/requests/api/discussions_shared_examples.rb' + - 'spec/support/shared_examples/requests/api/packages_shared_examples.rb' + - 'spec/support/shared_examples/requests/api/tracking_shared_examples.rb' + +# Offense count: 888 RSpec/ExpectInHook: Enabled: false -# Offense count: 2188 +# Offense count: 15945 +# Configuration parameters: AllowSubject. +RSpec/MultipleMemoizedHelpers: + Max: 40 + +# Offense count: 2297 # Cop supports --auto-correct. # Configuration parameters: Strict, EnforcedStyle, AllowedExplicitMatchers. # SupportedStyles: inflected, explicit RSpec/PredicateMatcher: Enabled: false -# Offense count: 635 +# Offense count: 98 +RSpec/RepeatedExampleGroupBody: + Enabled: false + +# Offense count: 213 +RSpec/RepeatedExampleGroupDescription: + Enabled: false + +# Offense count: 636 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: and_return, block RSpec/ReturnFromStub: Enabled: false -# Offense count: 518 +# Offense count: 574 +# Cop supports --auto-correct. RSpec/ScatteredLet: Enabled: false @@ -211,6 +428,34 @@ RSpec/ScatteredSetup: - 'spec/requests/api/jobs_spec.rb' # Offense count: 10 +# Configuration parameters: EnforcedStyle. +# SupportedStyles: symbols, strings +RSpec/VariableDefinition: + Exclude: + - 'spec/initializers/mail_encoding_patch_spec.rb' + +# Offense count: 25 +# Configuration parameters: EnforcedStyle, IgnoredPatterns. +# SupportedStyles: snake_case, camelCase +RSpec/VariableName: + Exclude: + - 'spec/features/projects/import_export/import_file_spec.rb' + - 'spec/features/task_lists_spec.rb' + - 'spec/initializers/mail_encoding_patch_spec.rb' + - 'spec/lib/gitlab/experimentation_spec.rb' + - 'spec/models/board_spec.rb' + - 'spec/support/shared_contexts/url_shared_context.rb' + - 'spec/support/shared_examples/requests/api/graphql/group_and_project_boards_query_shared_examples.rb' + - 'spec/support/shared_examples/services/boards/boards_list_service_shared_examples.rb' + +# Offense count: 27 +# Cop supports --auto-correct. +# Configuration parameters: Include. +# Include: app/models/**/*.rb +Rails/ActiveRecordCallbacksOrder: + Enabled: false + +# Offense count: 10 # Cop supports --auto-correct. Rails/ApplicationController: Exclude: @@ -232,41 +477,63 @@ Rails/BelongsTo: - 'app/models/deployment.rb' - 'app/models/environment.rb' -# Offense count: 71 +# Offense count: 84 # Configuration parameters: Database, Include. # SupportedDatabases: mysql, postgresql # Include: db/migrate/*.rb Rails/BulkChangeTable: Enabled: false -# Offense count: 208 +# Offense count: 151 +# Cop supports --auto-correct. +Rails/ContentTag: + Enabled: false + +# Offense count: 270 # Configuration parameters: Include. # Include: db/migrate/*.rb Rails/CreateTableWithTimestamps: Enabled: false -# Offense count: 346 +# Offense count: 323 # Configuration parameters: EnforcedStyle. # SupportedStyles: slashes, arguments Rails/FilePath: Enabled: false -# Offense count: 264 +# Offense count: 15 +# Cop supports --auto-correct. +Rails/FindById: + Exclude: + - 'app/controllers/projects/pipelines_controller.rb' + - 'app/services/concerns/deploy_token_methods.rb' + - 'ee/app/controllers/ee/groups/group_members_controller.rb' + - 'ee/lib/api/audit_events.rb' + - 'ee/lib/api/merge_request_approval_rules.rb' + - 'ee/lib/ee/api/groups.rb' + - 'ee/lib/ee/api/projects.rb' + - 'ee/spec/finders/audit_log_finder_spec.rb' + - 'lib/api/snippets.rb' + - 'spec/finders/concerns/finder_methods_spec.rb' + - 'spec/finders/concerns/finder_with_cross_project_access_spec.rb' + +# Offense count: 329 # Configuration parameters: Include. # Include: app/models/**/*.rb Rails/HasManyOrHasOneDependent: Enabled: false -# Offense count: 467 +# Offense count: 507 # Configuration parameters: Include. # Include: app/helpers/**/*.rb Rails/HelperInstanceVariable: Enabled: false -# Offense count: 15 +# Offense count: 17 # Cop supports --auto-correct. Rails/IndexBy: Exclude: + - 'app/graphql/types/design_management/design_fields.rb' - 'app/models/ci/pipeline.rb' - 'app/services/ci/pipeline_processing/atomic_processing_service/status_collection.rb' - 'ee/app/services/projects/update_mirror_service.rb' @@ -276,21 +543,27 @@ Rails/IndexBy: - 'ee/lib/gitlab/analytics/type_of_work/tasks_by_type.rb' - 'ee/lib/gitlab/elastic/document_reference.rb' - 'ee/lib/gitlab/group_plans_preloader.rb' + - 'lib/gitlab/danger/sidekiq_queues.rb' - 'lib/gitlab/database/count/reltuples_count_strategy.rb' - 'lib/gitlab/language_detection.rb' -# Offense count: 36 +# Offense count: 44 # Cop supports --auto-correct. Rails/IndexWith: Enabled: false -# Offense count: 105 +# Offense count: 1 +Rails/Inquiry: + Exclude: + - 'spec/helpers/labels_helper_spec.rb' + +# Offense count: 112 # Configuration parameters: Include. # Include: app/models/**/*.rb Rails/InverseOf: Enabled: false -# Offense count: 55 +# Offense count: 60 # Configuration parameters: Include. # Include: app/controllers/**/*.rb Rails/LexicallyScopedActionFilter: @@ -304,177 +577,77 @@ Rails/LinkToBlank: - 'app/helpers/wiki_helper.rb' - 'ee/app/helpers/ee/user_callouts_helper.rb' -# Offense count: 34 +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: Include. +# Include: app/mailers/**/*.rb +Rails/MailerName: + Exclude: + - 'app/mailers/notify.rb' + +# Offense count: 48 +# Cop supports --auto-correct. +Rails/NegateInclude: + Enabled: false + +# Offense count: 41 +# Cop supports --auto-correct. +Rails/Pick: + Enabled: false + +# Offense count: 113 +# Cop supports --auto-correct. +Rails/Pluck: + Enabled: false + +# Offense count: 38 +# Cop supports --auto-correct. # Configuration parameters: Include. # Include: **/Rakefile, **/*.rake Rails/RakeEnvironment: Enabled: false -# Offense count: 926 -# Configuration parameters: Blacklist, Whitelist. -# Blacklist: decrement!, decrement_counter, increment!, increment_counter, toggle!, touch, update_all, update_attribute, update_column, update_columns, update_counters -Rails/SkipsModelValidations: +# Offense count: 52 +# Cop supports --auto-correct. +Rails/RedundantForeignKey: Enabled: false -# Offense count: 308 +Rails/RenderInline: + Exclude: + - 'ee/app/controllers/sitemap_controller.rb' + +# Offense count: 4 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. -# SupportedStyles: strict, flexible -Rails/TimeZone: - Enabled: true +# SupportedStyles: conservative, aggressive +Rails/ShortI18n: Exclude: - - 'lib/gitlab/popen.rb' - - 'ee/lib/delay.rb' - - 'ee/lib/gitlab/elastic/helper.rb' - - 'ee/lib/gitlab/elastic/indexer.rb' - - 'ee/lib/gitlab/geo/base_request.rb' - - 'ee/lib/gitlab/geo/event_gap_tracking.rb' - - 'ee/lib/gitlab/geo/log_cursor/events/design_repository_updated_event.rb' - - 'ee/lib/gitlab/geo/log_cursor/events/repository_updated_event.rb' - - 'ee/lib/gitlab/geo/log_cursor/logger.rb' - - 'ee/lib/gitlab/geo/oauth/login_state.rb' - - 'ee/lib/gitlab/prometheus/queries/cluster_query.rb' - - 'ee/lib/gitlab/prometheus/queries/packet_flow_query.rb' - - 'ee/spec/lib/ee/gitlab/checks/push_rules/commit_check_spec.rb' - - 'ee/spec/lib/ee/gitlab/ci/pipeline/quota/job_activity_spec.rb' - - 'ee/spec/lib/gitlab/analytics/cycle_analytics/data_collector_spec.rb' - - 'ee/spec/lib/gitlab/analytics/cycle_analytics/summary/group/stage_summary_spec.rb' - - 'ee/spec/lib/gitlab/analytics/cycle_analytics/summary/group/stage_time_summary_spec.rb' - - 'ee/spec/lib/gitlab/auth/ldap/access_spec.rb' - - 'ee/spec/lib/gitlab/auth/smartcard/san_extension_spec.rb' - - 'ee/spec/lib/gitlab/auth/smartcard/session_spec.rb' - - 'ee/spec/lib/gitlab/background_migration/fix_orphan_promoted_issues_spec.rb' - - 'ee/spec/lib/gitlab/ci/pipeline/chain/limit/job_activity_spec.rb' - - 'ee/spec/lib/gitlab/elastic/client_spec.rb' - - 'ee/spec/lib/gitlab/geo/base_request_spec.rb' - - 'ee/spec/lib/gitlab/geo/log_cursor/events/cache_invalidation_event_spec.rb' - - 'ee/spec/lib/gitlab/geo/log_cursor/events/container_repository_updated_event_spec.rb' - - 'ee/spec/lib/gitlab/geo/log_cursor/events/design_repository_updated_event_spec.rb' - - 'ee/spec/lib/gitlab/geo/log_cursor/events/event_spec.rb' - - 'ee/spec/lib/gitlab/geo/log_cursor/events/hashed_storage_attachments_event_spec.rb' - - 'ee/spec/lib/gitlab/geo/log_cursor/events/hashed_storage_migrated_event_spec.rb' - - 'ee/spec/lib/gitlab/geo/log_cursor/events/job_artifact_deleted_event_spec.rb' - - 'ee/spec/lib/gitlab/geo/log_cursor/events/lfs_object_deleted_event_spec.rb' - - 'ee/spec/lib/gitlab/geo/log_cursor/events/repositories_changed_event_spec.rb' - - 'ee/spec/lib/gitlab/geo/log_cursor/events/repository_created_event_spec.rb' - - 'ee/spec/lib/gitlab/geo/log_cursor/events/repository_deleted_event_spec.rb' - - 'ee/spec/lib/gitlab/geo/log_cursor/events/repository_renamed_event_spec.rb' - - 'ee/spec/lib/gitlab/geo/log_cursor/events/repository_updated_event_spec.rb' - - 'ee/spec/lib/gitlab/geo/log_cursor/events/reset_checksum_event_spec.rb' - - 'ee/spec/lib/gitlab/geo/log_cursor/events/upload_deleted_event_spec.rb' - - 'ee/spec/lib/gitlab/geo/log_cursor/logger_spec.rb' - - 'ee/spec/lib/gitlab/git_access_spec.rb' - - 'ee/spec/lib/gitlab/prometheus/queries/additional_metrics_deployment_query_spec.rb' - - 'ee/spec/lib/gitlab/prometheus/queries/cluster_query_spec.rb' - - 'ee/spec/lib/gitlab/prometheus/queries/packet_flow_query_spec.rb' - - 'lib/api/helpers.rb' - - 'lib/api/sidekiq_metrics.rb' - - 'lib/backup/manager.rb' - - 'lib/bitbucket_server/representation/base.rb' - - 'lib/gitlab/auth/current_user_mode.rb' - - 'lib/gitlab/auth/ldap/access.rb' - - 'lib/gitlab/chaos.rb' - - 'lib/gitlab/checks/timed_logger.rb' - - 'lib/gitlab/ci/ansi2json/line.rb' - - 'lib/gitlab/ci/pipeline/chain/sequence.rb' - - 'lib/gitlab/ci/pipeline/duration.rb' - - 'lib/gitlab/cycle_analytics/summary/deployment_frequency.rb' - - 'lib/gitlab/database.rb' - - 'lib/gitlab/external_authorization/access.rb' - - 'lib/gitlab/external_authorization/cache.rb' - - 'lib/gitlab/gitaly_client.rb' - - 'lib/gitlab/gitaly_client/ref_service.rb' - - 'lib/gitlab/github_import/representation.rb' - - 'lib/gitlab/grape_logging/loggers/queue_duration_logger.rb' - - 'lib/gitlab/health_checks/base_abstract_check.rb' - - 'lib/gitlab/import_export.rb' - - 'lib/gitlab/instrumentation/elasticsearch_transport.rb' - - 'lib/gitlab/instrumentation/redis_interceptor.rb' - - 'lib/gitlab/instrumentation_helper.rb' - - 'lib/gitlab/kubernetes/helm/certificate.rb' - - 'lib/gitlab/lfs_token.rb' - - 'lib/gitlab/loop_helpers.rb' - - 'lib/gitlab/phabricator_import/representation/task.rb' - - 'lib/gitlab/prometheus/queries/additional_metrics_environment_query.rb' - - 'lib/gitlab/prometheus/queries/matched_metric_query.rb' - - 'lib/gitlab/prometheus_client.rb' - - 'lib/gitlab/sherlock/transaction.rb' - - 'lib/gitlab/task_helpers.rb' - - 'lib/gitlab/x509/tag.rb' - - 'lib/grafana/time_window.rb' - - 'lib/json_web_token/token.rb' - - 'lib/object_storage/direct_upload.rb' - - 'lib/quality/seeders/issues.rb' - - 'lib/rspec_flaky/flaky_example.rb' - - 'lib/rspec_flaky/report.rb' - - 'lib/tasks/gitlab/assets.rake' - - 'lib/tasks/gitlab/backup.rake' - - 'lib/tasks/gitlab/cleanup.rake' - - 'lib/tasks/gitlab/list_repos.rake' - - 'spec/lib/api/helpers_spec.rb' - - 'spec/lib/gitlab/analytics/cycle_analytics/base_query_builder_spec.rb' - - 'spec/lib/gitlab/app_json_logger_spec.rb' - - 'spec/lib/gitlab/app_text_logger_spec.rb' - - 'spec/lib/gitlab/auth/current_user_mode_spec.rb' - - 'spec/lib/gitlab/background_migration/recalculate_project_authorizations_spec.rb' - - 'spec/lib/gitlab/background_migration/wrongfully_confirmed_email_unconfirmer_spec.rb' - - 'spec/lib/gitlab/bitbucket_import/importer_spec.rb' - - 'spec/lib/gitlab/bitbucket_server_import/importer_spec.rb' - - 'spec/lib/gitlab/checks/timed_logger_spec.rb' - - 'spec/lib/gitlab/ci/cron_parser_spec.rb' - - 'spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb' - - 'spec/lib/gitlab/cycle_analytics/usage_data_spec.rb' - - 'spec/lib/gitlab/data_builder/note_spec.rb' - - 'spec/lib/gitlab/database/background_migration_job_spec.rb' - - 'spec/lib/gitlab/database_spec.rb' - - 'spec/lib/gitlab/discussions_diff/file_collection_spec.rb' - - 'spec/lib/gitlab/external_authorization/access_spec.rb' - - 'spec/lib/gitlab/external_authorization/cache_spec.rb' - - 'spec/lib/gitlab/external_authorization/logger_spec.rb' - - 'spec/lib/gitlab/fogbugz_import/importer_spec.rb' - - 'spec/lib/gitlab/git/branch_spec.rb' - - 'spec/lib/gitlab/git/commit_spec.rb' - - 'spec/lib/gitlab/git/repository_spec.rb' - - 'spec/lib/gitlab/git_access_spec.rb' - - 'spec/lib/gitlab/github_import/importer/diff_note_importer_spec.rb' - - 'spec/lib/gitlab/github_import/importer/issue_importer_spec.rb' - - 'spec/lib/gitlab/github_import/importer/issues_importer_spec.rb' - - 'spec/lib/gitlab/github_import/importer/milestones_importer_spec.rb' - - 'spec/lib/gitlab/github_import/importer/note_importer_spec.rb' - - 'spec/lib/gitlab/github_import/importer/pull_request_importer_spec.rb' - - 'spec/lib/gitlab/github_import/importer/releases_importer_spec.rb' - - 'spec/lib/gitlab/github_import/representation/diff_note_spec.rb' - - 'spec/lib/gitlab/github_import/representation/issue_spec.rb' - - 'spec/lib/gitlab/github_import/representation/note_spec.rb' - - 'spec/lib/gitlab/github_import/representation/pull_request_spec.rb' - - 'spec/lib/gitlab/grape_logging/formatters/lograge_with_timestamp_spec.rb' - - 'spec/lib/gitlab/grape_logging/loggers/cloudflare_logger_spec.rb' - - 'spec/lib/gitlab/grape_logging/loggers/queue_duration_logger_spec.rb' - - 'spec/lib/gitlab/graphql_logger_spec.rb' - - 'spec/lib/gitlab/graphs/commits_spec.rb' - - 'spec/lib/gitlab/import_export/project/relation_factory_spec.rb' - - 'spec/lib/gitlab/instrumentation_helper_spec.rb' - - 'spec/lib/gitlab/json_logger_spec.rb' - - 'spec/lib/gitlab/lfs_token_spec.rb' - - 'spec/lib/gitlab/log_timestamp_formatter_spec.rb' - - 'spec/lib/gitlab/middleware/rails_queue_duration_spec.rb' - - 'spec/lib/gitlab/omniauth_logging/json_formatter_spec.rb' - - 'spec/lib/gitlab/phabricator_import/issues/task_importer_spec.rb' - - 'spec/lib/gitlab/phabricator_import/representation/task_spec.rb' - - 'spec/lib/gitlab/prometheus/queries/additional_metrics_deployment_query_spec.rb' - - 'spec/lib/gitlab/prometheus/queries/deployment_query_spec.rb' - - 'spec/lib/gitlab/prometheus/queries/validate_query_spec.rb' - - 'spec/lib/gitlab/sherlock/transaction_spec.rb' - - 'spec/lib/gitlab/sidekiq_logging/json_formatter_spec.rb' - - 'spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/until_executing_spec.rb' - - 'spec/lib/gitlab/updated_notes_paginator_spec.rb' - - 'spec/lib/gitlab/utils/json_size_estimator_spec.rb' - - 'spec/lib/gitlab/x509/signature_spec.rb' - - 'spec/lib/grafana/time_window_spec.rb' - - 'spec/lib/json_web_token/hmac_token_spec.rb' - - 'spec/lib/rspec_flaky/flaky_example_spec.rb' - - 'spec/lib/rspec_flaky/listener_spec.rb' - - 'spec/lib/rspec_flaky/report_spec.rb' + - 'app/models/project_services/chat_message/pipeline_message.rb' + - 'app/uploaders/content_type_whitelist.rb' + - 'spec/views/shared/runners/show.html.haml_spec.rb' + +# Offense count: 1043 +# Configuration parameters: ForbiddenMethods, AllowedMethods. +# ForbiddenMethods: decrement!, decrement_counter, increment!, increment_counter, insert, insert!, insert_all, insert_all!, toggle!, touch, touch_all, update_all, update_attribute, update_column, update_columns, update_counters, upsert, upsert_all +Rails/SkipsModelValidations: + Enabled: false + +# Offense count: 202 +# Cop supports --auto-correct. +Rails/SquishedSQLHeredocs: + Enabled: false + +# Offense count: 37 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle. +# SupportedStyles: exists, where +Rails/WhereExists: + Enabled: false + +# Offense count: 21 +# Cop supports --auto-correct. +Rails/WhereNot: + Enabled: false # Offense count: 8 # Cop supports --auto-correct. @@ -486,13 +659,58 @@ Security/YAMLLoad: - 'spec/initializers/secret_token_spec.rb' - 'spec/lib/gitlab/prometheus/additional_metrics_parser_spec.rb' -# Offense count: 148 +# Offense count: 240 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle. +# SupportedStyles: separated, grouped +Style/AccessorGrouping: + Enabled: false + +# Offense count: 13 +# Cop supports --auto-correct. +Style/ArrayCoercion: + Exclude: + - 'app/controllers/admin/ci/variables_controller.rb' + - 'app/controllers/groups/variables_controller.rb' + - 'app/controllers/import/bulk_imports_controller.rb' + - 'app/controllers/projects/variables_controller.rb' + - 'db/migrate/20190620105427_change_null_private_profile_to_false.rb' + - 'db/post_migrate/20190812070645_migrate_private_profile_nulls.rb' + - 'db/post_migrate/20200311130802_schedule_populate_user_highest_roles_table.rb' + - 'db/post_migrate/20200805152108_migrate_null_external_diff_store_to_local_value.rb' + - 'db/post_migrate/20200806173633_migrate_null_package_files_file_store_to_local_value.rb' + - 'ee/app/services/geo/blob_verification_secondary_service.rb' + - 'ee/app/services/geo/repository_verification_secondary_service.rb' + - 'ee/lib/ee/banzai/pipeline/gfm_pipeline.rb' + - 'spec/support/helpers/lfs_http_helpers.rb' + +# Offense count: 176 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: percent_q, bare_percent Style/BarePercentLiterals: Enabled: false +# Offense count: 6 +# Cop supports --auto-correct. +Style/BisectedAttrAccessor: + Exclude: + - 'lib/system_check/base_check.rb' + - 'qa/qa/resource/api_fabricator.rb' + +# Offense count: 37 +# Cop supports --auto-correct. +Style/CaseLikeIf: + Enabled: false + +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SingleLineConditionsOnly, IncludeTernaryExpressions. +# SupportedStyles: assign_to_condition, assign_inside_condition +Style/ConditionalAssignment: + Exclude: + - 'lib/gitlab/database.rb' + # Offense count: 5 # Cop supports --auto-correct. Style/EachWithObject: @@ -503,715 +721,221 @@ Style/EachWithObject: - 'lib/gitlab/i18n/po_linter.rb' - 'lib/gitlab/import_export/members_mapper.rb' -# Offense count: 46 +# Offense count: 53 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: empty, nil, both Style/EmptyElse: Enabled: false -# Offense count: 170 +# Offense count: 193 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: compact, expanded Style/EmptyMethod: Enabled: false -# Offense count: 431 +# Offense count: 2 +# Cop supports --auto-correct. +Style/ExpandPathArguments: + Exclude: + - 'cable/config.ru' + - 'config.ru' + +# Offense count: 118 +# Cop supports --auto-correct. +Style/ExplicitBlockArgument: + Enabled: false + +# Offense count: 521 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: format, sprintf, percent Style/FormatString: Enabled: false -# Offense count: 769 +# Offense count: 48 +# Cop supports --auto-correct. +Style/GlobalStdStream: + Enabled: false + +# Offense count: 835 # Configuration parameters: MinBodyLength. Style/GuardClause: Enabled: false -# Offense count: 47 +# Offense count: 93 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle. +# SupportedStyles: braces, no_braces +Style/HashAsLastArrayItem: + Enabled: false + +# Offense count: 55 # Cop supports --auto-correct. Style/HashEachMethods: Enabled: false -# Offense count: 31 +# Offense count: 30 # Configuration parameters: AllowIfModifier. Style/IfInsideElse: Enabled: false -# Offense count: 1313 +# Offense count: 1798 # Cop supports --auto-correct. Style/IfUnlessModifier: Enabled: false -# Offense count: 377 +# Offense count: 447 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: line_count_dependent, lambda, literal Style/Lambda: Enabled: false -# Offense count: 17 -Style/MethodMissingSuper: - Enabled: false - -# Offense count: 17 +# Offense count: 18 Style/MissingRespondToMissing: Enabled: false -# Offense count: 5 -Style/MixinUsage: - Exclude: - - 'spec/factories/ci/builds.rb' - - 'spec/factories/ci/job_artifacts.rb' - - 'spec/factories/lfs_objects.rb' - - 'spec/factories/notes.rb' - - 'spec/lib/gitlab/import_export/version_checker_spec.rb' - -# Offense count: 29 +# Offense count: 32 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, MinBodyLength. # SupportedStyles: skip_modifier_ifs, always Style/Next: Enabled: false -# Offense count: 89 +# Offense count: 95 # Cop supports --auto-correct. # Configuration parameters: EnforcedOctalStyle. # SupportedOctalStyles: zero_with_o, zero_only Style/NumericLiteralPrefix: Enabled: false -# Offense count: 117 +# Offense count: 132 # Cop supports --auto-correct. Style/ParallelAssignment: Enabled: false -# Offense count: 2035 +# Offense count: 2473 # Cop supports --auto-correct. # Configuration parameters: PreferredDelimiters. Style/PercentLiteralDelimiters: Enabled: false -# Offense count: 200 +# Offense count: 246 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: compact, exploded Style/RaiseArgs: Enabled: false -# Offense count: 246 +# Offense count: 66 +# Cop supports --auto-correct. +Style/RedundantAssignment: + Enabled: false + +# Offense count: 26 +# Cop supports --auto-correct. +# Configuration parameters: SafeForConstants. +Style/RedundantFetchBlock: + Exclude: + - 'app/finders/admin/projects_finder.rb' + - 'lib/gitlab/diff/file.rb' + - 'spec/lib/gitlab/json_cache_spec.rb' + - 'spec/lib/gitlab/metrics/dashboard/cache_spec.rb' + - 'spec/lib/gitlab/null_request_store_spec.rb' + - 'spec/lib/gitlab/safe_request_store_spec.rb' + +# Offense count: 26 +# Cop supports --auto-correct. +Style/RedundantFileExtensionInRequire: + Enabled: false + +# Offense count: 260 # Cop supports --auto-correct. Style/RedundantFreeze: Enabled: false -# Offense count: 123 +# Offense count: 167 # Cop supports --auto-correct. Style/RedundantInterpolation: Enabled: false -# Offense count: 801 +# Offense count: 11 +# Cop supports --auto-correct. +Style/RedundantRegexpCharacterClass: + Exclude: + - 'app/models/concerns/taskable.rb' + - 'ee/lib/ee/gitlab/path_regex.rb' + - 'lib/gitlab/authorized_keys.rb' + - 'lib/gitlab/fogbugz_import/repository.rb' + - 'lib/gitlab/prometheus/internal.rb' + - 'lib/gitlab/quick_actions/substitution_definition.rb' + - 'lib/gitlab/regex.rb' + - 'spec/features/merge_request/user_views_open_merge_request_spec.rb' + - 'spec/tasks/gitlab/usage_data_rake_spec.rb' + +# Offense count: 250 +# Cop supports --auto-correct. +Style/RedundantRegexpEscape: + Enabled: false + +# Offense count: 868 # Cop supports --auto-correct. Style/RedundantSelf: Enabled: false -# Offense count: 120 +# Offense count: 179 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, AllowInnerSlashes. # SupportedStyles: slashes, percent_r, mixed Style/RegexpLiteral: Enabled: false -# Offense count: 46 +# Offense count: 49 # Cop supports --auto-correct. Style/RescueModifier: Enabled: false -# Offense count: 286 +# Offense count: 329 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: implicit, explicit Style/RescueStandardError: Enabled: false -# Offense count: 102 +# Offense count: 104 +# Cop supports --auto-correct. +Style/SingleArgumentDig: + Enabled: false + +# Offense count: 47 +# Cop supports --auto-correct. +Style/SlicingWithRange: + Enabled: false + +# Offense count: 109 # Cop supports --auto-correct. # Configuration parameters: . # SupportedStyles: use_perl_names, use_english_names Style/SpecialGlobalVars: EnforcedStyle: use_perl_names -# Offense count: 93 +# Offense count: 516 +# Cop supports --auto-correct. +Style/StringConcatenation: + Enabled: false + +# Offense count: 103 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. # SupportedStyles: single_quotes, double_quotes Style/StringLiteralsInInterpolation: Enabled: false -# Offense count: 233 +# Offense count: 276 # Cop supports --auto-correct. # Configuration parameters: IgnoredMethods. # IgnoredMethods: respond_to, define_method Style/SymbolProc: Enabled: false - -# Offense count: 2362 -# Cop supports --auto-correct. -# Configuration parameters: AllowImplicitReturn, AllowedReceivers. -Rails/SaveBang: - Exclude: - - 'ee/spec/controllers/projects/merge_requests_controller_spec.rb' - - 'ee/spec/controllers/subscriptions_controller_spec.rb' - - 'ee/spec/frontend/fixtures/analytics.rb' - - 'ee/spec/graphql/resolvers/vulnerabilities_resolver_spec.rb' - - 'ee/spec/initializers/fog_google_https_private_urls_spec.rb' - - 'ee/spec/lib/analytics/merge_request_metrics_calculator_spec.rb' - - 'ee/spec/lib/ee/gitlab/auth/ldap/sync/group_spec.rb' - - 'ee/spec/lib/ee/gitlab/checks/push_rules/commit_check_spec.rb' - - 'ee/spec/lib/ee/gitlab/ci/pipeline/quota/activity_spec.rb' - - 'ee/spec/lib/gitlab/auth/ldap/access_spec.rb' - - 'ee/spec/lib/gitlab/auth/o_auth/user_spec.rb' - - 'ee/spec/lib/gitlab/auth/saml/user_spec.rb' - - 'ee/spec/lib/gitlab/background_migration/fix_orphan_promoted_issues_spec.rb' - - 'ee/spec/lib/gitlab/elastic/search_results_spec.rb' - - 'ee/spec/lib/gitlab/email/handler/ee/service_desk_handler_spec.rb' - - 'ee/spec/lib/gitlab/geo_spec.rb' - - 'ee/spec/lib/gitlab/git_access_spec.rb' - - 'ee/spec/lib/gitlab/import_export/group/relation_factory_spec.rb' - - 'ee/spec/lib/gitlab/mirror_spec.rb' - - 'ee/spec/mailers/notify_spec.rb' - - 'ee/spec/migrations/fix_any_approver_rule_for_projects_spec.rb' - - 'ee/spec/migrations/geo/migrate_ci_job_artifacts_to_separate_registry_spec.rb' - - 'ee/spec/migrations/geo/migrate_lfs_objects_to_separate_registry_spec.rb' - - 'ee/spec/migrations/schedule_merge_request_any_approval_rule_migration_spec.rb' - - 'ee/spec/migrations/schedule_project_any_approval_rule_migration_spec.rb' - - 'ee/spec/models/application_setting_spec.rb' - - 'ee/spec/models/approval_merge_request_rule_spec.rb' - - 'ee/spec/models/approval_project_rule_spec.rb' - - 'ee/spec/models/burndown_spec.rb' - - 'ee/spec/models/ci/pipeline_spec.rb' - - 'ee/spec/models/ci/subscriptions/project_spec.rb' - - 'ee/spec/models/ee/appearance_spec.rb' - - 'ee/spec/models/ee/ci/job_artifact_spec.rb' - - 'ee/spec/models/ee/protected_branch_spec.rb' - - 'ee/spec/models/ee/protected_ref_access_spec.rb' - - 'ee/spec/models/ee/protected_ref_spec.rb' - - 'ee/spec/models/elasticsearch_indexed_namespace_spec.rb' - - 'ee/spec/models/environment_spec.rb' - - 'ee/spec/models/epic_spec.rb' - - 'ee/spec/models/geo/project_registry_spec.rb' - - 'ee/spec/models/geo_node_spec.rb' - - 'ee/spec/models/geo_node_status_spec.rb' - - 'ee/spec/models/gitlab_subscription_spec.rb' - - 'ee/spec/models/group_spec.rb' - - 'ee/spec/models/issue_spec.rb' - - 'ee/spec/models/label_note_spec.rb' - - 'ee/spec/models/lfs_object_spec.rb' - - 'ee/spec/models/license_spec.rb' - - 'ee/spec/models/merge_request_spec.rb' - - 'ee/spec/models/merge_train_spec.rb' - - 'spec/models/packages/package_spec.rb' - - 'ee/spec/models/project_ci_cd_setting_spec.rb' - - 'ee/spec/models/project_spec.rb' - - 'ee/spec/models/protected_environment_spec.rb' - - 'ee/spec/models/repository_spec.rb' - - 'ee/spec/models/scim_identity_spec.rb' - - 'ee/spec/models/scim_oauth_access_token_spec.rb' - - 'ee/spec/models/upload_spec.rb' - - 'ee/spec/models/user_preference_spec.rb' - - 'ee/spec/models/user_spec.rb' - - 'ee/spec/models/visible_approvable_spec.rb' - - 'ee/spec/models/vulnerabilities/feedback_spec.rb' - - 'ee/spec/models/vulnerabilities/issue_link_spec.rb' - - 'ee/spec/presenters/audit_event_presenter_spec.rb' - - 'ee/spec/presenters/epic_presenter_spec.rb' - - 'ee/spec/requests/api/boards_spec.rb' - - 'ee/spec/requests/api/epic_issues_spec.rb' - - 'ee/spec/requests/api/epic_links_spec.rb' - - 'ee/spec/requests/api/epics_spec.rb' - - 'ee/spec/requests/api/geo_nodes_spec.rb' - - 'ee/spec/requests/api/geo_spec.rb' - - 'ee/spec/requests/api/graphql/group/epics_spec.rb' - - 'ee/spec/requests/api/graphql/mutations/epic_tree/reorder_spec.rb' - - 'ee/spec/requests/api/groups_spec.rb' - - 'ee/spec/requests/api/issues_spec.rb' - - 'ee/spec/requests/api/ldap_group_links_spec.rb' - - 'ee/spec/requests/api/merge_request_approval_rules_spec.rb' - - 'ee/spec/requests/api/merge_request_approvals_spec.rb' - - 'ee/spec/requests/api/merge_requests_spec.rb' - - 'ee/spec/requests/api/project_approvals_spec.rb' - - 'ee/spec/requests/api/projects_spec.rb' - - 'ee/spec/requests/api/protected_branches_spec.rb' - - 'ee/spec/requests/api/scim_spec.rb' - - 'ee/spec/requests/api/todos_spec.rb' - - 'ee/spec/requests/lfs_http_spec.rb' - - 'ee/spec/services/approval_rules/finalize_service_spec.rb' - - 'ee/spec/services/approval_rules/update_service_spec.rb' - - 'ee/spec/services/ee/boards/issues/create_service_spec.rb' - - 'ee/spec/services/ee/boards/issues/list_service_spec.rb' - - 'ee/spec/services/ee/boards/lists/list_service_spec.rb' - - 'ee/spec/services/ee/issuable/clone/attributes_rewriter_spec.rb' - - 'ee/spec/services/ee/issuable/common_system_notes_service_spec.rb' - - 'ee/spec/services/ee/issues/update_service_spec.rb' - - 'ee/spec/services/ee/merge_requests/refresh_service_spec.rb' - - 'ee/spec/services/ee/merge_requests/update_service_spec.rb' - - 'ee/spec/services/ee/notes/quick_actions_service_spec.rb' - - 'ee/spec/services/ee/notification_service_spec.rb' - - 'ee/spec/services/epic_links/create_service_spec.rb' - - 'ee/spec/services/epics/close_service_spec.rb' - - 'ee/spec/services/epics/issue_promote_service_spec.rb' - - 'ee/spec/services/epics/reopen_service_spec.rb' - - 'ee/spec/services/epics/tree_reorder_service_spec.rb' - - 'ee/spec/services/epics/update_dates_service_spec.rb' - - 'ee/spec/services/epics/update_service_spec.rb' - - 'ee/spec/services/geo/blob_verification_secondary_service_spec.rb' - - 'ee/spec/services/geo/files_expire_service_spec.rb' - - 'ee/spec/services/geo/metrics_update_service_spec.rb' - - 'ee/spec/services/geo/registry_consistency_service_spec.rb' - - 'ee/spec/services/geo/repository_verification_secondary_service_spec.rb' - - 'ee/spec/services/groups/autocomplete_service_spec.rb' - - 'ee/spec/services/ldap_group_reset_service_spec.rb' - - 'ee/spec/services/lfs/unlock_file_service_spec.rb' - - 'ee/spec/services/merge_trains/refresh_merge_request_service_spec.rb' - - 'ee/spec/services/quick_actions/interpret_service_spec.rb' - - 'ee/spec/services/slash_commands/global_slack_handler_spec.rb' - - 'ee/spec/services/start_pull_mirroring_service_spec.rb' - - 'ee/spec/services/status_page/trigger_publish_service_spec.rb' - - 'ee/spec/services/todo_service_spec.rb' - - 'ee/spec/services/update_build_minutes_service_spec.rb' - - 'ee/spec/services/vulnerability_feedback/create_service_spec.rb' - - 'ee/spec/support/protected_tags/access_control_shared_examples.rb' - - 'ee/spec/support/shared_examples/features/protected_branches_access_control_shared_examples.rb' - - 'ee/spec/support/shared_examples/finders/geo/framework_registry_finder_shared_examples.rb' - - 'ee/spec/support/shared_examples/graphql/geo/geo_registries_resolver_shared_examples.rb' - - 'ee/spec/support/shared_examples/lib/analytics/common_merge_request_metrics_refresh_shared_examples.rb' - - 'ee/spec/support/shared_examples/policies/protected_environments_shared_examples.rb' - - 'ee/spec/workers/adjourned_project_deletion_worker_spec.rb' - - 'ee/spec/workers/clear_shared_runners_minutes_worker_spec.rb' - - 'ee/spec/workers/create_github_webhook_worker_spec.rb' - - 'ee/spec/workers/elastic_namespace_rollout_worker_spec.rb' - - 'ee/spec/workers/geo/container_repository_sync_dispatch_worker_spec.rb' - - 'ee/spec/workers/geo/file_download_dispatch_worker_spec.rb' - - 'ee/spec/workers/geo/prune_event_log_worker_spec.rb' - - 'ee/spec/workers/geo/registry_sync_worker_spec.rb' - - 'ee/spec/workers/geo/repository_shard_sync_worker_spec.rb' - - 'ee/spec/workers/repository_import_worker_spec.rb' - - 'ee/spec/workers/update_all_mirrors_worker_spec.rb' - - 'qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb' - - 'qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_lfs_over_http_spec.rb' - - 'qa/qa/specs/features/ee/browser_ui/3_create/repository/pull_mirroring_over_http_spec.rb' - - 'qa/qa/specs/features/ee/browser_ui/3_create/repository/pull_mirroring_over_ssh_with_key_spec.rb' - - 'spec/controllers/abuse_reports_controller_spec.rb' - - 'spec/controllers/admin/impersonations_controller_spec.rb' - - 'spec/controllers/admin/runners_controller_spec.rb' - - 'spec/controllers/admin/services_controller_spec.rb' - - 'spec/controllers/boards/issues_controller_spec.rb' - - 'spec/controllers/groups/milestones_controller_spec.rb' - - 'spec/controllers/groups/runners_controller_spec.rb' - - 'spec/controllers/groups/uploads_controller_spec.rb' - - 'spec/controllers/groups_controller_spec.rb' - - 'spec/controllers/oauth/authorizations_controller_spec.rb' - - 'spec/controllers/omniauth_callbacks_controller_spec.rb' - - 'spec/controllers/profiles/emails_controller_spec.rb' - - 'spec/controllers/profiles/notifications_controller_spec.rb' - - 'spec/controllers/projects/artifacts_controller_spec.rb' - - 'spec/controllers/projects/cycle_analytics/events_controller_spec.rb' - - 'spec/controllers/projects/cycle_analytics_controller_spec.rb' - - 'spec/controllers/projects/discussions_controller_spec.rb' - - 'spec/controllers/projects/forks_controller_spec.rb' - - 'spec/controllers/projects/group_links_controller_spec.rb' - - 'spec/controllers/projects/imports_controller_spec.rb' - - 'spec/controllers/projects/issues_controller_spec.rb' - - 'spec/controllers/projects/labels_controller_spec.rb' - - 'spec/controllers/projects/milestones_controller_spec.rb' - - 'spec/controllers/projects/notes_controller_spec.rb' - - 'spec/controllers/projects/pipelines_controller_spec.rb' - - 'spec/controllers/projects/releases/evidences_controller_spec.rb' - - 'spec/controllers/projects/runners_controller_spec.rb' - - 'spec/controllers/projects/starrers_controller_spec.rb' - - 'spec/controllers/projects/uploads_controller_spec.rb' - - 'spec/controllers/projects_controller_spec.rb' - - 'spec/controllers/sent_notifications_controller_spec.rb' - - 'spec/controllers/sessions_controller_spec.rb' - - 'spec/controllers/users_controller_spec.rb' - - 'spec/factories_spec.rb' - - 'spec/features/admin/admin_appearance_spec.rb' - - 'spec/features/admin/admin_labels_spec.rb' - - 'spec/features/admin/admin_mode/login_spec.rb' - - 'spec/features/admin/admin_runners_spec.rb' - - 'spec/features/admin/admin_sees_project_statistics_spec.rb' - - 'spec/features/admin/admin_sees_projects_statistics_spec.rb' - - 'spec/features/admin/admin_users_impersonation_tokens_spec.rb' - - 'spec/features/admin/admin_users_spec.rb' - - 'spec/features/boards/sidebar_spec.rb' - - 'spec/features/calendar_spec.rb' - - 'spec/features/commits_spec.rb' - - 'spec/features/dashboard/datetime_on_tooltips_spec.rb' - - 'spec/features/dashboard/issuables_counter_spec.rb' - - 'spec/features/dashboard/project_member_activity_index_spec.rb' - - 'spec/features/dashboard/projects_spec.rb' - - 'spec/features/error_tracking/user_sees_error_index_spec.rb' - - 'spec/features/groups/members/request_access_spec.rb' - - 'spec/features/issuables/close_reopen_report_toggle_spec.rb' - - 'spec/features/issues/bulk_assignment_labels_spec.rb' - - 'spec/features/issues/gfm_autocomplete_spec.rb' - - 'spec/features/issues/issue_sidebar_spec.rb' - - 'spec/features/issues/note_polling_spec.rb' - - 'spec/features/issues/user_creates_branch_and_merge_request_spec.rb' - - 'spec/features/issues/user_creates_confidential_merge_request_spec.rb' - - 'spec/features/issues/user_edits_issue_spec.rb' - - 'spec/features/issues/user_filters_issues_spec.rb' - - 'spec/features/issues/user_sees_live_update_spec.rb' - - 'spec/features/issues/user_sorts_issues_spec.rb' - - 'spec/features/profiles/emails_spec.rb' - - 'spec/features/profiles/password_spec.rb' - - 'spec/features/profiles/personal_access_tokens_spec.rb' - - 'spec/features/projects/features_visibility_spec.rb' - - 'spec/features/projects/fork_spec.rb' - - 'spec/features/projects/jobs/permissions_spec.rb' - - 'spec/features/projects/jobs_spec.rb' - - 'spec/features/projects/members/user_requests_access_spec.rb' - - 'spec/features/projects/pages_lets_encrypt_spec.rb' - - 'spec/features/projects/pages_spec.rb' - - 'spec/features/projects/pipelines/pipeline_spec.rb' - - 'spec/features/projects/pipelines/pipelines_spec.rb' - - 'spec/features/projects/remote_mirror_spec.rb' - - 'spec/features/projects/services/user_activates_slack_notifications_spec.rb' - - 'spec/features/projects/settings/access_tokens_spec.rb' - - 'spec/features/projects/show/user_sees_deletion_failure_message_spec.rb' - - 'spec/features/projects/user_sees_sidebar_spec.rb' - - 'spec/features/projects/wiki/user_updates_wiki_page_spec.rb' - - 'spec/features/projects/wiki/user_views_wiki_page_spec.rb' - - 'spec/features/projects/wiki/users_views_asciidoc_page_with_includes_spec.rb' - - 'spec/features/runners_spec.rb' - - 'spec/features/security/project/internal_access_spec.rb' - - 'spec/features/security/project/private_access_spec.rb' - - 'spec/features/security/project/public_access_spec.rb' - - 'spec/features/users/login_spec.rb' - - 'spec/features/users/show_spec.rb' - - 'spec/frontend/fixtures/issues.rb' - - 'spec/frontend/fixtures/merge_requests.rb' - - 'spec/graphql/mutations/merge_requests/set_locked_spec.rb' - - 'spec/graphql/mutations/merge_requests/set_wip_spec.rb' - - 'spec/graphql/resolvers/boards_resolver_spec.rb' - - 'spec/initializers/active_record_locking_spec.rb' - - 'spec/initializers/fog_google_https_private_urls_spec.rb' - - 'spec/lib/after_commit_queue_spec.rb' - - 'spec/lib/backup/manager_spec.rb' - - 'spec/lib/banzai/reference_parser/external_issue_parser_spec.rb' - - 'spec/lib/banzai/reference_redactor_spec.rb' - - 'spec/lib/gitlab/alerting/alert_spec.rb' - - 'spec/lib/gitlab/analytics/cycle_analytics/records_fetcher_spec.rb' - - 'spec/lib/gitlab/auth/ldap/user_spec.rb' - - 'spec/lib/gitlab/auth/o_auth/user_spec.rb' - - 'spec/lib/gitlab/auth/saml/user_spec.rb' - - 'spec/lib/gitlab/auth_spec.rb' - - 'spec/lib/gitlab/authorized_keys_spec.rb' - - 'spec/lib/gitlab/background_migration/backfill_deployment_clusters_from_deployments_spec.rb' - - 'spec/lib/gitlab/background_migration/backfill_project_repositories_spec.rb' - - 'spec/lib/gitlab/background_migration/backfill_project_settings_spec.rb' - - 'spec/lib/gitlab/background_migration/backfill_push_rules_id_in_projects_spec.rb' - - 'spec/lib/gitlab/background_migration/backfill_snippet_repositories_spec.rb' - - 'spec/lib/gitlab/background_migration/digest_column_spec.rb' - - 'spec/lib/gitlab/background_migration/encrypt_columns_spec.rb' - - 'spec/lib/gitlab/background_migration/fix_cross_project_label_links_spec.rb' - - 'spec/lib/gitlab/background_migration/fix_projects_without_project_feature_spec.rb' - - 'spec/lib/gitlab/background_migration/fix_projects_without_prometheus_service_spec.rb' - - 'spec/lib/gitlab/background_migration/fix_user_namespace_names_spec.rb' - - 'spec/lib/gitlab/background_migration/fix_user_project_route_names_spec.rb' - - 'spec/lib/gitlab/background_migration/legacy_upload_mover_spec.rb' - - 'spec/lib/gitlab/background_migration/legacy_uploads_migrator_spec.rb' - - 'spec/lib/gitlab/background_migration/link_lfs_objects_projects_spec.rb' - - 'spec/lib/gitlab/background_migration/migrate_issue_trackers_sensitive_data_spec.rb' - - 'spec/lib/gitlab/background_migration/migrate_stage_index_spec.rb' - - 'spec/lib/gitlab/background_migration/migrate_users_bio_to_user_details_spec.rb' - - 'spec/lib/gitlab/background_migration/populate_canonical_emails_spec.rb' - - 'spec/lib/gitlab/background_migration/populate_merge_request_assignees_table_spec.rb' - - 'spec/lib/gitlab/background_migration/populate_user_highest_roles_table_spec.rb' - - 'spec/lib/gitlab/background_migration/recalculate_project_authorizations_spec.rb' - - 'spec/lib/gitlab/background_migration/remove_restricted_todos_spec.rb' - - 'spec/lib/gitlab/background_migration/reset_merge_status_spec.rb' - - 'spec/lib/gitlab/background_migration/set_confidential_note_events_on_services_spec.rb' - - 'spec/lib/gitlab/background_migration/set_confidential_note_events_on_webhooks_spec.rb' - - 'spec/lib/gitlab/bitbucket_server_import/importer_spec.rb' - - 'spec/lib/gitlab/ci/ansi2json/style_spec.rb' - - 'spec/lib/gitlab/ci/status/build/common_spec.rb' - - 'spec/lib/gitlab/cycle_analytics/base_event_fetcher_spec.rb' - - 'spec/lib/gitlab/database/custom_structure_spec.rb' - - 'spec/lib/gitlab/database/partitioning_migration_helpers/table_management_helpers_spec.rb' - - 'spec/lib/gitlab/database_importers/self_monitoring/project/create_service_spec.rb' - - 'spec/lib/gitlab/email/handler/create_note_handler_spec.rb' - - 'spec/lib/gitlab/email/handler/unsubscribe_handler_spec.rb' - - 'spec/lib/gitlab/gfm/reference_rewriter_spec.rb' - - 'spec/lib/gitlab/git_access_spec.rb' - - 'spec/lib/gitlab/gitaly_client/object_pool_service_spec.rb' - - 'spec/lib/gitlab/gitaly_client/repository_service_spec.rb' - - 'spec/lib/gitlab/import_export/avatar_saver_spec.rb' - - 'spec/lib/gitlab/import_export/base/relation_factory_spec.rb' - - 'spec/lib/gitlab/import_export/design_repo_restorer_spec.rb' - - 'spec/lib/gitlab/import_export/fast_hash_serializer_spec.rb' - - 'spec/lib/gitlab/import_export/fork_spec.rb' - - 'spec/lib/gitlab/import_export/group/legacy_tree_saver_spec.rb' - - 'spec/lib/gitlab/import_export/group/relation_factory_spec.rb' - - 'spec/lib/gitlab/import_export/group/tree_saver_spec.rb' - - 'spec/lib/gitlab/import_export/importer_spec.rb' - - 'spec/lib/gitlab/import_export/lfs_restorer_spec.rb' - - 'spec/lib/gitlab/import_export/lfs_saver_spec.rb' - - 'spec/lib/gitlab/import_export/members_mapper_spec.rb' - - 'spec/lib/gitlab/import_export/project/relation_factory_spec.rb' - - 'spec/lib/gitlab/import_export/project/tree_restorer_spec.rb' - - 'spec/lib/gitlab/import_export/project/tree_saver_spec.rb' - - 'spec/lib/gitlab/import_export/repo_restorer_spec.rb' - - 'spec/lib/gitlab/import_export/saver_spec.rb' - - 'spec/lib/gitlab/import_export/snippet_repo_restorer_spec.rb' - - 'spec/lib/gitlab/import_export/snippet_repo_saver_spec.rb' - - 'spec/lib/gitlab/import_export/snippets_repo_restorer_spec.rb' - - 'spec/lib/gitlab/import_export/snippets_repo_saver_spec.rb' - - 'spec/lib/gitlab/import_export/uploads_manager_spec.rb' - - 'spec/lib/gitlab/import_export/uploads_saver_spec.rb' - - 'spec/lib/gitlab/import_export/wiki_restorer_spec.rb' - - 'spec/lib/gitlab/legacy_github_import/importer_spec.rb' - - 'spec/lib/gitlab/legacy_github_import/issue_formatter_spec.rb' - - 'spec/lib/gitlab/legacy_github_import/milestone_formatter_spec.rb' - - 'spec/lib/gitlab/legacy_github_import/pull_request_formatter_spec.rb' - - 'spec/lib/gitlab/lets_encrypt/client_spec.rb' - - 'spec/lib/gitlab/markdown_cache/active_record/extension_spec.rb' - - 'spec/lib/gitlab/markdown_cache/redis/store_spec.rb' - - 'spec/lib/gitlab/middleware/go_spec.rb' - - 'spec/lib/gitlab/shard_health_cache_spec.rb' - - 'spec/lib/mattermost/command_spec.rb' - - 'spec/lib/mattermost/session_spec.rb' - - 'spec/lib/mattermost/team_spec.rb' - - 'spec/mailers/notify_spec.rb' - - 'spec/migrations/20190924152703_migrate_issue_trackers_data_spec.rb' - - 'spec/migrations/20200122123016_backfill_project_settings_spec.rb' - - 'spec/migrations/20200123155929_remove_invalid_jira_data_spec.rb' - - 'spec/migrations/20200127090233_remove_invalid_issue_tracker_data_spec.rb' - - 'spec/migrations/20200130145430_reschedule_migrate_issue_trackers_data_spec.rb' - - 'spec/migrations/20200313203550_remove_orphaned_chat_names_spec.rb' - - 'spec/migrations/20200406102120_backfill_deployment_clusters_from_deployments_spec.rb' - - 'spec/migrations/20200526115436_dedup_mr_metrics_spec.rb' - - 'spec/migrations/add_deploy_token_type_to_deploy_tokens_spec.rb' - - 'spec/migrations/add_incident_settings_to_all_existing_projects_spec.rb' - - 'spec/migrations/add_unique_constraint_to_approvals_user_id_and_merge_request_id_spec.rb' - - 'spec/migrations/backfill_and_add_not_null_constraint_to_released_at_column_on_releases_table_spec.rb' - - 'spec/migrations/backfill_imported_snippet_repositories_spec.rb' - - 'spec/migrations/backfill_releases_table_updated_at_and_add_not_null_constraints_to_timestamps_spec.rb' - - 'spec/migrations/backfill_snippet_repositories_spec.rb' - - 'spec/migrations/encrypt_plaintext_attributes_on_application_settings_spec.rb' - - 'spec/migrations/enqueue_reset_merge_status_second_run_spec.rb' - - 'spec/migrations/enqueue_reset_merge_status_spec.rb' - - 'spec/migrations/fill_file_store_lfs_objects_spec.rb' - - 'spec/migrations/fill_store_uploads_spec.rb' - - 'spec/migrations/fix_null_type_labels_spec.rb' - - 'spec/migrations/fix_pool_repository_source_project_id_spec.rb' - - 'spec/migrations/fix_projects_without_project_feature_spec.rb' - - 'spec/migrations/fix_projects_without_prometheus_services_spec.rb' - - 'spec/migrations/fix_wrong_pages_access_level_spec.rb' - - 'spec/migrations/insert_project_hooks_plan_limits_spec.rb' - - 'spec/migrations/migrate_auto_dev_ops_domain_to_cluster_domain_spec.rb' - - 'spec/migrations/move_limits_from_plans_spec.rb' - - 'spec/migrations/populate_project_statistics_packages_size_spec.rb' - - 'spec/migrations/schedule_link_lfs_objects_projects_spec.rb' - - 'spec/migrations/schedule_populate_merge_request_assignees_table_spec.rb' - - 'spec/migrations/seed_repository_storages_weighted_spec.rb' - - 'spec/models/appearance_spec.rb' - - 'spec/models/application_record_spec.rb' - - 'spec/models/application_setting_spec.rb' - - 'spec/models/clusters/applications/helm_spec.rb' - - 'spec/models/commit_spec.rb' - - 'spec/models/commit_status_spec.rb' - - 'spec/models/container_repository_spec.rb' - - 'spec/models/deploy_keys_project_spec.rb' - - 'spec/models/deploy_token_spec.rb' - - 'spec/models/deployment_spec.rb' - - 'spec/models/design_management/version_spec.rb' - - 'spec/models/diff_discussion_spec.rb' - - 'spec/models/diff_note_spec.rb' - - 'spec/models/email_spec.rb' - - 'spec/models/environment_spec.rb' - - 'spec/models/event_spec.rb' - - 'spec/models/fork_network_spec.rb' - - 'spec/models/generic_commit_status_spec.rb' - - 'spec/models/grafana_integration_spec.rb' - - 'spec/models/group_spec.rb' - - 'spec/models/hooks/system_hook_spec.rb' - - 'spec/models/hooks/web_hook_spec.rb' - - 'spec/models/identity_spec.rb' - - 'spec/models/issue/metrics_spec.rb' - - 'spec/models/issue_spec.rb' - - 'spec/models/jira_import_state_spec.rb' - - 'spec/models/key_spec.rb' - - 'spec/models/lfs_objects_project_spec.rb' - - 'spec/models/member_spec.rb' - - 'spec/models/members/group_member_spec.rb' - - 'spec/models/members/project_member_spec.rb' - - 'spec/models/merge_request_spec.rb' - - 'spec/models/milestone_spec.rb' - - 'spec/models/namespace_spec.rb' - - 'spec/models/note_spec.rb' - - 'spec/models/notification_setting_spec.rb' - - 'spec/models/operations/feature_flag_scope_spec.rb' - - 'spec/models/operations/feature_flags/strategy_spec.rb' - - 'spec/models/operations/feature_flags/user_list_spec.rb' - - 'spec/models/pages_domain_spec.rb' - - 'spec/models/project_auto_devops_spec.rb' - - 'spec/models/project_feature_spec.rb' - - 'spec/models/project_spec.rb' - - 'spec/models/project_team_spec.rb' - - 'spec/models/protectable_dropdown_spec.rb' - - 'spec/models/redirect_route_spec.rb' - - 'spec/models/release_spec.rb' - - 'spec/models/remote_mirror_spec.rb' - - 'spec/models/resource_milestone_event_spec.rb' - - 'spec/models/route_spec.rb' - - 'spec/models/sentry_issue_spec.rb' - - 'spec/models/service_spec.rb' - - 'spec/models/snippet_spec.rb' - - 'spec/models/upload_spec.rb' - - 'spec/models/user_preference_spec.rb' - - 'spec/models/user_spec.rb' - - 'spec/models/user_status_spec.rb' - - 'spec/models/wiki_page/meta_spec.rb' - - 'spec/models/wiki_page_spec.rb' - - 'spec/presenters/ci/build_runner_presenter_spec.rb' - - 'spec/presenters/ci/trigger_presenter_spec.rb' - - 'spec/presenters/packages/conan/package_presenter_spec.rb' - - 'spec/requests/api/ci/runner_spec.rb' - - 'spec/requests/api/commit_statuses_spec.rb' - - 'spec/requests/api/conan_packages_spec.rb' - - 'spec/requests/api/deployments_spec.rb' - - 'spec/requests/api/environments_spec.rb' - - 'spec/requests/api/go_proxy_spec.rb' - - 'spec/requests/api/graphql/mutations/merge_requests/set_labels_spec.rb' - - 'spec/requests/api/graphql/user_query_spec.rb' - - 'spec/requests/api/graphql_spec.rb' - - 'spec/requests/api/group_import_spec.rb' - - 'spec/requests/api/group_milestones_spec.rb' - - 'spec/requests/api/internal/base_spec.rb' - - 'spec/requests/api/issues/get_group_issues_spec.rb' - - 'spec/requests/api/issues/post_projects_issues_spec.rb' - - 'spec/requests/api/jobs_spec.rb' - - 'spec/requests/api/labels_spec.rb' - - 'spec/requests/api/project_import_spec.rb' - - 'spec/requests/projects/cycle_analytics_events_spec.rb' - -# Offense count: 187 -# Cop supports --auto-correct. -RSpec/TimecopFreeze: - Exclude: - - 'ee/spec/lib/gitlab/geo/git_push_http_spec.rb' - - 'ee/spec/lib/gitlab/geo/log_cursor/daemon_spec.rb' - - 'ee/spec/lib/gitlab/analytics/cycle_analytics/data_collector_spec.rb' - - 'ee/spec/lib/gitlab/geo/oauth/login_state_spec.rb' - - 'ee/spec/lib/gitlab/insights/reducers/count_per_period_reducer_spec.rb' - - 'ee/spec/models/merge_train_spec.rb' - - 'ee/spec/frontend/fixtures/analytics.rb' - - 'ee/spec/support/shared_contexts/lib/gitlab/insights/reducers/reducers_shared_contexts.rb' - - 'qa/spec/support/repeater_spec.rb' - - 'spec/features/profiles/active_sessions_spec.rb' - - 'spec/features/projects/environments/environment_metrics_spec.rb' - - 'spec/features/users/active_sessions_spec.rb' - - 'spec/lib/atlassian/jira_connect/client_spec.rb' - - 'spec/lib/gitlab/analytics/cycle_analytics/base_query_builder_spec.rb' - - 'spec/lib/gitlab/analytics/cycle_analytics/median_spec.rb' - - 'spec/lib/gitlab/analytics/cycle_analytics/records_fetcher_spec.rb' - - 'spec/lib/gitlab/anonymous_session_spec.rb' - - 'spec/lib/gitlab/auth/unique_ips_limiter_spec.rb' - - 'spec/lib/gitlab/checks/timed_logger_spec.rb' - - 'spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb' - - 'spec/lib/gitlab/cycle_analytics/usage_data_spec.rb' - - 'spec/lib/gitlab/instrumentation_helper_spec.rb' - - 'spec/lib/gitlab/omniauth_logging/json_formatter_spec.rb' - - 'spec/lib/gitlab/puma_logging/json_formatter_spec.rb' - - 'spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb' - - 'spec/lib/json_web_token/hmac_token_spec.rb' - - 'spec/lib/rspec_flaky/flaky_example_spec.rb' - - 'spec/lib/rspec_flaky/listener_spec.rb' - - 'spec/models/active_session_spec.rb' - - 'spec/models/container_repository_spec.rb' - - 'spec/models/pages/lookup_path_spec.rb' - - 'spec/models/project_feature_usage_spec.rb' - - 'spec/requests/api/v3/github_spec.rb' - - 'spec/serializers/entity_date_helper_spec.rb' - - 'spec/support/cycle_analytics_helpers/test_generation.rb' - - 'spec/support/helpers/cycle_analytics_helpers.rb' - - 'spec/support/helpers/javascript_fixtures_helpers.rb' - - 'spec/support/shared_contexts/rack_attack_shared_context.rb' - - 'spec/support/shared_examples/workers/concerns/reenqueuer_shared_examples.rb' - - 'spec/workers/concerns/reenqueuer_spec.rb' - - 'spec/workers/metrics/dashboard/prune_old_annotations_worker_spec.rb' - -# Offense count: 54 -# Cop supports --auto-correct. -RSpec/TimecopTravel: - Exclude: - - 'ee/spec/lib/gitlab/geo/event_gap_tracking_spec.rb' - - 'ee/spec/lib/gitlab/geo/git_push_http_spec.rb' - - 'ee/spec/lib/gitlab/geo/jwt_request_decoder_spec.rb' - - 'ee/spec/lib/gitlab/geo/log_cursor/daemon_spec.rb' - - 'ee/spec/models/broadcast_message_spec.rb' - - 'ee/spec/models/burndown_spec.rb' - - 'qa/spec/support/repeater_spec.rb' - - 'spec/features/users/terms_spec.rb' - - 'spec/lib/feature_spec.rb' - - 'spec/models/broadcast_message_spec.rb' - - 'spec/models/concerns/issuable_spec.rb' - - 'spec/requests/api/ci/runner/jobs_trace_spec.rb' - - 'spec/requests/api/issues/put_projects_issues_spec.rb' - - 'spec/support/shared_contexts/cache_allowed_users_in_namespace_shared_context.rb' - - 'spec/support/shared_examples/requests/api/time_tracking_shared_examples.rb' - - 'spec/support/shared_examples/workers/concerns/reenqueuer_shared_examples.rb' - - 'spec/workers/concerns/reenqueuer_spec.rb' - - 'spec/lib/gitlab/analytics/cycle_analytics/median_spec.rb' - -# Offense count: 21 -Graphql/IDType: - Exclude: - - 'ee/app/graphql/ee/mutations/issues/update.rb' - - 'ee/app/graphql/mutations/iterations/update.rb' - - 'ee/app/graphql/resolvers/iterations_resolver.rb' - - 'app/graphql/mutations/boards/issues/issue_move_list.rb' - - 'app/graphql/mutations/issues/update.rb' - - 'app/graphql/mutations/metrics/dashboard/annotations/delete.rb' - - 'app/graphql/mutations/snippets/destroy.rb' - - 'app/graphql/mutations/snippets/mark_as_spam.rb' - - 'app/graphql/mutations/snippets/update.rb' - - 'app/graphql/resolvers/design_management/design_at_version_resolver.rb' - - 'app/graphql/resolvers/design_management/design_resolver.rb' - - 'app/graphql/resolvers/design_management/designs_resolver.rb' - - 'app/graphql/resolvers/design_management/version/design_at_version_resolver.rb' - - 'app/graphql/resolvers/design_management/version_in_collection_resolver.rb' - - 'app/graphql/resolvers/design_management/version_resolver.rb' - - 'app/graphql/resolvers/design_management/versions_resolver.rb' - - 'app/graphql/resolvers/error_tracking/sentry_detailed_error_resolver.rb' - - 'app/graphql/resolvers/error_tracking/sentry_error_stack_trace_resolver.rb' - - 'app/graphql/resolvers/snippets_resolver.rb' - - 'app/graphql/resolvers/user_merge_requests_resolver.rb' - -# Offense count: 86 -# Cop supports --auto-correct. -FactoryBot/InlineAssociation: - Exclude: - - 'ee/spec/factories/analytics/cycle_analytics/group_stages.rb' - - 'ee/spec/factories/geo/event_log.rb' - - 'ee/spec/factories/groups.rb' - - 'ee/spec/factories/merge_request_blocks.rb' - - 'ee/spec/factories/vulnerabilities/feedback.rb' - - 'spec/factories/atlassian_identities.rb' - - 'spec/factories/design_management/design_at_version.rb' - - 'spec/factories/design_management/designs.rb' - - 'spec/factories/design_management/versions.rb' - - 'spec/factories/events.rb' - - 'spec/factories/git_wiki_commit_details.rb' - - 'spec/factories/gitaly/commit.rb' - - 'spec/factories/go_module_commits.rb' - - 'spec/factories/go_module_versions.rb' - - 'spec/factories/go_modules.rb' - - 'spec/factories/group_group_links.rb' - - 'spec/factories/import_export_uploads.rb' - - 'spec/factories/merge_requests.rb' - - 'spec/factories/notes.rb' - - 'spec/factories/packages.rb' - - 'spec/factories/packages/package_file.rb' - - 'spec/factories/sent_notifications.rb' @@ -370,11 +370,7 @@ group :development, :test do gem 'spring', '~> 2.0.0' gem 'spring-commands-rspec', '~> 1.0.4' - gem 'gitlab-styles', '~> 4.3.0', require: false - # Pin these dependencies, otherwise a new rule could break the CI pipelines - gem 'rubocop', '~> 0.82.0' - gem 'rubocop-performance', '~> 1.5.2' - gem 'rubocop-rspec', '~> 1.37.0' + gem 'gitlab-styles', '~> 5.0.0', require: false gem 'scss_lint', '~> 0.56.0', require: false gem 'haml_lint', '~> 0.36.0', require: false diff --git a/Gemfile.lock b/Gemfile.lock index 5c77e1a92cf..f16934bf05c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -449,12 +449,12 @@ GEM gitlab-puma (>= 2.7, < 5) gitlab-sidekiq-fetcher (0.5.2) sidekiq (~> 5) - gitlab-styles (4.3.0) - rubocop (~> 0.82.0) + gitlab-styles (5.0.0) + rubocop (~> 0.89.1) rubocop-gitlab-security (~> 0.1.0) - rubocop-performance (~> 1.5.2) - rubocop-rails (~> 2.5) - rubocop-rspec (~> 1.36) + rubocop-performance (~> 1.8.1) + rubocop-rails (~> 2.8) + rubocop-rspec (~> 1.44) gitlab_chronic_duration (0.10.6.2) numerizer (~> 0.2) gitlab_omniauth-ldap (2.1.1) @@ -602,7 +602,6 @@ GEM jaeger-client (1.1.0) opentracing (~> 0.3) thrift - jaro_winkler (1.5.4) jira-ruby (2.0.0) activesupport atlassian-jwt @@ -834,7 +833,7 @@ GEM rubypants (~> 0.2) orm_adapter (0.5.0) os (1.0.0) - parallel (1.19.1) + parallel (1.19.2) parser (2.7.2.0) ast (~> 2.4.1) parslet (1.8.2) @@ -958,7 +957,7 @@ GEM redis-store (>= 1.2, < 2) redis-store (1.8.1) redis (>= 4, < 5) - regexp_parser (1.5.1) + regexp_parser (1.8.2) regexp_property_values (0.3.5) representable (3.0.4) declarative (< 0.1.0) @@ -1019,24 +1018,29 @@ GEM pg rails sqlite3 - rubocop (0.82.0) - jaro_winkler (~> 1.5.1) + rubocop (0.89.1) parallel (~> 1.10) - parser (>= 2.7.0.1) + parser (>= 2.7.1.1) rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.7) rexml + rubocop-ast (>= 0.3.0, < 1.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 1.4.0, < 2.0) + rubocop-ast (0.8.0) + parser (>= 2.7.1.5) rubocop-gitlab-security (0.1.1) rubocop (>= 0.51) - rubocop-performance (1.5.2) - rubocop (>= 0.71.0) - rubocop-rails (2.5.2) - activesupport + rubocop-performance (1.8.1) + rubocop (>= 0.87.0) + rubocop-ast (>= 0.4.0) + rubocop-rails (2.8.1) + activesupport (>= 4.2.0) rack (>= 1.1) - rubocop (>= 0.72.0) - rubocop-rspec (1.37.0) - rubocop (>= 0.68.1) + rubocop (>= 0.87.0) + rubocop-rspec (1.44.1) + rubocop (~> 0.87) + rubocop-ast (>= 0.7.1) ruby-enum (0.7.2) i18n ruby-fogbugz (0.2.1) @@ -1249,7 +1253,7 @@ GEM xpath (3.2.0) nokogiri (~> 1.8) yajl-ruby (1.4.1) - zeitwerk (2.4.0) + zeitwerk (2.4.1) PLATFORMS ruby @@ -1353,7 +1357,7 @@ DEPENDENCIES gitlab-puma (~> 4.3.3.gitlab.2) gitlab-puma_worker_killer (~> 0.1.1.gitlab.1) gitlab-sidekiq-fetcher (= 0.5.2) - gitlab-styles (~> 4.3.0) + gitlab-styles (~> 5.0.0) gitlab_chronic_duration (~> 0.10.6.2) gitlab_omniauth-ldap (~> 2.1.1) gon (~> 6.2) @@ -1473,9 +1477,6 @@ DEPENDENCIES rspec-retry (~> 0.6.1) rspec_junit_formatter rspec_profiling (~> 0.0.6) - rubocop (~> 0.82.0) - rubocop-performance (~> 1.5.2) - rubocop-rspec (~> 1.37.0) ruby-fogbugz (~> 0.2.1) ruby-prof (~> 1.3.0) ruby-progressbar diff --git a/app/assets/javascripts/alerts_settings/components/alerts_integrations_list.vue b/app/assets/javascripts/alerts_settings/components/alerts_integrations_list.vue index 1c22f035a15..5ecb2dd3e58 100644 --- a/app/assets/javascripts/alerts_settings/components/alerts_integrations_list.vue +++ b/app/assets/javascripts/alerts_settings/components/alerts_integrations_list.vue @@ -1,5 +1,12 @@ <script> -import { GlTable, GlIcon, GlTooltipDirective, GlLoadingIcon } from '@gitlab/ui'; +import { + GlButtonGroup, + GlButton, + GlIcon, + GlLoadingIcon, + GlTable, + GlTooltipDirective, +} from '@gitlab/ui'; import { s__, __ } from '~/locale'; import Tracking from '~/tracking'; import { trackAlertIntegrationsViewsOptions } from '../constants'; @@ -25,9 +32,11 @@ const bodyTrClass = export default { i18n, components: { - GlTable, + GlButtonGroup, + GlButton, GlIcon, GlLoadingIcon, + GlTable, }, directives: { GlTooltip: GlTooltipDirective, @@ -57,6 +66,10 @@ export default { key: 'type', label: __('Type'), }, + { + key: 'actions', + label: __('Actions'), + }, ], computed: { tbodyTrClass() { @@ -111,6 +124,13 @@ export default { </span> </template> + <template #cell(actions)="{ item }"> + <gl-button-group> + <gl-button icon="pencil" @click="$emit('edit-integration', { id: item.id })" /> + <gl-button icon="remove" @click="$emit('delete-integration', { id: item.id })" /> + </gl-button-group> + </template> + <template #table-busy> <gl-loading-icon size="lg" color="dark" class="mt-3" /> </template> diff --git a/app/assets/javascripts/alerts_settings/components/alerts_settings_form_new.vue b/app/assets/javascripts/alerts_settings/components/alerts_settings_form_new.vue index 84ee2fb524d..c5322c9865e 100644 --- a/app/assets/javascripts/alerts_settings/components/alerts_settings_form_new.vue +++ b/app/assets/javascripts/alerts_settings/components/alerts_settings_form_new.vue @@ -21,12 +21,14 @@ import { JSON_VALIDATE_DELAY, targetPrometheusUrlPlaceholder, typeSet, + defaultFormState, } from '../constants'; export default { targetPrometheusUrlPlaceholder, JSON_VALIDATE_DELAY, typeSet, + defaultFormState, i18n: { integrationFormSteps: { step1: { @@ -62,6 +64,11 @@ export default { label: s__('AlertSettings|Prometheus API base URL'), help: s__('AlertSettings|URL cannot be blank and must start with http or https'), }, + restKeyInfo: { + label: s__( + 'AlertSettings|Resetting the authorization key for this project will require updating the authorization key in every alert source it is enabled in.', + ), + }, }, }, components: { @@ -95,23 +102,18 @@ export default { type: Boolean, required: true, }, + currentIntegration: { + type: Object, + required: false, + default: null, + }, }, data() { return { selectedIntegration: integrationTypesNew[0].value, + active: false, options: integrationTypesNew, formVisible: false, - integrationForm: { - name: '', - integrationTestPayload: { - json: null, - error: null, - }, - active: false, - authKey: '', - url: '', - apiUrl: '', - }, }; }, computed: { @@ -125,9 +127,29 @@ export default { case this.$options.typeSet.prometheus: return this.prometheus; default: - return {}; + return this.defaultFormState; } }, + integrationForm() { + return { + name: this.currentIntegration?.name || '', + integrationTestPayload: { + json: null, + error: null, + }, + active: this.currentIntegration?.active || false, + token: this.currentIntegration?.token || '', + url: this.currentIntegration?.url || '', + apiUrl: this.currentIntegration?.apiUrl || '', + }; + }, + }, + watch: { + currentIntegration(val) { + this.selectedIntegration = val.type; + this.active = val.active; + this.onIntegrationTypeSelect(); + }, }, methods: { onIntegrationTypeSelect() { @@ -142,18 +164,29 @@ export default { this.onSubmit(); }, onSubmit() { - const { name, apiUrl, active } = this.integrationForm; + const { name, apiUrl } = this.integrationForm; const variables = this.selectedIntegration === this.$options.typeSet.http - ? { name, active } - : { apiUrl, active }; - this.$emit('on-create-new-integration', { type: this.selectedIntegration, variables }); + ? { name, active: this.active } + : { apiUrl, active: this.active }; + const integrationPayload = { type: this.selectedIntegration, variables }; + + if (this.currentIntegration) { + return this.$emit('update-integration', integrationPayload); + } + + return this.$emit('create-new-integration', integrationPayload); }, onReset() { - // TODO: Reset form values + this.integrationForm = this.defaultFormState; + this.selectedIntegration = integrationTypesNew[0].value; + this.onIntegrationTypeSelect(); }, onResetAuthKey() { - // TODO: Handle reset auth key via GraphQL + this.$emit('reset-token', { + type: this.selectedIntegration, + variables: { id: this.currentIntegration.id }, + }); }, validateJson() { this.integrationForm.integrationTestPayload.error = null; @@ -214,7 +247,7 @@ export default { /> <gl-toggle - v-model="integrationForm.active" + v-model="active" :is-loading="loading" :label="__('Active')" class="gl-my-4 gl-font-weight-normal" @@ -242,13 +275,9 @@ export default { {{ s__('AlertSettings|Webhook URL') }} </span> - <gl-form-input-group id="url" readonly :value="selectedIntegrationType.url"> + <gl-form-input-group id="url" readonly :value="integrationForm.url"> <template #append> - <clipboard-button - :text="selectedIntegrationType.url || ''" - :title="__('Copy')" - class="gl-m-0!" - /> + <clipboard-button :text="integrationForm.url" :title="__('Copy')" class="gl-m-0!" /> </template> </gl-form-input-group> </div> @@ -262,14 +291,10 @@ export default { id="authorization-key" class="gl-mb-2" readonly - :value="selectedIntegrationType.authKey" + :value="integrationForm.token" > <template #append> - <clipboard-button - :text="selectedIntegrationType.authKey || ''" - :title="__('Copy')" - class="gl-m-0!" - /> + <clipboard-button :text="integrationForm.token" :title="__('Copy')" class="gl-m-0!" /> </template> </gl-form-input-group> @@ -281,9 +306,9 @@ export default { :title="$options.i18n.integrationFormSteps.step3.reset" :ok-title="$options.i18n.integrationFormSteps.step3.reset" ok-variant="danger" - @ok="() => {}" + @ok="onResetAuthKey" > - {{ $options.i18n.integrationFormSteps.step3.reset }} + {{ $options.i18n.integrationFormSteps.restKeyInfo.label }} </gl-modal> </div> </gl-form-group> diff --git a/app/assets/javascripts/alerts_settings/components/alerts_settings_form_old.vue b/app/assets/javascripts/alerts_settings/components/alerts_settings_form_old.vue index 7d5ea9aa8c4..e4ba87c4e14 100644 --- a/app/assets/javascripts/alerts_settings/components/alerts_settings_form_old.vue +++ b/app/assets/javascripts/alerts_settings/components/alerts_settings_form_old.vue @@ -59,7 +59,7 @@ export default { selectedIntegration: integrationTypes[0].value, options: integrationTypes, active: false, - authKey: '', + token: '', targetUrl: '', feedback: { variant: 'danger', @@ -98,7 +98,7 @@ export default { case 'HTTP': { return { url: this.generic.url, - authKey: this.generic.authKey, + token: this.generic.token, active: this.generic.active, resetKey: this.resetKey.bind(this), }; @@ -106,7 +106,7 @@ export default { case 'PROMETHEUS': { return { url: this.prometheus.url, - authKey: this.prometheus.authKey, + token: this.prometheus.token, active: this.prometheus.active, resetKey: this.resetKey.bind(this, 'PROMETHEUS'), targetUrl: this.prometheus.prometheusApiUrl, @@ -167,7 +167,7 @@ export default { this.setOpsgenieAsDefault(); } this.active = this.selectedIntegrationType.active; - this.authKey = this.selectedIntegrationType.authKey ?? ''; + this.token = this.selectedIntegrationType.token ?? ''; }, methods: { createUserErrorMessage(errors = {}) { @@ -212,8 +212,8 @@ export default { return fn .then(({ data: { token } }) => { - this.authKey = token; - this.setFeedback({ feedbackMessage: this.$options.i18n.authKeyRest, variant: 'success' }); + this.token = token; + this.setFeedback({ feedbackMessage: this.$options.i18n.tokenRest, variant: 'success' }); }) .catch(() => { this.setFeedback({ feedbackMessage: this.$options.i18n.errorKeyMsg, variant: 'danger' }); @@ -313,7 +313,7 @@ export default { .updateTestAlert({ endpoint: this.selectedIntegrationType.url, data: this.testAlert.json, - authKey: this.selectedIntegrationType.authKey, + token: this.selectedIntegrationType.token, }) .then(() => { this.setFeedback({ @@ -439,21 +439,21 @@ export default { {{ prometheusInfo }} </span> </gl-form-group> - <gl-form-group :label="$options.i18n.authKeyLabel" label-for="authorization-key"> - <gl-form-input-group id="authorization-key" class="gl-mb-2" readonly :value="authKey"> + <gl-form-group :label="$options.i18n.tokenLabel" label-for="authorization-key"> + <gl-form-input-group id="authorization-key" class="gl-mb-2" readonly :value="token"> <template #append> <clipboard-button - :text="authKey" + :text="token" :title="$options.i18n.copyToClipboard" class="gl-m-0!" /> </template> </gl-form-input-group> - <gl-button v-gl-modal.authKeyModal :disabled="!active" class="gl-mt-3">{{ + <gl-button v-gl-modal.tokenModal :disabled="!active" class="gl-mt-3">{{ $options.i18n.resetKey }}</gl-button> <gl-modal - modal-id="authKeyModal" + modal-id="tokenModal" :title="$options.i18n.resetKey" :ok-title="$options.i18n.resetKey" ok-variant="danger" diff --git a/app/assets/javascripts/alerts_settings/components/alerts_settings_wrapper.vue b/app/assets/javascripts/alerts_settings/components/alerts_settings_wrapper.vue index 7fe0a4ad2cb..0a59a5981ef 100644 --- a/app/assets/javascripts/alerts_settings/components/alerts_settings_wrapper.vue +++ b/app/assets/javascripts/alerts_settings/components/alerts_settings_wrapper.vue @@ -7,6 +7,10 @@ import createFlash, { FLASH_TYPES } from '~/flash'; import getIntegrationsQuery from '../graphql/queries/get_integrations.query.graphql'; import createHttpIntegrationMutation from '../graphql/mutations/create_http_integration.mutation.graphql'; import createPrometheusIntegrationMutation from '../graphql/mutations/create_prometheus_integration.mutation.graphql'; +import updateHttpIntegrationMutation from '../graphql/mutations/update_http_integration.mutation.graphql'; +import updatePrometheusIntegrationMutation from '../graphql/mutations/update_prometheus_integration.mutation.graphql'; +import resetHttpTokenMutation from '../graphql/mutations/reset_http_token.mutation.graphql'; +import resetPrometheusTokenMutation from '../graphql/mutations/reset_prometheus_token.mutation.graphql'; import IntegrationsList from './alerts_integrations_list.vue'; import SettingsFormOld from './alerts_settings_form_old.vue'; import SettingsFormNew from './alerts_settings_form_new.vue'; @@ -52,16 +56,16 @@ export default { list, }; }, - error() { - this.errored = true; + error(err) { + createFlash({ message: err }); }, }, }, data() { return { - errored: false, isUpdating: false, integrations: {}, + currentIntegration: null, }; }, computed: { @@ -84,7 +88,7 @@ export default { }, }, methods: { - onCreateNewIntegration({ type, variables }) { + createNewIntegration({ type, variables }) { this.isUpdating = true; this.$apollo .mutate({ @@ -109,7 +113,6 @@ export default { }); }) .catch(err => { - this.errored = true; createFlash({ message: err }); }) .finally(() => { @@ -151,6 +154,72 @@ export default { data, }); }, + updateIntegration({ type, variables }) { + this.isUpdating = true; + this.$apollo + .mutate({ + mutation: + type === this.$options.typeSet.http + ? updateHttpIntegrationMutation + : updatePrometheusIntegrationMutation, + variables: { + ...variables, + id: this.currentIntegration.id, + }, + }) + .then(({ data: { httpIntegrationUpdate, prometheusIntegrationUpdate } = {} } = {}) => { + const error = httpIntegrationUpdate?.errors[0] || prometheusIntegrationUpdate?.errors[0]; + if (error) { + return createFlash({ message: error }); + } + return createFlash({ + message: this.$options.i18n.changesSaved, + type: FLASH_TYPES.SUCCESS, + }); + }) + .catch(err => { + createFlash({ message: err }); + }) + .finally(() => { + this.isUpdating = false; + }); + }, + resetToken({ type, variables }) { + this.isUpdating = true; + this.$apollo + .mutate({ + mutation: + type === this.$options.typeSet.http + ? resetHttpTokenMutation + : resetPrometheusTokenMutation, + variables, + }) + .then( + ({ data: { httpIntegrationResetToken, prometheusIntegrationResetToken } = {} } = {}) => { + const error = + httpIntegrationResetToken?.errors[0] || prometheusIntegrationResetToken?.errors[0]; + if (error) { + return createFlash({ message: error }); + } + return createFlash({ + message: this.$options.i18n.changesSaved, + type: FLASH_TYPES.SUCCESS, + }); + }, + ) + .catch(err => { + createFlash({ message: err }); + }) + .finally(() => { + this.isUpdating = false; + }); + }, + editIntegration({ id }) { + this.currentIntegration = this.integrations.list.find(integration => integration.id === id); + }, + deleteIntegration() { + // TODO, handle delete via GraphQL + }, }, }; </script> @@ -160,11 +229,16 @@ export default { <integrations-list :integrations="glFeatures.httpIntegrationsList ? integrations.list : intergrationsOptionsOld" :loading="loading" + @edit-integration="editIntegration" + @delete-integration="deleteIntegration" /> <settings-form-new v-if="glFeatures.httpIntegrationsList" - :loading="loading" - @on-create-new-integration="onCreateNewIntegration" + :loading="isUpdating" + :current-integration="currentIntegration" + @create-new-integration="createNewIntegration" + @update-integration="updateIntegration" + @reset-token="resetToken" /> <settings-form-old v-else /> </div> diff --git a/app/assets/javascripts/alerts_settings/constants.js b/app/assets/javascripts/alerts_settings/constants.js index 7e0422c100d..4ab8d215572 100644 --- a/app/assets/javascripts/alerts_settings/constants.js +++ b/app/assets/javascripts/alerts_settings/constants.js @@ -57,6 +57,15 @@ export const typeSet = { prometheus: 'PROMETHEUS', }; +export const defaultFormState = { + name: '', + active: false, + token: '', + url: '', + apiUrl: '', + integrationTestPayload: { json: null, error: null }, +}; + export const JSON_VALIDATE_DELAY = 250; export const targetPrometheusUrlPlaceholder = 'http://prometheus.example.com/'; diff --git a/app/assets/javascripts/alerts_settings/graphql/mutations/reset_http_token.mutation.graphql b/app/assets/javascripts/alerts_settings/graphql/mutations/reset_http_token.mutation.graphql new file mode 100644 index 00000000000..178d1e13047 --- /dev/null +++ b/app/assets/javascripts/alerts_settings/graphql/mutations/reset_http_token.mutation.graphql @@ -0,0 +1,10 @@ +#import "../fragments/integration_item.fragment.graphql" + +mutation resetHttpIntegrationToken($id: ID!) { + httpIntegrationResetToken(input: { id: $id }) { + errors + integration { + ...IntegrationItem + } + } +} diff --git a/app/assets/javascripts/alerts_settings/graphql/mutations/reset_prometheus_token.mutation.graphql b/app/assets/javascripts/alerts_settings/graphql/mutations/reset_prometheus_token.mutation.graphql new file mode 100644 index 00000000000..8f34521b9fd --- /dev/null +++ b/app/assets/javascripts/alerts_settings/graphql/mutations/reset_prometheus_token.mutation.graphql @@ -0,0 +1,10 @@ +#import "../fragments/integration_item.fragment.graphql" + +mutation resetPrometheusIntegrationToken($id: ID!) { + prometheusIntegrationResetToken(input: { id: $id }) { + errors + integration { + ...IntegrationItem + } + } +} diff --git a/app/assets/javascripts/alerts_settings/graphql/mutations/update_http_integration.mutation.graphql b/app/assets/javascripts/alerts_settings/graphql/mutations/update_http_integration.mutation.graphql new file mode 100644 index 00000000000..bb5b334deeb --- /dev/null +++ b/app/assets/javascripts/alerts_settings/graphql/mutations/update_http_integration.mutation.graphql @@ -0,0 +1,10 @@ +#import "../fragments/integration_item.fragment.graphql" + +mutation updateHttpIntegration($id: ID!, $name: String!, $active: Boolean!) { + httpIntegrationUpdate(input: { id: $id, name: $name, active: $active }) { + errors + integration { + ...IntegrationItem + } + } +} diff --git a/app/assets/javascripts/alerts_settings/graphql/mutations/update_prometheus_integration.mutation.graphql b/app/assets/javascripts/alerts_settings/graphql/mutations/update_prometheus_integration.mutation.graphql new file mode 100644 index 00000000000..62761730bd2 --- /dev/null +++ b/app/assets/javascripts/alerts_settings/graphql/mutations/update_prometheus_integration.mutation.graphql @@ -0,0 +1,10 @@ +#import "../fragments/integration_item.fragment.graphql" + +mutation updatePrometheusIntegration($id: ID!, $apiUrl: String!, $active: Boolean!) { + prometheusIntegrationUpdate(input: { id: $id, apiUrl: $apiUrl, active: $active }) { + errors + integration { + ...IntegrationItem + } + } +} diff --git a/app/assets/javascripts/alerts_settings/index.js b/app/assets/javascripts/alerts_settings/index.js index 611148cd103..2ae0dd447a1 100644 --- a/app/assets/javascripts/alerts_settings/index.js +++ b/app/assets/javascripts/alerts_settings/index.js @@ -50,7 +50,7 @@ export default el => { prometheus: { active: parseBoolean(prometheusActivated), url: prometheusUrl, - authKey: prometheusAuthorizationKey, + token: prometheusAuthorizationKey, prometheusFormPath, prometheusResetKeyPath, prometheusApiUrl, @@ -60,7 +60,7 @@ export default el => { alertsUsageUrl, active: parseBoolean(activatedStr), formPath, - authKey: authorizationKey, + token: authorizationKey, url, }, opsgenie: { diff --git a/app/assets/javascripts/design_management/components/upload/button.vue b/app/assets/javascripts/design_management/components/upload/button.vue index c76041c74a8..d7b287f663b 100644 --- a/app/assets/javascripts/design_management/components/upload/button.vue +++ b/app/assets/javascripts/design_management/components/upload/button.vue @@ -1,11 +1,10 @@ <script> -import { GlButton, GlLoadingIcon, GlTooltipDirective } from '@gitlab/ui'; +import { GlButton, GlTooltipDirective } from '@gitlab/ui'; import { VALID_DESIGN_FILE_MIMETYPE } from '../../constants'; export default { components: { GlButton, - GlLoadingIcon, }, directives: { GlTooltip: GlTooltipDirective, @@ -38,12 +37,12 @@ export default { ) " :disabled="isSaving" + :loading="isSaving" variant="default" size="small" @click="openFileUpload" > {{ s__('DesignManagement|Upload designs') }} - <gl-loading-icon v-if="isSaving" inline class="ml-1" /> </gl-button> <input diff --git a/app/assets/javascripts/integrations/edit/components/confirmation_modal.vue b/app/assets/javascripts/integrations/edit/components/confirmation_modal.vue index 890381a8f29..d4489bbf693 100644 --- a/app/assets/javascripts/integrations/edit/components/confirmation_modal.vue +++ b/app/assets/javascripts/integrations/edit/components/confirmation_modal.vue @@ -52,7 +52,7 @@ export default { <p class="gl-mb-0"> {{ s__( - 'Integrations|Projects using custom settings will not be impacted unless the project owner chooses to use instance-level defaults.', + 'Integrations|Projects using custom settings will not be impacted unless the project owner chooses to use parent level defaults.', ) }} </p> diff --git a/app/assets/javascripts/integrations/edit/components/integration_form.vue b/app/assets/javascripts/integrations/edit/components/integration_form.vue index 0fd39c5635d..e42a8b7de7c 100644 --- a/app/assets/javascripts/integrations/edit/components/integration_form.vue +++ b/app/assets/javascripts/integrations/edit/components/integration_form.vue @@ -38,8 +38,11 @@ export default { isJira() { return this.propsSource.type === 'jira'; }, - isInstanceLevel() { - return this.propsSource.integrationLevel === integrationLevels.INSTANCE; + isInstanceOrGroupLevel() { + return ( + this.propsSource.integrationLevel === integrationLevels.INSTANCE || + this.propsSource.integrationLevel === integrationLevels.GROUP + ); }, showJiraIssuesFields() { return this.isJira && this.glFeatures.jiraIssuesIntegration; @@ -91,7 +94,7 @@ export default { v-bind="propsSource.jiraIssuesProps" /> <div v-if="isEditable" class="footer-block row-content-block"> - <template v-if="isInstanceLevel"> + <template v-if="isInstanceOrGroupLevel"> <gl-button v-gl-modal.confirmSaveIntegration category="primary" diff --git a/app/assets/javascripts/integrations/edit/components/jira_trigger_fields.vue b/app/assets/javascripts/integrations/edit/components/jira_trigger_fields.vue index 08f24ce8ab6..123d794912a 100644 --- a/app/assets/javascripts/integrations/edit/components/jira_trigger_fields.vue +++ b/app/assets/javascripts/integrations/edit/components/jira_trigger_fields.vue @@ -108,12 +108,7 @@ export default { :label="s__('Integrations|Comment detail:')" data-testid="comment-detail" > - <input - v-if="isInheriting" - name="service[comment_detail]" - type="hidden" - :value="commentDetail" - /> + <input name="service[comment_detail]" type="hidden" :value="commentDetail" /> <gl-form-radio v-for="commentDetailOption in commentDetailOptions" :key="commentDetailOption.value" diff --git a/app/assets/javascripts/invite_members/components/invite_members_modal.vue b/app/assets/javascripts/invite_members/components/invite_members_modal.vue index d2ea14a658b..b47b22c4d44 100644 --- a/app/assets/javascripts/invite_members/components/invite_members_modal.vue +++ b/app/assets/javascripts/invite_members/components/invite_members_modal.vue @@ -6,13 +6,13 @@ import { GlDatepicker, GlLink, GlSprintf, - GlSearchBoxByType, GlButton, GlFormInput, } from '@gitlab/ui'; import eventHub from '../event_hub'; import { s__, sprintf } from '~/locale'; import Api from '~/api'; +import MembersTokenSelect from '~/invite_members/components/members_token_select.vue'; export default { name: 'InviteMembersModal', @@ -23,9 +23,9 @@ export default { GlDropdown, GlDropdownItem, GlSprintf, - GlSearchBoxByType, GlButton, GlFormInput, + MembersTokenSelect, }, props: { groupId: { @@ -129,44 +129,45 @@ export default { }, labels: { modalTitle: s__('InviteMembersModal|Invite team members'), - userToInvite: s__('InviteMembersModal|GitLab member or Email address'), + newUsersToInvite: s__('InviteMembersModal|GitLab member or Email address'), userPlaceholder: s__('InviteMembersModal|Search for members to invite'), accessLevel: s__('InviteMembersModal|Choose a role permission'), accessExpireDate: s__('InviteMembersModal|Access expiration date (optional)'), - toastMessageSuccessful: s__('InviteMembersModal|Users were succesfully added'), - toastMessageUnsuccessful: s__('InviteMembersModal|User not invited. Feature coming soon!'), + toastMessageSuccessful: s__('InviteMembersModal|Members were successfully added'), + toastMessageUnsuccessful: s__('InviteMembersModal|Some of the members could not be added'), readMoreText: s__(`InviteMembersModal|%{linkStart}Read more%{linkEnd} about role permissions`), inviteButtonText: s__('InviteMembersModal|Invite'), cancelButtonText: s__('InviteMembersModal|Cancel'), + headerCloseLabel: s__('InviteMembersModal|Close invite team members'), }, + membersTokenSelectLabelId: 'invite-members-input', }; </script> <template> - <gl-modal :modal-id="modalId" size="sm" :title="$options.labels.modalTitle"> + <gl-modal + :modal-id="modalId" + size="sm" + :title="$options.labels.modalTitle" + :header-close-label="$options.labels.headerCloseLabel" + > <div class="gl-ml-5 gl-mr-5"> <div>{{ introText }}</div> - <label class="gl-font-weight-bold gl-mt-5">{{ $options.labels.userToInvite }}</label> + <label :id="$options.membersTokenSelectLabelId" class="gl-font-weight-bold gl-mt-5">{{ + $options.labels.newUsersToInvite + }}</label> <div class="gl-mt-2"> - <gl-search-box-by-type + <members-token-select v-model="newUsersToInvite" + :label="$options.labels.newUsersToInvite" + :aria-labelledby="$options.membersTokenSelectLabelId" :placeholder="$options.labels.userPlaceholder" - type="text" - autocomplete="off" - autocorrect="off" - autocapitalize="off" - spellcheck="false" /> </div> <label class="gl-font-weight-bold gl-mt-5">{{ $options.labels.accessLevel }}</label> <div class="gl-mt-2 gl-w-half gl-xs-w-full"> - <gl-dropdown - menu-class="dropdown-menu-selectable" - class="gl-shadow-none gl-w-full" - v-bind="$attrs" - :text="selectedRoleName" - > + <gl-dropdown class="gl-shadow-none gl-w-full" v-bind="$attrs" :text="selectedRoleName"> <template v-for="(key, item) in accessLevels"> <gl-dropdown-item :key="key" @@ -215,9 +216,13 @@ export default { {{ $options.labels.cancelButtonText }} </gl-button> <div class="gl-mr-3"></div> - <gl-button ref="inviteButton" variant="success" @click="sendInvite">{{ - $options.labels.inviteButtonText - }}</gl-button> + <gl-button + ref="inviteButton" + :disabled="!newUsersToInvite" + variant="success" + @click="sendInvite" + >{{ $options.labels.inviteButtonText }}</gl-button + > </div> </template> </gl-modal> diff --git a/app/assets/javascripts/invite_members/components/members_token_select.vue b/app/assets/javascripts/invite_members/components/members_token_select.vue new file mode 100644 index 00000000000..aed2e5e3236 --- /dev/null +++ b/app/assets/javascripts/invite_members/components/members_token_select.vue @@ -0,0 +1,120 @@ +<script> +import { debounce } from 'lodash'; +import { GlTokenSelector, GlAvatar, GlAvatarLabeled } from '@gitlab/ui'; +import { USER_SEARCH_DELAY } from '../constants'; +import Api from '~/api'; + +export default { + components: { + GlTokenSelector, + GlAvatar, + GlAvatarLabeled, + }, + props: { + placeholder: { + type: String, + required: false, + default: '', + }, + ariaLabelledby: { + type: String, + required: true, + }, + }, + data() { + return { + loading: false, + query: '', + users: [], + selectedTokens: [], + hasBeenFocused: false, + hideDropdownWithNoItems: true, + }; + }, + computed: { + newUsersToInvite() { + return this.selectedTokens + .map(obj => { + return obj.id; + }) + .join(','); + }, + placeholderText() { + if (this.selectedTokens.length === 0) { + return this.placeholder; + } + return ''; + }, + }, + methods: { + handleTextInput(query) { + this.hideDropdownWithNoItems = false; + this.query = query; + this.loading = true; + this.retrieveUsers(query); + }, + retrieveUsers: debounce(function debouncedRetrieveUsers() { + return Api.users(this.query, this.$options.queryOptions) + .then(response => { + this.users = response.data.map(token => ({ + id: token.id, + name: token.name, + username: token.username, + avatar_url: token.avatar_url, + })); + this.loading = false; + }) + .catch(() => { + this.loading = false; + }); + }, USER_SEARCH_DELAY), + handleInput() { + this.$emit('input', this.newUsersToInvite); + }, + handleBlur() { + this.hideDropdownWithNoItems = false; + }, + handleFocus() { + // The modal auto-focuses on the input when opened. + // This prevents the dropdown from opening when the modal opens. + if (this.hasBeenFocused) { + this.loading = true; + this.retrieveUsers(); + } + + this.hasBeenFocused = true; + }, + }, + queryOptions: { exclude_internal: true, active: true }, +}; +</script> + +<template> + <gl-token-selector + v-model="selectedTokens" + :dropdown-items="users" + :loading="loading" + :allow-user-defined-tokens="false" + :hide-dropdown-with-no-items="hideDropdownWithNoItems" + :placeholder="placeholderText" + :aria-labelledby="ariaLabelledby" + @blur="handleBlur" + @text-input="handleTextInput" + @input="handleInput" + @focus="handleFocus" + > + <template #token-content="{ token }"> + <gl-avatar v-if="token.avatar_url" :src="token.avatar_url" :size="16" /> + {{ token.name }} + </template> + + <template #dropdown-item-content="{ dropdownItem }"> + <gl-avatar-labeled + :src="dropdownItem.avatar_url" + :size="32" + :label="dropdownItem.name" + :sub-label="dropdownItem.username" + /> + </template> + </gl-token-selector> +</template> diff --git a/app/assets/javascripts/invite_members/constants.js b/app/assets/javascripts/invite_members/constants.js new file mode 100644 index 00000000000..1ff2125c292 --- /dev/null +++ b/app/assets/javascripts/invite_members/constants.js @@ -0,0 +1 @@ +export const USER_SEARCH_DELAY = 200; diff --git a/app/assets/javascripts/jira_connect/.eslintrc.yml b/app/assets/javascripts/jira_connect/.eslintrc.yml new file mode 100644 index 00000000000..053f8c6b285 --- /dev/null +++ b/app/assets/javascripts/jira_connect/.eslintrc.yml @@ -0,0 +1,5 @@ +globals: + AP: readonly +rules: + '@gitlab/require-i18n-strings': off + '@gitlab/vue-require-i18n-strings': off diff --git a/app/assets/javascripts/jira_connect/components/app.vue b/app/assets/javascripts/jira_connect/components/app.vue new file mode 100644 index 00000000000..6d32ba41eae --- /dev/null +++ b/app/assets/javascripts/jira_connect/components/app.vue @@ -0,0 +1,7 @@ +<script> +export default {}; +</script> + +<template> + <div></div> +</template> diff --git a/app/assets/javascripts/jira_connect/index.js b/app/assets/javascripts/jira_connect/index.js new file mode 100644 index 00000000000..37f00d56a05 --- /dev/null +++ b/app/assets/javascripts/jira_connect/index.js @@ -0,0 +1,15 @@ +import Vue from 'vue'; +import App from './components/app.vue'; + +function initJiraConnect() { + const el = document.querySelector('.js-jira-connect-app'); + + return new Vue({ + el, + render(createElement) { + return createElement(App, {}); + }, + }); +} + +document.addEventListener('DOMContentLoaded', initJiraConnect); diff --git a/app/assets/stylesheets/bootstrap_migration.scss b/app/assets/stylesheets/bootstrap_migration.scss index 165feba4a81..3d5076f485c 100644 --- a/app/assets/stylesheets/bootstrap_migration.scss +++ b/app/assets/stylesheets/bootstrap_migration.scss @@ -115,14 +115,10 @@ code { background-color: $gray-50; border-radius: $border-radius-default; - .code > & { - background-color: inherit; - padding: unset; - } - + .code > &, .build-trace & { background-color: inherit; - padding: inherit; + padding: unset; } } diff --git a/app/assets/stylesheets/page_bundles/jira_connect.scss b/app/assets/stylesheets/page_bundles/jira_connect.scss index b8cdd120e04..c3e49da92a6 100644 --- a/app/assets/stylesheets/page_bundles/jira_connect.scss +++ b/app/assets/stylesheets/page_bundles/jira_connect.scss @@ -1,4 +1,6 @@ -@import 'framework/variables'; +@import 'mixins_and_variables_and_functions'; +// We should only import styles that we actually use. +// @import '@gitlab/ui/src/scss/gitlab_ui'; $atlaskit-border-color: #dfe1e6; diff --git a/app/helpers/page_layout_helper.rb b/app/helpers/page_layout_helper.rb index 0551d1cd784..7630524b545 100644 --- a/app/helpers/page_layout_helper.rb +++ b/app/helpers/page_layout_helper.rb @@ -150,6 +150,14 @@ module PageLayoutHelper css_class.join(' ') end + def page_itemtype(itemtype = nil) + if itemtype + @page_itemtype = { itemscope: true, itemtype: itemtype } + else + @page_itemtype || {} + end + end + private def generic_canonical_url diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb index f47937e6d57..2962a089064 100644 --- a/app/helpers/users_helper.rb +++ b/app/helpers/users_helper.rb @@ -91,18 +91,18 @@ module UsersHelper end end - def work_information(user) + def work_information(user, with_schema_markup: false) return unless user organization = user.organization job_title = user.job_title if organization.present? && job_title.present? - s_('Profile|%{job_title} at %{organization}') % { job_title: job_title, organization: organization } + render_job_title_and_organization(job_title, organization, with_schema_markup: with_schema_markup) elsif job_title.present? - job_title + render_job_title(job_title, with_schema_markup: with_schema_markup) elsif organization.present? - organization + render_organization(organization, with_schema_markup: with_schema_markup) end end @@ -151,6 +151,35 @@ module UsersHelper items end + + def render_job_title(job_title, with_schema_markup: false) + if with_schema_markup + content_tag :span, itemprop: 'jobTitle' do + job_title + end + else + job_title + end + end + + def render_organization(organization, with_schema_markup: false) + if with_schema_markup + content_tag :span, itemprop: 'worksFor' do + organization + end + else + organization + end + end + + def render_job_title_and_organization(job_title, organization, with_schema_markup: false) + if with_schema_markup + job_title = '<span itemprop="jobTitle">'.html_safe + job_title + "</span>".html_safe + organization = '<span itemprop="worksFor">'.html_safe + organization + "</span>".html_safe + end + + html_escape(s_('Profile|%{job_title} at %{organization}')) % { job_title: job_title, organization: organization } + end end UsersHelper.prepend_if_ee('EE::UsersHelper') diff --git a/app/views/jira_connect/subscriptions/index.html.haml b/app/views/jira_connect/subscriptions/index.html.haml index 655c413f2a6..5156472d203 100644 --- a/app/views/jira_connect/subscriptions/index.html.haml +++ b/app/views/jira_connect/subscriptions/index.html.haml @@ -21,6 +21,8 @@ .gl-mt-5 %p Note: this integration only works with accounts on GitLab.com (SaaS). - else + .js-jira-connect-app + %form#add-subscription-form.subscription-form{ action: jira_connect_subscriptions_path } .ak-field-group %label @@ -57,5 +59,8 @@ or enable cross-site cookies in your browser when adding a namespace. %a{ href: 'https://gitlab.com/gitlab-org/gitlab/-/issues/263509', target: '_blank', rel: 'noopener noreferrer' } Learn more += webpack_bundle_tag 'performance_bar' if performance_bar_enabled? += webpack_bundle_tag 'jira_connect_app' + = page_specific_javascript_tag('jira_connect.js') - add_page_specific_style 'page_bundles/jira_connect' diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml index 9b925369660..a75493e4a16 100644 --- a/app/views/layouts/_page.html.haml +++ b/app/views/layouts/_page.html.haml @@ -20,6 +20,6 @@ - unless @hide_breadcrumbs = render "layouts/nav/breadcrumbs" %div{ class: "#{(container_class unless @no_container)} #{@content_class}" } - .content{ id: "content-body" } + .content{ id: "content-body", **page_itemtype } = render "layouts/flash", extra_flash_class: 'limit-container-width' = yield diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml index 2746a139dd0..90e0b230948 100644 --- a/app/views/users/show.html.haml +++ b/app/views/users/show.html.haml @@ -4,6 +4,7 @@ - page_title @user.blocked? ? s_('UserProfile|Blocked user') : @user.name - page_description @user.bio_html - header_title @user.name, user_path(@user) +- page_itemtype 'http://schema.org/Person' - link_classes = "flex-grow-1 mx-1 " = content_for :meta_tags do @@ -35,7 +36,7 @@ .profile-header{ class: [('with-no-profile-tabs' if profile_tabs.empty?)] } .avatar-holder = link_to avatar_icon_for_user(@user, 400), target: '_blank', rel: 'noopener noreferrer' do - = image_tag avatar_icon_for_user(@user, 90), class: "avatar s90", alt: '' + = image_tag avatar_icon_for_user(@user, 90), class: "avatar s90", alt: '', itemprop: 'image' - if @user.blocked? .user-info @@ -44,7 +45,7 @@ = render "users/profile_basic_info" - else .user-info - .cover-title + .cover-title{ itemprop: 'name' } = @user.name - if @user.status @@ -54,15 +55,15 @@ = render "users/profile_basic_info" .cover-desc.cgray.mb-1.mb-sm-2 - unless @user.location.blank? - .profile-link-holder.middle-dot-divider-sm.d-block.d-sm-inline.mb-1.mb-sm-0 + .profile-link-holder.middle-dot-divider-sm.d-block.d-sm-inline.mb-1.mb-sm-0{ itemprop: 'address', itemscope: true, itemtype: 'https://schema.org/PostalAddress' } = sprite_icon('location', css_class: 'vertical-align-sub fgray') - %span.vertical-align-middle + %span.vertical-align-middle{ itemprop: 'addressLocality' } = @user.location - unless work_information(@user).blank? .profile-link-holder.middle-dot-divider-sm.d-block.d-sm-inline = sprite_icon('work', css_class: 'vertical-align-middle fgray') %span.vertical-align-middle - = work_information(@user) + = work_information(@user, with_schema_markup: true) .cover-desc.cgray.mb-1.mb-sm-2 - unless @user.skype.blank? .profile-link-holder.middle-dot-divider @@ -80,10 +81,10 @@ .profile-link-holder.middle-dot-divider-sm.d-block.d-sm-inline.mt-1.mt-sm-0 - if Feature.enabled?(:security_auto_fix) && @user.bot? = sprite_icon('question', css_class: 'gl-text-blue-600') - = link_to @user.short_website_url, @user.full_website_url, class: 'text-link', target: '_blank', rel: 'me noopener noreferrer nofollow' + = link_to @user.short_website_url, @user.full_website_url, class: 'text-link', target: '_blank', rel: 'me noopener noreferrer nofollow', itemprop: 'url' - unless @user.public_email.blank? .profile-link-holder.middle-dot-divider-sm.d-block.d-sm-inline.mt-1.mt-sm-0 - = link_to @user.public_email, "mailto:#{@user.public_email}", class: 'text-link' + = link_to @user.public_email, "mailto:#{@user.public_email}", class: 'text-link', itemprop: 'email' - if @user.bio.present? .cover-desc.cgray .profile-user-bio diff --git a/changelogs/unreleased/273261-not-able-to-set-comment-settings-for-jira.yml b/changelogs/unreleased/273261-not-able-to-set-comment-settings-for-jira.yml new file mode 100644 index 00000000000..1aecd98c60a --- /dev/null +++ b/changelogs/unreleased/273261-not-able-to-set-comment-settings-for-jira.yml @@ -0,0 +1,5 @@ +--- +title: Fix setting Comment detail for Jira and modal for groups +merge_request: 46945 +author: +type: fixed diff --git a/changelogs/unreleased/273750-fj-structured-data-for-users.yml b/changelogs/unreleased/273750-fj-structured-data-for-users.yml new file mode 100644 index 00000000000..26f421e806a --- /dev/null +++ b/changelogs/unreleased/273750-fj-structured-data-for-users.yml @@ -0,0 +1,5 @@ +--- +title: Add structured markup for users +merge_request: 46553 +author: +type: added diff --git a/changelogs/unreleased/design-upload-button-loading-prop.yml b/changelogs/unreleased/design-upload-button-loading-prop.yml new file mode 100644 index 00000000000..ab8b53d7922 --- /dev/null +++ b/changelogs/unreleased/design-upload-button-loading-prop.yml @@ -0,0 +1,5 @@ +--- +title: Use standard loading state for Design Upload button +merge_request: 46292 +author: +type: changed diff --git a/changelogs/unreleased/fix-padding-on-failed-job-tab.yml b/changelogs/unreleased/fix-padding-on-failed-job-tab.yml new file mode 100644 index 00000000000..5dcbbdcdc01 --- /dev/null +++ b/changelogs/unreleased/fix-padding-on-failed-job-tab.yml @@ -0,0 +1,5 @@ +--- +title: Fix code lines being cut-off on failed job tab +merge_request: 46885 +author: +type: fixed diff --git a/changelogs/unreleased/move-timebox-reports-graphql.yml b/changelogs/unreleased/move-timebox-reports-graphql.yml new file mode 100644 index 00000000000..32fb2c59894 --- /dev/null +++ b/changelogs/unreleased/move-timebox-reports-graphql.yml @@ -0,0 +1,5 @@ +--- +title: Add GraphQL burnup endpoint under milestone and iteration reports +merge_request: 45121 +author: +type: added diff --git a/config/feature_flags/development/security_on_demand_scans_http_header_validation.yml b/config/feature_flags/development/security_on_demand_scans_http_header_validation.yml new file mode 100644 index 00000000000..475cbfa4d9a --- /dev/null +++ b/config/feature_flags/development/security_on_demand_scans_http_header_validation.yml @@ -0,0 +1,8 @@ +--- +name: security_on_demand_scans_http_header_validation +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/42812 +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/276403 +milestone: '13.6' +type: development +group: group::dynamic analysis +default_enabled: false diff --git a/config/webpack.config.js b/config/webpack.config.js index 821ddc84e1a..aae05ba270c 100644 --- a/config/webpack.config.js +++ b/config/webpack.config.js @@ -82,6 +82,7 @@ function generateEntries() { // sentry: './sentry/index.js', Temporarily commented out to investigate performance: https://gitlab.com/gitlab-org/gitlab/-/issues/251179 performance_bar: './performance_bar/index.js', chrome_84_icon_fix: './lib/chrome_84_icon_fix.js', + jira_connect_app: './jira_connect/index.js', }; return Object.assign(manualEntries, autoEntries); diff --git a/doc/api/graphql/reference/gitlab_schema.graphql b/doc/api/graphql/reference/gitlab_schema.graphql index f0e159093e6..a82329ad835 100644 --- a/doc/api/graphql/reference/gitlab_schema.graphql +++ b/doc/api/graphql/reference/gitlab_schema.graphql @@ -10818,7 +10818,7 @@ enum IssueType { """ Represents an iteration object """ -type Iteration implements TimeboxBurnupTimeSeriesInterface { +type Iteration implements TimeboxReportInterface { """ Daily scope and completed totals for burnup charts """ @@ -10855,6 +10855,11 @@ type Iteration implements TimeboxBurnupTimeSeriesInterface { iid: ID! """ + Historically accurate report about the timebox + """ + report: TimeboxReport + + """ Web path of the iteration, scoped to the query parent. Only valid for Project parents. Returns null in other contexts """ scopedPath: String @@ -12831,7 +12836,7 @@ type MetricsDashboardAnnotationEdge { """ Represents a milestone """ -type Milestone implements TimeboxBurnupTimeSeriesInterface { +type Milestone implements TimeboxReportInterface { """ Daily scope and completed totals for burnup charts """ @@ -12868,6 +12873,11 @@ type Milestone implements TimeboxBurnupTimeSeriesInterface { projectMilestone: Boolean! """ + Historically accurate report about the timebox + """ + report: TimeboxReport + + """ Timestamp of the milestone start date """ startDate: Time @@ -20155,13 +20165,28 @@ Time represented in ISO 8601 """ scalar Time -interface TimeboxBurnupTimeSeriesInterface { +""" +Represents a historically accurate report about the timebox +""" +type TimeboxReport { """ Daily scope and completed totals for burnup charts """ burnupTimeSeries: [BurnupChartDailyTotals!] } +interface TimeboxReportInterface { + """ + Daily scope and completed totals for burnup charts + """ + burnupTimeSeries: [BurnupChartDailyTotals!] + + """ + Historically accurate report about the timebox + """ + report: TimeboxReport +} + """ A time-frame defined as a closed inclusive range of two dates """ diff --git a/doc/api/graphql/reference/gitlab_schema.json b/doc/api/graphql/reference/gitlab_schema.json index 434c3e0aef1..d09396fb680 100644 --- a/doc/api/graphql/reference/gitlab_schema.json +++ b/doc/api/graphql/reference/gitlab_schema.json @@ -29534,6 +29534,20 @@ "deprecationReason": null }, { + "name": "report", + "description": "Historically accurate report about the timebox", + "args": [ + + ], + "type": { + "kind": "OBJECT", + "name": "TimeboxReport", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { "name": "scopedPath", "description": "Web path of the iteration, scoped to the query parent. Only valid for Project parents. Returns null in other contexts", "args": [ @@ -29670,7 +29684,7 @@ "interfaces": [ { "kind": "INTERFACE", - "name": "TimeboxBurnupTimeSeriesInterface", + "name": "TimeboxReportInterface", "ofType": null } ], @@ -35319,6 +35333,20 @@ "deprecationReason": null }, { + "name": "report", + "description": "Historically accurate report about the timebox", + "args": [ + + ], + "type": { + "kind": "OBJECT", + "name": "TimeboxReport", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { "name": "startDate", "description": "Timestamp of the milestone start date", "args": [ @@ -35441,7 +35469,7 @@ "interfaces": [ { "kind": "INTERFACE", - "name": "TimeboxBurnupTimeSeriesInterface", + "name": "TimeboxReportInterface", "ofType": null } ], @@ -58504,8 +58532,43 @@ "possibleTypes": null }, { + "kind": "OBJECT", + "name": "TimeboxReport", + "description": "Represents a historically accurate report about the timebox", + "fields": [ + { + "name": "burnupTimeSeries", + "description": "Daily scope and completed totals for burnup charts", + "args": [ + + ], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "BurnupChartDailyTotals", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + + ], + "enumValues": null, + "possibleTypes": null + }, + { "kind": "INTERFACE", - "name": "TimeboxBurnupTimeSeriesInterface", + "name": "TimeboxReportInterface", "description": null, "fields": [ { @@ -58529,6 +58592,20 @@ }, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "report", + "description": "Historically accurate report about the timebox", + "args": [ + + ], + "type": { + "kind": "OBJECT", + "name": "TimeboxReport", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null } ], "inputFields": null, diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index be355d77e31..db0e92892a1 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -1652,6 +1652,7 @@ Represents an iteration object. | `dueDate` | Time | Timestamp of the iteration due date | | `id` | ID! | ID of the iteration | | `iid` | ID! | Internal ID of the iteration | +| `report` | TimeboxReport | Historically accurate report about the timebox | | `scopedPath` | String | Web path of the iteration, scoped to the query parent. Only valid for Project parents. Returns null in other contexts | | `scopedUrl` | String | Web URL of the iteration, scoped to the query parent. Only valid for Project parents. Returns null in other contexts | | `startDate` | Time | Timestamp of the iteration start date | @@ -1964,6 +1965,7 @@ Represents a milestone. | `groupMilestone` | Boolean! | Indicates if milestone is at group level | | `id` | ID! | ID of the milestone | | `projectMilestone` | Boolean! | Indicates if milestone is at project level | +| `report` | TimeboxReport | Historically accurate report about the timebox | | `startDate` | Time | Timestamp of the milestone start date | | `state` | MilestoneStateEnum! | State of the milestone | | `stats` | MilestoneStats | Milestone statistics | @@ -2958,6 +2960,14 @@ Represents a requirement test report. | `id` | ID! | ID of the test report | | `state` | TestReportState! | State of the test report | +### TimeboxReport + +Represents a historically accurate report about the timebox. + +| Field | Type | Description | +| ----- | ---- | ----------- | +| `burnupTimeSeries` | BurnupChartDailyTotals! => Array | Daily scope and completed totals for burnup charts | + ### Timelog | Field | Type | Description | diff --git a/doc/ci/merge_request_pipelines/index.md b/doc/ci/merge_request_pipelines/index.md index 6e95bcc5df2..ac9cda4e46c 100644 --- a/doc/ci/merge_request_pipelines/index.md +++ b/doc/ci/merge_request_pipelines/index.md @@ -128,12 +128,6 @@ This helps you avoid having to add the `only:` rule to all of your jobs to make them always run. You can use this format to set up a Review App, helping to save resources. -### Using SAST, DAST, and other Secure Templates with Pipelines for Merge Requests - -To use [Secure templates](https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/ci/templates/Security) -with pipelines for merge requests, you may need to apply a `rules: if: merge_request_event` for the -Secure scans to run in the same pipeline as the commit. - #### Excluding certain branches Pipelines for merge requests require special treatment when diff --git a/doc/development/contributing/merge_request_workflow.md b/doc/development/contributing/merge_request_workflow.md index 0d2e94d4359..d5ffff7bfc8 100644 --- a/doc/development/contributing/merge_request_workflow.md +++ b/doc/development/contributing/merge_request_workflow.md @@ -138,13 +138,14 @@ Commit messages should follow the guidelines below, for reasons explained by Chr - The merge request should not contain more than 10 commit messages. - The commit subject should contain at least 3 words. -CAUTION: **Caution:** -If the guidelines are not met, the MR may not pass the -[Danger checks](https://gitlab.com/gitlab-org/gitlab/blob/master/danger/commit_messages/Dangerfile). - -TIP: **Tip:** -Consider enabling [Squash and merge](../../user/project/merge_requests/squash_and_merge.md#squash-and-merge) if your merge -request includes "Applied suggestion to X files" commits, so that Danger can ignore those. +**Important notes:** + +- If the guidelines are not met, the MR may not pass the [Danger checks](https://gitlab.com/gitlab-org/gitlab/blob/master/danger/commit_messages/Dangerfile). +- Consider enabling [Squash and merge](../../user/project/merge_requests/squash_and_merge.md#squash-and-merge) + if your merge request includes "Applied suggestion to X files" commits, so that Danger can ignore those. +- The prefixes in the form of `[prefix]` and `prefix:` are allowed (they can be all lowercase, as long + as the message itself is capitalized). For instance, `danger: Improve Danger behavior` and + `[API] Improve the labels endpoint` are valid commit messages. #### Why these standards matter diff --git a/doc/development/fe_guide/security.md b/doc/development/fe_guide/security.md index 64095ce3a60..a82c315032f 100644 --- a/doc/development/fe_guide/security.md +++ b/doc/development/fe_guide/security.md @@ -83,3 +83,25 @@ inject scripts into the web app. Inline styles should be avoided in almost all cases, they should only be used when no alternatives can be found. This allows reusability of styles as well as readability. + +### Sanitize HTML output + +If you need to output raw HTML, you should sanitize it. + +If you are using Vue, you can use the[`v-safe-html` directive](https://gitlab-org.gitlab.io/gitlab-ui/?path=/story/directives-safe-html-directive--default) from GitLab UI. + +For other use cases, wrap a preconfigured version of [`dompurify`](https://www.npmjs.com/package/dompurify) +that also allows the icons to be rendered: + +```javascript +import { sanitize } from '~/lib/dompurify'; + +const unsafeHtml = '<some unsafe content ... >'; + +// ... + +element.appendChild(sanitize(unsafeHtml)); +``` + +This `sanitize` function takes the same configuration as the +original. diff --git a/doc/development/secure_coding_guidelines.md b/doc/development/secure_coding_guidelines.md index 5575a70c71a..e7dc24201aa 100644 --- a/doc/development/secure_coding_guidelines.md +++ b/doc/development/secure_coding_guidelines.md @@ -329,6 +329,7 @@ References: - When updating the content of an HTML element using JavaScript, mark user-controlled values as `textContent` or `nodeValue` instead of `innerHTML`. - Avoid using `v-html` with user-controlled data, use [`v-safe-html`](https://gitlab-org.gitlab.io/gitlab-ui/?path=/story/directives-safe-html-directive--default) instead. +- Render unsafe or unsanitized content using [`dompurify`](fe_guide/security.md#sanitize-html-output). - Consider using [`gl-sprintf`](../../ee/development/i18n/externalization.md#interpolation) to interpolate translated strings securely. - Avoid `__()` with translations that contain user-controlled values. - When working with `postMessage`, ensure the `origin` of the message is allowlisted. diff --git a/doc/development/testing_guide/end_to_end/rspec_metadata_tests.md b/doc/development/testing_guide/end_to_end/rspec_metadata_tests.md index 66922ca8471..8e99cf18ea0 100644 --- a/doc/development/testing_guide/end_to_end/rspec_metadata_tests.md +++ b/doc/development/testing_guide/end_to_end/rspec_metadata_tests.md @@ -16,7 +16,7 @@ This is a partial list of the [RSpec metadata](https://relishapp.com/rspec/rspec | `:elasticsearch` | The test requires an Elasticsearch service. It is used by the [instance-level scenario](https://gitlab.com/gitlab-org/gitlab-qa#definitions) [`Test::Integration::Elasticsearch`](https://gitlab.com/gitlab-org/gitlab/-/blob/72b62b51bdf513e2936301cb6c7c91ec27c35b4d/qa/qa/ee/scenario/test/integration/elasticsearch.rb) to include only tests that require Elasticsearch. | | `:gitaly_cluster` | The test will run against a GitLab instance where repositories are stored on redundant Gitaly nodes behind a Praefect node. All nodes are [separate containers](../../../administration/gitaly/praefect.md#requirements-for-configuring-a-gitaly-cluster). Tests that use this tag have a longer setup time since there are three additional containers that need to be started. | | `:jira` | The test requires a Jira Server. [GitLab-QA](https://gitlab.com/gitlab-org/gitlab-qa) will provision the Jira Server in a Docker container when the `Test::Integration::Jira` test scenario is run. -| `:kubernetes` | The test includes a GitLab instance that is configured to be run behind an SSH tunnel, allowing a TLS-accessible GitLab. This test will also include provisioning of at least one Kubernetes cluster to test against. *This tag is often be paired with `:orchestrated`.* | +| `:kubernetes` | The test includes a GitLab instance that is configured to be run behind an SSH tunnel, allowing a TLS-accessible GitLab. This test will also include provisioning of at least one Kubernetes cluster to test against. _This tag is often be paired with `:orchestrated`._ | | `:only` | The test is only to be run against specific environments or pipelines. See [Environment selection](environment_selection.md) for more information. | | `:orchestrated` | The GitLab instance under test may be [configured by `gitlab-qa`](https://gitlab.com/gitlab-org/gitlab-qa/-/blob/master/docs/what_tests_can_be_run.md#orchestrated-tests) to be different to the default GitLab configuration, or `gitlab-qa` may launch additional services in separate Docker containers, or both. Tests tagged with `:orchestrated` are excluded when testing environments where we can't dynamically modify GitLab's configuration (for example, Staging). | | `:quarantine` | The test has been [quarantined](https://about.gitlab.com/handbook/engineering/quality/guidelines/debugging-qa-test-failures/#quarantining-tests), will run in a separate job that only includes quarantined tests, and is allowed to fail. The test will be skipped in its regular job so that if it fails it will not hold up the pipeline. Note that you can also [quarantine a test only when it runs against specific environment](environment_selection.md#quarantining-a-test-for-a-specific-environment). | @@ -25,3 +25,20 @@ This is a partial list of the [RSpec metadata](https://relishapp.com/rspec/rspec | `:runner` | The test depends on and will set up a GitLab Runner instance, typically to run a pipeline. | | `:skip_live_env` | The test will be excluded when run against live deployed environments such as Staging, Canary, and Production. | | `:testcase` | The link to the test case issue in the [Quality Testcases project](https://gitlab.com/gitlab-org/quality/testcases/). | +| `:mattermost` | The test requires a GitLab Mattermost service on the GitLab instance. | +| `:ldap_no_server` | The test requires a GitLab instance to be configured to use LDAP. To be used with the `:orchestrated` tag. It does not spin up an LDAP server at orchestration time. Instead, it creates the LDAP server at runtime. | +| `:ldap_no_tls` | The test requires a GitLab instance to be configured to use an external LDAP server with TLS not enabled. | +| `:ldap_tls` | The test requires a GitLab instance to be configured to use an external LDAP server with TLS enabled. | +| `:object_storage` | The test requires a GitLab instance to be configured to use multiple [object storage types](../../../administration/object_storage.md). Uses MinIO as the object storage server. | +| `:smtp` | The test requires a GitLab instance to be configured to use an SMTP server. Tests SMTP notification email delivery from GitLab by using MailHog. | +| `:group_saml` | The test requires a GitLab instance that has SAML SSO enabled at the group level. Interacts with an external SAML identity provider. Paired with the `:orchestrated` tag. | +| `:instance_saml` | The test requires a GitLab instance that has SAML SSO enabled at the instance level. Interacts with an external SAML identity provider. Paired with the `:orchestrated` tag. | +| `:skip_signup_disabled` | The test uses UI to sign up a new user and will be skipped in any environment that does not allow new user registration via the UI. | +| `:smoke` | The test belongs to the test suite which verifies basic functionality of a GitLab instance.| +| `:github` | The test requires a GitHub personal access token. | +| `:repository_storage` | The test requires a GitLab instance to be configured to use multiple [repository storage paths](../../../administration/repository_storage_paths.md). Paired with the `:orchestrated` tag. | +| `:geo` | The test requires two GitLab Geo instances - a primary and a secondary - to be spun up. | +| `:relative_url` | The test requires a GitLab instance to be installed under a [relative URL](../../../install/relative_url.md). | +| `:requires_git_protocol_v2` | The test requires that Git protocol version 2 is enabled on the server. It's assumed to be enabled by default but if not the test can be skipped by setting `QA_CAN_TEST_GIT_PROTOCOL_V2` to `false`. | +| `:requires_praefect` | The test requires that the GitLab instance uses [Gitaly Cluster](../../../administration/gitaly/praefect.md) (a.k.a. Praefect) as the repository storage . It's assumed to be used by default but if not the test can be skipped by setting `QA_CAN_TEST_PRAEFECT` to `false`. | +| `:packages` | The test requires a GitLab instance that has the [Package Registry](../../../administration/packages/#gitlab-package-registry-administration) enabled. | diff --git a/doc/policy/maintenance.md b/doc/policy/maintenance.md index f742487f2fa..2cfc2923616 100644 --- a/doc/policy/maintenance.md +++ b/doc/policy/maintenance.md @@ -1,6 +1,6 @@ --- -stage: none -group: unassigned +stage: Enablement +group: Distribution info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers type: concepts --- @@ -57,21 +57,11 @@ one major version. For example, it is safe to: - `12.7.5` -> `12.10.5` - `11.3.4` -> `11.11.1` - - `10.6.6` -> `10.8.3` - - `11.3.4` -> `11.11.8` - - `10.6.6` -> `10.8.7` - - `9.2.3` -> `9.5.5` - - `8.9.4` -> `8.12.3` - Upgrade the *patch* version. For example: - `12.0.4` -> `12.0.12` - `11.11.1` -> `11.11.8` - - `10.6.3` -> `10.6.6` - - `11.11.1` -> `11.11.8` - - `10.6.3` -> `10.6.6` - - `9.5.5` -> `9.5.9` - - `8.9.2` -> `8.9.6` NOTE: **Note:** Version specific changes in Omnibus GitLab Linux packages can be found in [the Omnibus GitLab documentation](https://docs.gitlab.com/omnibus/update/README.html#version-specific-changes). @@ -82,87 +72,9 @@ Instructions are available for downloading an Omnibus GitLab Linux package local NOTE: **Note:** A step-by-step guide to [upgrading the Omnibus-bundled PostgreSQL is documented separately](https://docs.gitlab.com/omnibus/settings/database.html#upgrade-packaged-postgresql-server). -### Upgrading major versions - -Upgrading the *major* version requires more attention. -Backward-incompatible changes and migrations are reserved for major versions. -We cannot guarantee that upgrading between major versions will be seamless. -We suggest upgrading to the latest available *minor* version within -your major version before proceeding to the next major version. -Doing this will address any backward-incompatible changes or deprecations -to help ensure a successful upgrade to the next major release. - -It's also important to ensure that any background migrations have been fully completed -before upgrading to a new major version. To see the current size of the `background_migration` queue, -[Check for background migrations before upgrading](../update/README.md#checking-for-background-migrations-before-upgrading). - -If your GitLab instance has any runners associated with it, it is very -important to upgrade GitLab Runner to match the GitLab minor version that was -upgraded to. This is to ensure [compatibility with GitLab versions](https://docs.gitlab.com/runner/#compatibility-with-gitlab-versions). - -### Version 12 onward: Extra step for major upgrades - -From version 12 onward, an additional step is required. More significant migrations -may occur during major release upgrades. - -NOTE: **Note:** -If you are planning to upgrade from `12.0.x` to `12.10.x`, it is necessary to perform an intermediary upgrade to `12.1.x` -before upgrading to `12.10.x` to avoid [#215141](https://gitlab.com/gitlab-org/gitlab/-/issues/215141). - -To ensure these are successful: - -1. Increment to the first minor version (`x.0.x`) during the major version jump. -1. Proceed with upgrading to a newer release. - -**For example: `11.5.x` -> `11.11.x` -> `12.0.x` -> `12.1.x` -> `12.10.x` -> `13.0.x`** - -### Example upgrade paths - -Please see the table below for some examples: +## Upgrading major versions -| Target version | Your version | Recommended upgrade path | Note | -| --------------------- | ------------ | ------------------------ | ---- | -| `13.4.3` | `12.9.2` | `12.9.2` -> `12.10.14` -> `13.0.14` -> `13.4.3` | Two intermediate versions are required: the final `12.10` release, plus `13.0`. | -| `13.2.10` | `11.5.0` | `11.5.0` -> `11.11.8` -> `12.0.12` -> `12.1.17` -> `12.10.14` -> `13.0.14` -> `13.2.10` | Five intermediate versions are required: the final `11.11`, `12.0`, `12.1` and `12.10` releases, plus `13.0`. | -| `12.10.14` | `11.3.4` | `11.3.4` -> `11.11.8` -> `12.0.12` -> `12.1.17` -> `12.10.14` | Three intermediate versions are required: the final `11.11` and `12.0` releases, plus `12.1` | -| `12.9.5` | `10.4.5` | `10.4.5` -> `10.8.7` -> `11.11.8` -> `12.0.12` -> `12.1.17` -> `12.9.5` | Four intermediate versions are required: `10.8`, `11.11`, `12.0` and `12.1`, then `12.9.5` | -| `12.2.5` | `9.2.6` | `9.2.6` -> `9.5.10` -> `10.8.7` -> `11.11.8` -> `12.0.12` -> `12.1.17` -> `12.2.5` | Five intermediate versions are required: `9.5`, `10.8`, `11.11`, `12.0`, `12.1`, then `12.2`. | -| `11.3.4` | `8.13.4` | `8.13.4` -> `8.17.7` -> `9.5.10` -> `10.8.7` -> `11.3.4` | `8.17.7` is the last version in version 8, `9.5.10` is the last version in version 9, `10.8.7` is the last version in version 10. | - -### Upgrades from versions earlier than 8.12 - -- `8.11.x` and earlier: you might have to upgrade to `8.12.0` specifically before you can upgrade to `8.17.7`. This was [reported in an issue](https://gitlab.com/gitlab-org/gitlab/-/issues/207259). -- [CI changes prior to version 8.0](https://docs.gitlab.com/omnibus/update/README.html#updating-gitlab-ci-from-prior-540-to-version-714-via-omnibus-gitlab) - when it was merged into GitLab. - -### Multi-step upgrade paths with GitLab all-in-one Linux package repository - -Linux package managers default to installing the latest available version of a package for installation and upgrades. -Upgrading directly to the latest major version can be problematic for older GitLab versions that require a multi-stage upgrade path. - -When following an upgrade path spanning multiple versions, for each upgrade, specify the intended GitLab version number in your package manager's install or upgrade command. - -Examples: - -```shell -# apt-get (Ubuntu/Debian) -sudo apt-get upgrade gitlab-ee=12.0.12-ee.0 -# yum (RHEL/CentOS 6 and 7) -yum install gitlab-ee-12.0.12-ee.0.el7 -# dnf (RHEL/CentOS 8) -dnf install gitlab-ee-12.0.12-ee.0.el8 -# zypper (SUSE) -zypper install gitlab-ee=12.0.12-ee.0 -``` - -To identify the GitLab version number in your package manager, run the following commands: - -```shell -# apt-cache (Ubuntu/Debian) -sudo apt-cache madison gitlab-ee -# yum (RHEL/CentOS 6 and 7) -yum --showduplicates list gitlab-ee -``` +Backward-incompatible changes and migrations are reserved for major versions. See the [upgrade guide](../update/README.md#upgrading-to-a-new-major-version). ## Patch releases @@ -237,19 +149,6 @@ This decision is made on a case-by-case basis. ## More information -Check [our release posts](https://about.gitlab.com/releases/categories/releases/). - -Each month, we publish either a major or minor release of GitLab. At the end -of those release posts, there are three sections to look for: Deprecations, Removals, and Important notes on upgrading. These will include: - -- Steps you need to perform as part of an upgrade. - For example [8.12](https://about.gitlab.com/releases/2016/09/22/gitlab-8-12-released/#upgrade-barometer) - required the Elasticsearch index to be recreated. Any older version of GitLab upgrading to 8.12 or higher would require this. -- Changes to the versions of software we support such as - [ceasing support for IE11 in GitLab 13](https://about.gitlab.com/releases/2020/03/22/gitlab-12-9-released/#ending-support-for-internet-explorer-11). - -You should check all the major and minor versions you're passing over. - More information about the release procedures can be found in our [release documentation](https://gitlab.com/gitlab-org/release/docs). You may also want to read our [Responsible Disclosure Policy](https://about.gitlab.com/security/disclosure/). diff --git a/doc/update/README.md b/doc/update/README.md index 58b948d6a1a..d09c5f45446 100644 --- a/doc/update/README.md +++ b/doc/update/README.md @@ -1,34 +1,51 @@ --- -stage: none -group: unassigned +stage: Enablement +group: Distribution info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers --- -# Updating GitLab +# Upgrading GitLab -Depending on the installation method and your GitLab version, there are multiple -update guides. +Upgrading GitLab is a relatively straightforward process, but the complexity +can increase based on the installation method you have used, how old your +GitLab version is, if you're upgrading to a major version, and so on. + +Make sure to read the whole page as it contains information related to every upgrade method. + +The [maintenance policy documentation](../policy/maintenance.md) +has additional information about upgrading, including: -There are currently 3 official ways to install GitLab: +- How to interpret GitLab product versioning. +- Recommendations on the what release to run. +- How we use patch and security patch releases. +- When we backport code changes. + +## Upgrade based on installation method + +Depending on the installation method and your GitLab version, there are multiple +official ways to update GitLab: -- [Omnibus packages](#omnibus-packages) -- [Source installation](#installation-from-source) -- [Docker installation](#installation-using-docker) +- [Linux packages (Omnibus GitLab)](#linux-packages-omnibus-gitlab) +- [Source installations](#installation-from-source) +- [Docker installations](#installation-using-docker) +- [Kubernetes (Helm) installations](#installation-using-helm) -Based on your installation, choose a section below that fits your needs. +### Linux packages (Omnibus GitLab) -## Omnibus Packages +The [Omnibus update guide](https://docs.gitlab.com/omnibus/update/) +contains the steps needed to update a package installed by GitLab's official +repositories. -- The [Omnibus update guide](https://docs.gitlab.com/omnibus/update/README.html) - contains the steps needed to update an Omnibus GitLab package. +There are also instructions when you want to +[update to a specific version](https://docs.gitlab.com/omnibus/update/#multi-step-upgrade-using-the-official-repositories). -## Installation from source +### Installation from source - [Upgrading Community Edition and Enterprise Edition from source](upgrading_from_source.md) - The guidelines for upgrading Community Edition and Enterprise Edition from source. - [Patch versions](patch_versions.md) guide includes the steps needed for a - patch version, such as 6.2.0 to 6.2.1, and apply to both Community and Enterprise + patch version, such as 13.2.0 to 13.2.1, and apply to both Community and Enterprise Editions. In the past we used separate documents for the upgrading instructions, but we @@ -38,82 +55,20 @@ can still be found in the Git repository: - [Old upgrading guidelines for Community Edition](https://gitlab.com/gitlab-org/gitlab-foss/tree/11-8-stable/doc/update) - [Old upgrading guidelines for Enterprise Edition](https://gitlab.com/gitlab-org/gitlab/tree/11-8-stable-ee/doc/update) -## Installation using Docker +### Installation using Docker GitLab provides official Docker images for both Community and Enterprise editions. They are based on the Omnibus package and instructions on how to update them are in [a separate document](https://docs.gitlab.com/omnibus/docker/README.html). -## Upgrading without downtime - -Starting with GitLab 9.1.0 it's possible to upgrade to a newer major, minor, or -patch version of GitLab without having to take your GitLab instance offline. -However, for this to work there are the following requirements: - -- You can only upgrade 1 minor release at a time. So from 9.1 to 9.2, not to - 9.3. -- You have to use [post-deployment - migrations](../development/post_deployment_migrations.md) (included in - zero downtime update steps below). -- You are using PostgreSQL. Starting from GitLab 12.1, MySQL is not supported. -- Multi-node GitLab instance. Single-node instances may experience brief interruptions - [as services restart (Puma in particular)](https://docs.gitlab.com/omnibus/update/README.html#single-node-deployment). - -Most of the time you can safely upgrade from a patch release to the next minor -release if the patch release is not the latest. For example, upgrading from -9.1.1 to 9.2.0 should be safe even if 9.1.2 has been released. We do recommend -you check the release posts of any releases between your current and target -version just in case they include any migrations that may require you to upgrade -1 release at a time. +### Installation using Helm -Some releases may also include so called "background migrations". These -migrations are performed in the background by Sidekiq and are often used for -migrating data. Background migrations are only added in the monthly releases. +GitLab can be deployed into a Kubernetes cluster using Helm. +Instructions on how to update a cloud-native deployment are in +[a separate document](https://docs.gitlab.com/charts/installation/upgrade.html). -Certain major/minor releases may require a set of background migrations to be -finished. To guarantee this such a release will process any remaining jobs -before continuing the upgrading procedure. While this won't require downtime -(if the above conditions are met) we recommend users to keep at least 1 week -between upgrading major/minor releases, allowing the background migrations to -finish. The time necessary to complete these migrations can be reduced by -increasing the number of Sidekiq workers that can process jobs in the -`background_migration` queue. To see the size of this queue, -[Check for background migrations before upgrading](#checking-for-background-migrations-before-upgrading). - -As a rule of thumb, any database smaller than 10 GB won't take too much time to -upgrade; perhaps an hour at most per minor release. Larger databases however may -require more time, but this is highly dependent on the size of the database and -the migrations that are being performed. - -### Examples - -To help explain this, let's look at some examples. - -**Example 1:** You are running a large GitLab installation using version 9.4.2, -which is the latest patch release of 9.4. When GitLab 9.5.0 is released this -installation can be safely upgraded to 9.5.0 without requiring downtime if the -requirements mentioned above are met. You can also skip 9.5.0 and upgrade to -9.5.1 once it's released, but you **can not** upgrade straight to 9.6.0; you -_have_ to first upgrade to a 9.5.x release. - -**Example 2:** You are running a large GitLab installation using version 9.4.2, -which is the latest patch release of 9.4. GitLab 9.5 includes some background -migrations, and 10.0 will require these to be completed (processing any -remaining jobs for you). Skipping 9.5 is not possible without downtime, and due -to the background migrations would require potentially hours of downtime -depending on how long it takes for the background migrations to complete. To -work around this you will have to upgrade to 9.5.x first, then wait at least a -week before upgrading to 10.0. - -**Example 3:** You use MySQL as the database for GitLab. Any upgrade to a new -major/minor release will require downtime. If a release includes any background -migrations this could potentially lead to hours of downtime, depending on the -size of your database. To work around this you will have to use PostgreSQL and -meet the other online upgrade requirements mentioned above. - -### Steps - -Steps to [upgrade without downtime](https://docs.gitlab.com/omnibus/update/README.html#zero-downtime-updates). +Use the [version mapping](https://docs.gitlab.com/charts/installation/version_mappings.html) +from the chart version to GitLab version to determine the [upgrade path](#upgrade-paths). ## Checking for background migrations before upgrading @@ -136,8 +91,6 @@ puts Sidekiq::Queue.new("background_migration").size Sidekiq::ScheduledSet.new.select { |r| r.klass == 'BackgroundMigrationWorker' }.size ``` ---- - **For installations from source** If using GitLab 12.9 and newer, run: @@ -159,7 +112,6 @@ Sidekiq::ScheduledSet.new.select { |r| r.klass == 'BackgroundMigrationWorker' }. CAUTION: **Warning:** The following operations can disrupt your GitLab performance. -NOTE: **Note:** It is safe to re-execute these commands, especially if you have 1000+ pending jobs which would likely overflow your runtime memory. **For Omnibus installations** @@ -186,16 +138,123 @@ pending_job_classes = scheduled_queue.select { |job| job["class"] == "Background pending_job_classes.each { |job_class| Gitlab::BackgroundMigration.steal(job_class) } ``` +## Upgrade paths + +Although you can generally upgrade through multiple GitLab versions in one go, +sometimes this can cause issues. + +Find where your version sits in the upgrade path below, and upgrade GitLab +accordingly, while also consulting the +[version-specific upgrade instructions](#version-specific-upgrading-instructions): + +`8.11.x` -> `8.12.0` -> `8.17.7` -> `9.5.10` -> `10.8.7` -> `11.11.8` -> `12.0.12` -> `12.1.17` -> `12.10.14` -> `13.0.14` -> `13.1.11` - > `13.5.3` + +The following table, while not exhaustive, shows some examples of the supported +upgrade paths. + +| Target version | Your version | Supported upgrade path | Note | +| --------------------- | ------------ | ------------------------ | ---- | +| `13.4.3` | `12.9.2` | `12.9.2` -> `12.10.14` -> `13.0.14` -> `13.4.3` | Two intermediate versions are required: the final `12.10` release, plus `13.0`. | +| `13.2.10` | `11.5.0` | `11.5.0` -> `11.11.8` -> `12.0.12` -> `12.1.17` -> `12.10.14` -> `13.0.14` -> `13.2.10` | Five intermediate versions are required: the final `11.11`, `12.0`, `12.1` and `12.10` releases, plus `13.0`. | +| `12.10.14` | `11.3.4` | `11.3.4` -> `11.11.8` -> `12.0.12` -> `12.1.17` -> `12.10.14` | Three intermediate versions are required: the final `11.11` and `12.0` releases, plus `12.1` | +| `12.9.5` | `10.4.5` | `10.4.5` -> `10.8.7` -> `11.11.8` -> `12.0.12` -> `12.1.17` -> `12.9.5` | Four intermediate versions are required: `10.8`, `11.11`, `12.0` and `12.1`, then `12.9.5` | +| `12.2.5` | `9.2.6` | `9.2.6` -> `9.5.10` -> `10.8.7` -> `11.11.8` -> `12.0.12` -> `12.1.17` -> `12.2.5` | Five intermediate versions are required: `9.5`, `10.8`, `11.11`, `12.0`, `12.1`, then `12.2`. | +| `11.3.4` | `8.13.4` | `8.13.4` -> `8.17.7` -> `9.5.10` -> `10.8.7` -> `11.3.4` | `8.17.7` is the last version in version 8, `9.5.10` is the last version in version 9, `10.8.7` is the last version in version 10. | + ## Upgrading to a new major version -Major versions are reserved for backwards incompatible changes. We recommend that -you first upgrade to the latest available minor version within your major version. -Please follow the [Upgrade Recommendations](../policy/maintenance.md#upgrade-recommendations) -to identify a supported upgrade path. +Upgrading the *major* version requires more attention. +Backward-incompatible changes and migrations are reserved for major versions. +We cannot guarantee that upgrading between major versions will be seamless. +It is suggested to upgrade to the latest available *minor* version within +your major version before proceeding to the next major version. +Doing this will address any backward-incompatible changes or deprecations +to help ensure a successful upgrade to the next major release. +Identify a [supported upgrade path](#upgrade-paths). + +More significant migrations may occur during major release upgrades. To ensure these are successful: -Before upgrading to a new major version, you should ensure that any background -migration jobs from previous releases have been completed. To see the current size -of the `background_migration` queue, [check for background migrations before upgrading](#checking-for-background-migrations-before-upgrading). +1. Increment to the first minor version (`x.0.x`) during the major version jump. +1. Proceed with upgrading to a newer release. + +It's also important to ensure that any background migrations have been fully completed +before upgrading to a new major version. To see the current size of the `background_migration` queue, +[Check for background migrations before upgrading](#checking-for-background-migrations-before-upgrading). + +If your GitLab instance has any runners associated with it, it is very +important to upgrade GitLab Runner to match the GitLab minor version that was +upgraded to. This is to ensure [compatibility with GitLab versions](https://docs.gitlab.com/runner/#compatibility-with-gitlab-versions). + +## Upgrading without downtime + +Starting with GitLab 9.1.0 it's possible to upgrade to a newer major, minor, or +patch version of GitLab without having to take your GitLab instance offline. +However, for this to work there are the following requirements: + +- You can only upgrade 1 minor release at a time. So from 9.1 to 9.2, not to + 9.3. +- You have to use [post-deployment + migrations](../development/post_deployment_migrations.md) (included in + zero downtime update steps below). +- You are using PostgreSQL. Starting from GitLab 12.1, MySQL is not supported. +- Multi-node GitLab instance. Single-node instances may experience brief interruptions + [as services restart (Puma in particular)](https://docs.gitlab.com/omnibus/update/README.html#single-node-deployment). + +Most of the time you can safely upgrade from a patch release to the next minor +release if the patch release is not the latest. For example, upgrading from +9.1.1 to 9.2.0 should be safe even if 9.1.2 has been released. We do recommend +you check the release posts of any releases between your current and target +version just in case they include any migrations that may require you to upgrade +1 release at a time. + +Some releases may also include so called "background migrations". These +migrations are performed in the background by Sidekiq and are often used for +migrating data. Background migrations are only added in the monthly releases. + +Certain major/minor releases may require a set of background migrations to be +finished. To guarantee this such a release will process any remaining jobs +before continuing the upgrading procedure. While this won't require downtime +(if the above conditions are met) we recommend users to keep at least 1 week +between upgrading major/minor releases, allowing the background migrations to +finish. The time necessary to complete these migrations can be reduced by +increasing the number of Sidekiq workers that can process jobs in the +`background_migration` queue. To see the size of this queue, +[Check for background migrations before upgrading](#checking-for-background-migrations-before-upgrading). + +As a rule of thumb, any database smaller than 10 GB won't take too much time to +upgrade; perhaps an hour at most per minor release. Larger databases however may +require more time, but this is highly dependent on the size of the database and +the migrations that are being performed. + +### Examples + +To help explain this, let's look at some examples. + +**Example 1:** You are running a large GitLab installation using version 9.4.2, +which is the latest patch release of 9.4. When GitLab 9.5.0 is released this +installation can be safely upgraded to 9.5.0 without requiring downtime if the +requirements mentioned above are met. You can also skip 9.5.0 and upgrade to +9.5.1 after it's released, but you **can not** upgrade straight to 9.6.0; you +_have_ to first upgrade to a 9.5.x release. + +**Example 2:** You are running a large GitLab installation using version 9.4.2, +which is the latest patch release of 9.4. GitLab 9.5 includes some background +migrations, and 10.0 will require these to be completed (processing any +remaining jobs for you). Skipping 9.5 is not possible without downtime, and due +to the background migrations would require potentially hours of downtime +depending on how long it takes for the background migrations to complete. To +work around this you will have to upgrade to 9.5.x first, then wait at least a +week before upgrading to 10.0. + +**Example 3:** You use MySQL as the database for GitLab. Any upgrade to a new +major/minor release will require downtime. If a release includes any background +migrations this could potentially lead to hours of downtime, depending on the +size of your database. To work around this you will have to use PostgreSQL and +meet the other online upgrade requirements mentioned above. + +### Steps + +Steps to [upgrade without downtime](https://docs.gitlab.com/omnibus/update/README.html#zero-downtime-updates). ## Upgrading between editions @@ -203,7 +262,7 @@ GitLab comes in two flavors: [Community Edition](https://about.gitlab.com/featur and [Enterprise Edition](https://about.gitlab.com/features/#enterprise) which builds on top of the Community Edition and includes extra features mainly aimed at organizations with more than 100 users. -Below you can find some guides to help you change editions easily. +Below you can find some guides to help you change GitLab editions. ### Community to Enterprise Edition @@ -226,7 +285,30 @@ If you need to downgrade your Enterprise Edition installation back to Community Edition, you can follow [this guide](../downgrade_ee_to_ce/README.md) to make the process as smooth as possible. -## Version specific upgrading instructions +## Version-specific upgrading instructions + +Each month, a major or minor release of GitLab is published along with a +[release post](https://about.gitlab.com/releases/categories/releases/). +You should check all the major and minor versions you're passing over. +At the end of those release posts, there are three sections to look for: + +- Deprecations +- Removals +- Important notes on upgrading + +These will include: + +- Steps you need to perform as part of an upgrade. + For example [8.12](https://about.gitlab.com/releases/2016/09/22/gitlab-8-12-released/#upgrade-barometer) + required the Elasticsearch index to be recreated. Any older version of GitLab upgrading to 8.12 or higher would require this. +- Changes to the versions of software we support such as + [ceasing support for IE11 in GitLab 13](https://about.gitlab.com/releases/2020/03/22/gitlab-12-9-released/#ending-support-for-internet-explorer-11). + +Apart from the instructions in this section, you should also check the +installation-specific upgrade instructions, based on how you installed GitLab: + +- [Linux packages (Omnibus GitLab)](https://docs.gitlab.com/omnibus/update/README.html#version-specific-changes) +- [Helm charts](https://docs.gitlab.com/charts/installation/upgrade.html) ### 13.6.0 @@ -293,10 +375,16 @@ automatically upgraded. However, session cookie downgrades are not supported. So after upgrading to 12.2.0, any downgrades would result to all sessions being invalidated and users are logged out. +### 12.1.0 + +If you are planning to upgrade from `12.0.x` to `12.10.x`, it is necessary to +perform an intermediary upgrade to `12.1.x` before upgrading to `12.10.x` to +avoid issues like [#215141](https://gitlab.com/gitlab-org/gitlab/-/issues/215141). + ### 12.0.0 In 12.0.0 we made various database related changes. These changes require that -users first upgrade to the latest 11.11 patch release. Once upgraded to 11.11.x, +users first upgrade to the latest 11.11 patch release. After upgraded to 11.11.x, users can upgrade to 12.0.x. Failure to do so may result in database migrations not being applied, which could lead to application errors. @@ -308,11 +396,17 @@ release for 11.11.x. You can upgrade as usual to 12.0.x. Example 2: you are currently using a version of GitLab 10.x. To upgrade, first upgrade to the last 10.x release (10.8.7) then the last 11.x release (11.11.8). -Once upgraded to 11.11.8 you can safely upgrade to 12.0.x. +After upgraded to 11.11.8 you can safely upgrade to 12.0.x. See our [documentation on upgrade paths](../policy/maintenance.md#upgrade-recommendations) for more information. +### Upgrades from versions earlier than 8.12 + +- `8.11.x` and earlier: you might have to upgrade to `8.12.0` specifically before you can upgrade to `8.17.7`. This was [reported in an issue](https://gitlab.com/gitlab-org/gitlab/-/issues/207259). +- [CI changes prior to version 8.0](https://docs.gitlab.com/omnibus/update/README.html#updating-gitlab-ci-from-prior-540-to-version-714-via-omnibus-gitlab) + when it was merged into GitLab. + ## Miscellaneous - [MySQL to PostgreSQL](mysql_to_postgresql.md) guides you through migrating diff --git a/doc/user/admin_area/settings/account_and_limit_settings.md b/doc/user/admin_area/settings/account_and_limit_settings.md index 957f84206e9..5f90bd87a0c 100644 --- a/doc/user/admin_area/settings/account_and_limit_settings.md +++ b/doc/user/admin_area/settings/account_and_limit_settings.md @@ -18,6 +18,12 @@ If you choose a size larger than what is currently configured for the web server you will likely get errors. See the [troubleshooting section](#troubleshooting) for more details. +## Max push size + +You can change the maximum push size for your repository. +Navigate to **Admin Area (wrench icon) > Settings > General**, then expand **Account and Limit**. +From here, you can increase or decrease by changing the value in `Maximum push size (MB)`. + ## Max import size You can change the maximum file size for imports in GitLab. diff --git a/doc/user/application_security/img/vulnerability_page_download_patch_button_v13_1.png b/doc/user/application_security/img/vulnerability_page_download_patch_button_v13_1.png Binary files differdeleted file mode 100644 index b925c342a11..00000000000 --- a/doc/user/application_security/img/vulnerability_page_download_patch_button_v13_1.png +++ /dev/null diff --git a/doc/user/application_security/index.md b/doc/user/application_security/index.md index a1c94f4bd7d..6a8dc5d7e10 100644 --- a/doc/user/application_security/index.md +++ b/doc/user/application_security/index.md @@ -21,7 +21,7 @@ For an overview of application security with GitLab, see ## Quick start Get started quickly with Dependency Scanning, License Scanning, Static Application Security -Testing (SAST), and Secret Detection by adding the following to your `.gitlab-ci.yml`: +Testing (SAST), and Secret Detection by adding the following to your [`.gitlab-ci.yml`](../../ci/yaml/README.md): ```yaml include: @@ -70,12 +70,26 @@ GitLab uses the following tools to scan and report known vulnerabilities found i | [Dependency List](dependency_list/index.md) **(ULTIMATE)** | View your project's dependencies and their known vulnerabilities. | | [Dependency Scanning](dependency_scanning/index.md) **(ULTIMATE)** | Analyze your dependencies for known vulnerabilities. | | [Dynamic Application Security Testing (DAST)](dast/index.md) **(ULTIMATE)** | Analyze running web applications for known vulnerabilities. | -| [API fuzzing](api_fuzzing/index.md) **(ULTIMATE)** | Find unknown bugs and vulnerabilities in web APIs with fuzzing. | +| [API fuzzing](api_fuzzing/index.md) **(ULTIMATE)** | Find unknown bugs and vulnerabilities in web APIs with fuzzing. | | [Secret Detection](secret_detection/index.md) **(ULTIMATE)** | Analyze Git history for leaked secrets. | | [Security Dashboard](security_dashboard/index.md) **(ULTIMATE)** | View vulnerabilities in all your projects and groups. | | [Static Application Security Testing (SAST)](sast/index.md) | Analyze source code for known vulnerabilities. | | [Coverage fuzzing](coverage_fuzzing/index.md) **(ULTIMATE)** | Find unknown bugs and vulnerabilities with coverage-guided fuzzing. | +### Use security scanning tools with Pipelines for Merge Requests + +The security scanning tools can all be added to pipelines with [templates](https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/ci/templates/Security). +See each tool for details on how to use include each template in your CI/CD configuration. + +By default, the application security jobs are configured to run for branch pipelines only. +To use them with [pipelines for merge requests](../../ci/merge_request_pipelines/index.md), +you may need to override the default `rules:` configuration to add: + +```yaml +rules: + - if: $CI_PIPELINE_SOURCE == "merge_request_event" +``` + ## Security Scanning with Auto DevOps When [Auto DevOps](../../topics/autodevops/) is enabled, all GitLab Security scanning tools will be configured using default settings. @@ -144,21 +158,21 @@ To view details of DAST vulnerabilities: 1. Click on the vulnerability's description. The following details are provided: - | Field | Description | -|:-----------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| Description | Description of the vulnerability. | -| Project | Namespace and project in which the vulnerability was detected. | -| Method | HTTP method used to detect the vulnerability. | -| URL | URL at which the vulnerability was detected. | -| Request Headers | Headers of the request. | -| Response Status | Response status received from the application. | -| Response Headers | Headers of the response received from the application. | +| Field | Description | +|:-----------------|:------------------------------------------------------------------ | +| Description | Description of the vulnerability. | +| Project | Namespace and project in which the vulnerability was detected. | +| Method | HTTP method used to detect the vulnerability. | +| URL | URL at which the vulnerability was detected. | +| Request Headers | Headers of the request. | +| Response Status | Response status received from the application. | +| Response Headers | Headers of the response received from the application. | | Evidence | Evidence of the data found that verified the vulnerability. Often a snippet of the request or response, this can be used to help verify that the finding is a vulnerability. | -| Identifiers | Identifiers of the vulnerability. | -| Severity | Severity of the vulnerability. | -| Scanner Type | Type of vulnerability report. | -| Links | Links to further details of the detected vulnerability. | -| Solution | Details of a recommended solution to the vulnerability (optional). | +| Identifiers | Identifiers of the vulnerability. | +| Severity | Severity of the vulnerability. | +| Scanner Type | Type of vulnerability report. | +| Links | Links to further details of the detected vulnerability. | +| Solution | Details of a recommended solution to the vulnerability (optional). | #### Hide sensitive information in headers @@ -238,14 +252,11 @@ Selecting the button creates a merge request with the solution. #### Manually applying the suggested patch -1. To manually apply the patch that was generated by GitLab for a vulnerability, select the dropdown arrow on the **Resolve -with merge request** button, then select **Download patch to resolve**: - -![Resolve with Merge Request button dropdown](img/vulnerability_page_merge_request_button_dropdown_v13_1.png) +To manually apply the patch that GitLab generated for a vulnerability: -1. The button's text changes to **Download patch to resolve**. Click on it to download the patch: +1. Select the **Resolve with merge request** dropdown, then select **Download patch to resolve**: -![Download patch button](img/vulnerability_page_download_patch_button_v13_1.png) + ![Resolve with Merge Request button dropdown](img/vulnerability_page_merge_request_button_dropdown_v13_1.png) 1. Ensure your local project has the same commit checked out that was used to generate the patch. 1. Run `git apply remediation.patch`. diff --git a/doc/user/search/img/filtering_merge_requests_by_date_v13_6.png b/doc/user/search/img/filtering_merge_requests_by_date_v13_6.png Binary files differnew file mode 100644 index 00000000000..13ed7ccbb84 --- /dev/null +++ b/doc/user/search/img/filtering_merge_requests_by_date_v13_6.png diff --git a/doc/user/search/img/filtering_merge_requests_by_environment_v13_6.png b/doc/user/search/img/filtering_merge_requests_by_environment_v13_6.png Binary files differnew file mode 100644 index 00000000000..24553ce6730 --- /dev/null +++ b/doc/user/search/img/filtering_merge_requests_by_environment_v13_6.png diff --git a/doc/user/search/index.md b/doc/user/search/index.md index f4a306f825e..8eb3cc23d0b 100644 --- a/doc/user/search/index.md +++ b/doc/user/search/index.md @@ -117,6 +117,28 @@ the dropdown) **Approved-By** and select the user. ![Filter MRs by approved by](img/filter_approved_by_merge_requests_v13_0.png) +### Filtering merge requests by environment or deployment date **(CORE)** + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/44041) in GitLab 13.6. + +To filter merge requests by deployment data, such as the environment or a date, +you can type (or select from the dropdown) the following: + +- Environment +- Deployed-before +- Deployed-after + +When filtering by an environment, a dropdown presents all environments that +you can choose from: + +![Filter MRs by their environment](img/filtering_merge_requests_by_environment_v13_6.png) + +When filtering by a deploy date, you must enter the date manually. Deploy dates +use the format `YYYY-MM-DD`, and must be quoted if you wish to specify +both a date and time (`"YYYY-MM-DD HH:MM"`): + +![Filter MRs by a deploy date](img/filtering_merge_requests_by_date_v13_6.png) + ## Filters autocomplete GitLab provides many filters across many pages (issues, merge requests, epics, diff --git a/lib/gitlab/danger/helper.rb b/lib/gitlab/danger/helper.rb index 599a458d4a9..89f21e8bd23 100644 --- a/lib/gitlab/danger/helper.rb +++ b/lib/gitlab/danger/helper.rb @@ -190,7 +190,7 @@ module Gitlab %r{\A(ee/)?vendor/} => :backend, %r{\A(Gemfile|Gemfile.lock|Rakefile)\z} => :backend, %r{\A[A-Z_]+_VERSION\z} => :backend, - %r{\A\.rubocop(_todo)?\.yml\z} => :backend, + %r{\A\.rubocop((_manual)?_todo)?\.yml\z} => :backend, %r{\Afile_hooks/} => :backend, %r{\A(ee/)?qa/} => :qa, diff --git a/locale/gitlab.pot b/locale/gitlab.pot index aaf96e5e9b5..4acaff30542 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -8319,6 +8319,9 @@ msgstr "" msgid "DastProfiles|Authentication URL" msgstr "" +msgid "DastProfiles|Copy HTTP header to clipboard" +msgstr "" + msgid "DastProfiles|Could not create site validation token. Please refresh the page, or try again later." msgstr "" @@ -8385,6 +8388,9 @@ msgstr "" msgid "DastProfiles|Error Details" msgstr "" +msgid "DastProfiles|Header validation" +msgstr "" + msgid "DastProfiles|Hide debug messages" msgstr "" @@ -8469,9 +8475,15 @@ msgstr "" msgid "DastProfiles|Step 1 - Choose site validation method" msgstr "" +msgid "DastProfiles|Step 2 - Add following HTTP header to your site" +msgstr "" + msgid "DastProfiles|Step 2 - Add following text to the target site" msgstr "" +msgid "DastProfiles|Step 3 - Confirm header location and validate" +msgstr "" + msgid "DastProfiles|Step 3 - Confirm text file location and validate" msgstr "" @@ -8508,7 +8520,7 @@ msgstr "" msgid "DastProfiles|Validating..." msgstr "" -msgid "DastProfiles|Validation failed, please make sure that you follow the steps above with the choosen method." +msgid "DastProfiles|Validation failed, please make sure that you follow the steps above with the chosen method." msgstr "" msgid "DastProfiles|Validation failed. Please try again." @@ -14507,7 +14519,7 @@ msgstr "" msgid "Integrations|Issues created in Jira are shown here once you have created the issues in project setup in Jira." msgstr "" -msgid "Integrations|Projects using custom settings will not be impacted unless the project owner chooses to use instance-level defaults." +msgid "Integrations|Projects using custom settings will not be impacted unless the project owner chooses to use parent level defaults." msgstr "" msgid "Integrations|Return to GitLab for Jira" @@ -14732,6 +14744,9 @@ msgstr "" msgid "InviteMembersModal|Choose a role permission" msgstr "" +msgid "InviteMembersModal|Close invite team members" +msgstr "" + msgid "InviteMembersModal|GitLab member or Email address" msgstr "" @@ -14741,13 +14756,13 @@ msgstr "" msgid "InviteMembersModal|Invite team members" msgstr "" -msgid "InviteMembersModal|Search for members to invite" +msgid "InviteMembersModal|Members were successfully added" msgstr "" -msgid "InviteMembersModal|User not invited. Feature coming soon!" +msgid "InviteMembersModal|Search for members to invite" msgstr "" -msgid "InviteMembersModal|Users were succesfully added" +msgid "InviteMembersModal|Some of the members could not be added" msgstr "" msgid "InviteMembersModal|You're inviting members to the %{group_name} group" diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/run_pipeline_via_web_only_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/run_pipeline_via_web_only_spec.rb index 153ccafaa20..b79bda108af 100644 --- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/run_pipeline_via_web_only_spec.rb +++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/run_pipeline_via_web_only_spec.rb @@ -2,11 +2,8 @@ module QA RSpec.describe 'Verify' do - describe 'Run pipeline', :requires_admin, :skip_live_env do - # [TODO]: Developer to remove :requires_admin and :skip_live_env once FF is removed in https://gitlab.com/gitlab-org/gitlab/-/issues/229632 - + describe 'Run pipeline', only: { subdomain: :staging } do context 'with web only rule' do - let(:feature_flag) { :new_pipeline_form } let(:job_name) { 'test_job' } let(:project) do Resource::Project.fabricate_via_api! do |project| @@ -20,33 +17,29 @@ module QA commit.commit_message = 'Add .gitlab-ci.yml' commit.add_files( [ - { - file_path: '.gitlab-ci.yml', - content: <<~YAML - #{job_name}: - tags: - - #{project.name} - script: echo 'OK' - only: - - web - YAML - } + { + file_path: '.gitlab-ci.yml', + content: <<~YAML + #{job_name}: + tags: + - #{project.name} + script: echo 'OK' + only: + - web + + YAML + } ] ) end end before do - Runtime::Feature.enable(feature_flag) # [TODO]: Developer to remove when feature flag is removed Flow::Login.sign_in project.visit! Page::Project::Menu.perform(&:click_ci_cd_pipelines) end - after do - Runtime::Feature.disable(feature_flag) # [TODO]: Developer to remove when feature flag is removed - end - it 'can trigger pipeline', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/946' do Page::Project::Pipeline::Index.perform do |index| expect(index).not_to have_pipeline # should not auto trigger pipeline diff --git a/rubocop/cop/code_reuse/active_record.rb b/rubocop/cop/code_reuse/active_record.rb deleted file mode 100644 index f6b5d66647d..00000000000 --- a/rubocop/cop/code_reuse/active_record.rb +++ /dev/null @@ -1,168 +0,0 @@ -# frozen_string_literal: true - -require_relative '../../code_reuse_helpers' - -module RuboCop - module Cop - module CodeReuse - # Cop that denies the use of ActiveRecord methods outside of models. - class ActiveRecord < RuboCop::Cop::Cop - include CodeReuseHelpers - - MSG = 'This method can only be used inside an ActiveRecord model: ' \ - 'https://gitlab.com/gitlab-org/gitlab-foss/issues/49653' - - # Various methods from ActiveRecord::Querying that are denied. We - # exclude some generic ones such as `any?` and `first`, as these may - # lead to too many false positives, since `Array` also supports these - # methods. - # - # The keys of this Hash are the denied method names. The values are - # booleans that indicate if the method should only be denied if any - # arguments are provided. - NOT_ALLOWED = { - average: true, - calculate: true, - count_by_sql: true, - create_with: true, - distinct: false, - eager_load: true, - exists?: true, - find_by: true, - find_by!: true, - find_by_sql: true, - find_each: true, - find_in_batches: true, - find_or_create_by: true, - find_or_create_by!: true, - find_or_initialize_by: true, - first!: false, - first_or_create: true, - first_or_create!: true, - first_or_initialize: true, - from: true, - group: true, - having: true, - ids: false, - includes: true, - joins: true, - limit: true, - lock: false, - many?: false, - offset: true, - order: true, - pluck: true, - preload: true, - readonly: false, - references: true, - reorder: true, - rewhere: true, - take: false, - take!: false, - unscope: false, - where: false, - with: true - }.freeze - - # Directories that allow the use of the denied methods. These - # directories are checked relative to both . and ee/ - ALLOWED_DIRECTORIES = %w[ - app/models - config - danger - db - lib/backup - lib/banzai - lib/gitlab/background_migration - lib/gitlab/cycle_analytics - lib/gitlab/database - lib/gitlab/import_export - lib/gitlab/project_authorizations - lib/gitlab/sql - lib/system_check - lib/tasks - qa - rubocop - spec - ].freeze - - def on_send(node) - return if in_allowed_directory?(node) - - receiver = node.children[0] - send_name = node.children[1] - first_arg = node.children[2] - - if receiver && NOT_ALLOWED.key?(send_name) - # If the rule requires an argument to be given, but none are - # provided, we won't register an offense. This prevents us from - # adding offenses for `project.group`, while still covering - # `Project.group(:name)`. - return if NOT_ALLOWED[send_name] && !first_arg - - add_offense(node, location: :selector) - end - end - - # Returns true if the node resides in one of the allowed - # directories. - def in_allowed_directory?(node) - path = file_path_for_node(node) - - ALLOWED_DIRECTORIES.any? do |directory| - path.start_with?( - File.join(rails_root, directory), - File.join(rails_root, 'ee', directory) - ) - end - end - - # We can not auto correct code like this, as it requires manual - # refactoring. Instead, we'll just allow the surrounding scope. - # - # Despite this method's presence, you should not use it. This method - # exists to make it possible to allow large chunks of offenses we - # can't fix in the short term. If you are writing new code, follow the - # code reuse guidelines, instead of allowing any new offenses. - def autocorrect(node) - scope = surrounding_scope_of(node) - indent = indentation_of(scope) - - lambda do |corrector| - # This prevents us from inserting the same enable/disable comment - # for a method or block that has multiple offenses. - next if allowed_scopes.include?(scope) - - corrector.insert_before( - scope.source_range, - "# rubocop: disable #{cop_name}\n#{indent}" - ) - - corrector.insert_after( - scope.source_range, - "\n#{indent}# rubocop: enable #{cop_name}" - ) - - allowed_scopes << scope - end - end - - def indentation_of(node) - ' ' * node.loc.expression.source_line[/\A */].length - end - - def surrounding_scope_of(node) - %i[def defs block begin].each do |type| - if (found = node.each_ancestor(type).first) - return found - end - end - end - - def allowed_scopes - @allowed_scopes ||= Set.new - end - end - end - end -end diff --git a/rubocop/qa_helpers.rb b/rubocop/qa_helpers.rb index 95875d64727..f4adf7f4e9f 100644 --- a/rubocop/qa_helpers.rb +++ b/rubocop/qa_helpers.rb @@ -5,7 +5,7 @@ module RuboCop def in_qa_file?(node) path = node.location.expression.source_buffer.name - path.start_with?(File.join(RuboCop::PathUtil.pwd, 'qa')) + path.start_with?(File.join(Dir.pwd, 'qa')) end end end diff --git a/rubocop/rubocop-code_reuse.yml b/rubocop/rubocop-code_reuse.yml new file mode 100644 index 00000000000..64e51c859f4 --- /dev/null +++ b/rubocop/rubocop-code_reuse.yml @@ -0,0 +1,41 @@ +# Denies the use of ActiveRecord methods outside of configured +# excluded directories +# Directories that allow the use of the denied methods. +# To start we provide a default configuration that matches +# a standard Rails app and enable. +# The default configuration can be overridden by +# providing your own Exclusion list as follows: +# CodeReuse/ActiveRecord: +# Enabled: true +# Exclude: +# - app/models/**/*.rb +# - config/**/*.rb +# - db/**/*.rb +# - lib/tasks/**/*.rb +# - spec/**/*.rb +# - lib/gitlab/**/*.rb +CodeReuse/ActiveRecord: + Exclude: + - app/models/**/*.rb + - config/**/*.rb + - db/**/*.rb + - lib/tasks/**/*.rake + - spec/**/*.rb + - danger/**/*.rb + - lib/backup/**/*.rb + - lib/banzai/**/*.rb + - lib/gitlab/background_migration/**/*.rb + - lib/gitlab/cycle_analytics/**/*.rb + - lib/gitlab/database/**/*.rb + - lib/gitlab/database_importers/common_metrics/importer.rb + - lib/gitlab/import_export/**/*.rb + - lib/gitlab/project_authorizations.rb + - lib/gitlab/sql/**/*.rb + - lib/system_check/**/*.rb + - qa/**/*.rb + - rubocop/**/*.rb + - ee/app/models/**/*.rb + - ee/spec/**/*.rb + - ee/db/fixtures/**/*.rb + - ee/lib/tasks/**/*.rake + - ee/lib/ee/gitlab/background_migration/**/*.rb diff --git a/spec/features/users/show_spec.rb b/spec/features/users/show_spec.rb index 466b7361da9..aebe2cc602d 100644 --- a/spec/features/users/show_spec.rb +++ b/spec/features/users/show_spec.rb @@ -5,11 +5,13 @@ require 'spec_helper' RSpec.describe 'User page' do include ExternalAuthorizationServiceHelpers - let(:user) { create(:user, bio: '**Lorem** _ipsum_ dolor sit [amet](https://example.com)') } + let_it_be(:user) { create(:user, bio: '**Lorem** _ipsum_ dolor sit [amet](https://example.com)') } + + subject { visit(user_path(user)) } context 'with public profile' do it 'shows all the tabs' do - visit(user_path(user)) + subject page.within '.nav-links' do expect(page).to have_link('Overview') @@ -22,14 +24,12 @@ RSpec.describe 'User page' do end it 'does not show private profile message' do - visit(user_path(user)) + subject expect(page).not_to have_content("This user has a private profile") end context 'work information' do - subject { visit(user_path(user)) } - it 'shows job title and organization details' do user.update(organization: 'GitLab - work info test', job_title: 'Frontend Engineer') @@ -57,24 +57,24 @@ RSpec.describe 'User page' do end context 'with private profile' do - let(:user) { create(:user, private_profile: true) } + let_it_be(:user) { create(:user, private_profile: true) } it 'shows no tab' do - visit(user_path(user)) + subject expect(page).to have_css("div.profile-header") expect(page).not_to have_css("ul.nav-links") end it 'shows private profile message' do - visit(user_path(user)) + subject expect(page).to have_content("This user has a private profile") end it 'shows own tabs' do sign_in(user) - visit(user_path(user)) + subject page.within '.nav-links' do expect(page).to have_link('Overview') @@ -88,36 +88,36 @@ RSpec.describe 'User page' do end context 'with blocked profile' do - let(:user) { create(:user, state: :blocked) } + let_it_be(:user) { create(:user, state: :blocked) } it 'shows no tab' do - visit(user_path(user)) + subject expect(page).to have_css("div.profile-header") expect(page).not_to have_css("ul.nav-links") end it 'shows blocked message' do - visit(user_path(user)) + subject expect(page).to have_content("This user is blocked") end it 'shows user name as blocked' do - visit(user_path(user)) + subject expect(page).to have_css(".cover-title", text: 'Blocked user') end it 'shows no additional fields' do - visit(user_path(user)) + subject expect(page).not_to have_css(".profile-user-bio") expect(page).not_to have_css(".profile-link-holder") end it 'shows username' do - visit(user_path(user)) + subject expect(page).to have_content("@#{user.username}") end @@ -126,7 +126,7 @@ RSpec.describe 'User page' do it 'shows the status if there was one' do create(:user_status, user: user, message: "Working hard!") - visit(user_path(user)) + subject expect(page).to have_content("Working hard!") end @@ -135,7 +135,7 @@ RSpec.describe 'User page' do it 'shows the sign in link' do stub_application_setting(signup_enabled: false) - visit(user_path(user)) + subject page.within '.navbar-nav' do expect(page).to have_link('Sign in') @@ -147,7 +147,7 @@ RSpec.describe 'User page' do it 'shows the sign in and register link' do stub_application_setting(signup_enabled: true) - visit(user_path(user)) + subject page.within '.navbar-nav' do expect(page).to have_link('Sign in / Register') @@ -157,7 +157,7 @@ RSpec.describe 'User page' do context 'most recent activity' do it 'shows the most recent activity' do - visit(user_path(user)) + subject expect(page).to have_content('Most Recent Activity') end @@ -168,7 +168,7 @@ RSpec.describe 'User page' do end it 'hides the most recent activity' do - visit(user_path(user)) + subject expect(page).not_to have_content('Most Recent Activity') end @@ -177,14 +177,14 @@ RSpec.describe 'User page' do context 'page description' do before do - visit(user_path(user)) + subject end it_behaves_like 'page meta description', 'Lorem ipsum dolor sit amet' end context 'with a bot user' do - let(:user) { create(:user, user_type: :security_bot) } + let_it_be(:user) { create(:user, user_type: :security_bot) } describe 'feature flag enabled' do before do @@ -192,7 +192,7 @@ RSpec.describe 'User page' do end it 'only shows Overview and Activity tabs' do - visit(user_path(user)) + subject page.within '.nav-links' do expect(page).to have_link('Overview') @@ -211,7 +211,7 @@ RSpec.describe 'User page' do end it 'only shows Overview and Activity tabs' do - visit(user_path(user)) + subject page.within '.nav-links' do expect(page).to have_link('Overview') @@ -224,4 +224,24 @@ RSpec.describe 'User page' do end end end + + context 'structured markup' do + let_it_be(:user) { create(:user, website_url: 'https://gitlab.com', organization: 'GitLab', job_title: 'Frontend Engineer', email: 'public@example.com', public_email: 'public@example.com', location: 'Country', created_at: Time.now, updated_at: Time.now) } + + it 'shows Person structured markup' do + subject + + aggregate_failures do + expect(page).to have_selector('[itemscope][itemtype="http://schema.org/Person"]') + expect(page).to have_selector('img[itemprop="image"]') + expect(page).to have_selector('[itemprop="name"]') + expect(page).to have_selector('[itemprop="address"][itemscope][itemtype="https://schema.org/PostalAddress"]') + expect(page).to have_selector('[itemprop="addressLocality"]') + expect(page).to have_selector('[itemprop="url"]') + expect(page).to have_selector('[itemprop="email"]') + expect(page).to have_selector('span[itemprop="jobTitle"]') + expect(page).to have_selector('span[itemprop="worksFor"]') + end + end + end end diff --git a/spec/frontend/alerts_settings/__snapshots__/alerts_settings_form_old_spec.js.snap b/spec/frontend/alerts_settings/__snapshots__/alerts_settings_form_old_spec.js.snap index 17188f73677..9306bf24baf 100644 --- a/spec/frontend/alerts_settings/__snapshots__/alerts_settings_form_old_spec.js.snap +++ b/spec/frontend/alerts_settings/__snapshots__/alerts_settings_form_old_spec.js.snap @@ -24,10 +24,10 @@ exports[`AlertsSettingsFormOld with default values renders the initial template </span> </gl-form-group-stub> - <gl-form-group-stub label=\\"Authorization key\\" label-for=\\"authorization-key\\"> + <gl-form-group-stub label-for=\\"authorization-key\\"> <gl-form-input-group-stub value=\\"\\" predefinedoptions=\\"[object Object]\\" id=\\"authorization-key\\" readonly=\\"\\" class=\\"gl-mb-2\\"></gl-form-input-group-stub> <gl-button-stub category=\\"primary\\" variant=\\"default\\" size=\\"medium\\" icon=\\"\\" buttontextclasses=\\"\\" disabled=\\"true\\" class=\\"gl-mt-3\\" role=\\"button\\" tabindex=\\"0\\">Reset key</gl-button-stub> - <gl-modal-stub modalid=\\"authKeyModal\\" titletag=\\"h4\\" modalclass=\\"\\" size=\\"md\\" title=\\"Reset key\\" ok-title=\\"Reset key\\" ok-variant=\\"danger\\"> + <gl-modal-stub modalid=\\"tokenModal\\" titletag=\\"h4\\" modalclass=\\"\\" size=\\"md\\" title=\\"Reset key\\" ok-title=\\"Reset key\\" ok-variant=\\"danger\\"> Resetting the authorization key for this project will require updating the authorization key in every alert source it is enabled in. </gl-modal-stub> </gl-form-group-stub> diff --git a/spec/frontend/alerts_settings/alerts_settings_form_new_spec.js b/spec/frontend/alerts_settings/alerts_settings_form_new_spec.js index 51d529c5e70..8d14babf4af 100644 --- a/spec/frontend/alerts_settings/alerts_settings_form_new_spec.js +++ b/spec/frontend/alerts_settings/alerts_settings_form_new_spec.js @@ -70,16 +70,70 @@ describe('AlertsSettingsFormNew', () => { }); }); - describe('when form is invalid', () => { - // TODO, implement specs for when form is invalid - }); + describe('submitting integration form', () => { + it('allows for create-new-integration with the correct form values for HTTP', async () => { + createComponent({}); - describe('when form is valid', () => { - beforeEach(() => { + const options = findSelect().findAll('option'); + await options.at(1).setSelected(); + + await findFormFields() + .at(0) + .setValue('Test integration'); + await findFormToggle().trigger('click'); + + await wrapper.vm.$nextTick(); + + expect(findSubmitButton().exists()).toBe(true); + expect(findSubmitButton().text()).toBe('Save integration'); + + findForm().trigger('submit'); + + await wrapper.vm.$nextTick(); + + expect(wrapper.emitted('create-new-integration')).toBeTruthy(); + expect(wrapper.emitted('create-new-integration')[0]).toEqual([ + { type: typeSet.http, variables: { name: 'Test integration', active: true } }, + ]); + }); + + it('allows for create-new-integration with the correct form values for PROMETHEUS', async () => { createComponent({}); + + const options = findSelect().findAll('option'); + await options.at(2).setSelected(); + + await findFormFields() + .at(0) + .setValue('Test integration'); + await findFormFields() + .at(1) + .setValue('https://test.com'); + await findFormToggle().trigger('click'); + + await wrapper.vm.$nextTick(); + + expect(findSubmitButton().exists()).toBe(true); + expect(findSubmitButton().text()).toBe('Save integration'); + + findForm().trigger('submit'); + + await wrapper.vm.$nextTick(); + + expect(wrapper.emitted('create-new-integration')).toBeTruthy(); + expect(wrapper.emitted('create-new-integration')[0]).toEqual([ + { type: typeSet.prometheus, variables: { apiUrl: 'https://test.com', active: true } }, + ]); }); - it('allows for on-create-new-integration with the correct form values for HTTP', async () => { + it('allows for update-integration with the correct form values for HTTP', async () => { + createComponent({ + props: { + currentIntegration: { id: '1' }, + loading: false, + }, + }); + const options = findSelect().findAll('option'); await options.at(1).setSelected(); @@ -97,13 +151,20 @@ describe('AlertsSettingsFormNew', () => { await wrapper.vm.$nextTick(); - expect(wrapper.emitted('on-create-new-integration')).toBeTruthy(); - expect(wrapper.emitted('on-create-new-integration')[0]).toEqual([ + expect(wrapper.emitted('update-integration')).toBeTruthy(); + expect(wrapper.emitted('update-integration')[0]).toEqual([ { type: typeSet.http, variables: { name: 'Test integration', active: true } }, ]); }); - it('allows for on-create-new-integration with the correct form values for PROMETHEUS', async () => { + it('allows for update-integration with the correct form values for PROMETHEUS', async () => { + createComponent({ + props: { + currentIntegration: { id: '1' }, + loading: false, + }, + }); + const options = findSelect().findAll('option'); await options.at(2).setSelected(); @@ -124,8 +185,8 @@ describe('AlertsSettingsFormNew', () => { await wrapper.vm.$nextTick(); - expect(wrapper.emitted('on-create-new-integration')).toBeTruthy(); - expect(wrapper.emitted('on-create-new-integration')[0]).toEqual([ + expect(wrapper.emitted('update-integration')).toBeTruthy(); + expect(wrapper.emitted('update-integration')[0]).toEqual([ { type: typeSet.prometheus, variables: { apiUrl: 'https://test.com', active: true } }, ]); }); diff --git a/spec/frontend/alerts_settings/alerts_settings_form_old_spec.js b/spec/frontend/alerts_settings/alerts_settings_form_old_spec.js index da4c74360d8..3d0dfb44d63 100644 --- a/spec/frontend/alerts_settings/alerts_settings_form_old_spec.js +++ b/spec/frontend/alerts_settings/alerts_settings_form_old_spec.js @@ -69,7 +69,7 @@ describe('AlertsSettingsFormOld', () => { createComponent( {}, { - authKey: 'newToken', + token: 'newToken', }, ); diff --git a/spec/frontend/alerts_settings/alerts_settings_wrapper_spec.js b/spec/frontend/alerts_settings/alerts_settings_wrapper_spec.js index ce7bed0dc0c..5fa21d01340 100644 --- a/spec/frontend/alerts_settings/alerts_settings_wrapper_spec.js +++ b/spec/frontend/alerts_settings/alerts_settings_wrapper_spec.js @@ -6,14 +6,24 @@ import AlertsSettingsFormNew from '~/alerts_settings/components/alerts_settings_ import IntegrationsList from '~/alerts_settings/components/alerts_integrations_list.vue'; import createHttpIntegrationMutation from '~/alerts_settings/graphql/mutations/create_http_integration.mutation.graphql'; import createPrometheusIntegrationMutation from '~/alerts_settings/graphql/mutations/create_prometheus_integration.mutation.graphql'; +import updateHttpIntegrationMutation from '~/alerts_settings/graphql/mutations/update_http_integration.mutation.graphql'; +import updatePrometheusIntegrationMutation from '~/alerts_settings/graphql/mutations/update_prometheus_integration.mutation.graphql'; +import resetHttpTokenMutation from '~/alerts_settings/graphql/mutations/reset_http_token.mutation.graphql'; +import resetPrometheusTokenMutation from '~/alerts_settings/graphql/mutations/reset_prometheus_token.mutation.graphql'; +import { typeSet } from '~/alerts_settings/constants'; import createFlash from '~/flash'; import { defaultAlertSettingsConfig } from './util'; import mockIntegrations from './mocks/integrations.json'; +import { + createHttpVariables, + updateHttpVariables, + createPrometheusVariables, + updatePrometheusVariables, + ID, +} from './mocks/apollo_mock'; jest.mock('~/flash'); -const projectPath = ''; - describe('AlertsSettingsWrapper', () => { let wrapper; @@ -80,7 +90,7 @@ describe('AlertsSettingsWrapper', () => { it('renders the IntegrationsList table using the API data', () => { createComponent({ - data: { integrations: { list: mockIntegrations } }, + data: { integrations: { list: mockIntegrations }, currentIntegration: mockIntegrations[0] }, provide: { glFeatures: { httpIntegrationsList: true } }, loading: false, }); @@ -100,7 +110,7 @@ describe('AlertsSettingsWrapper', () => { it('calls `$apollo.mutate` with `createHttpIntegrationMutation`', () => { createComponent({ - data: { integrations: { list: mockIntegrations } }, + data: { integrations: { list: mockIntegrations }, currentIntegration: mockIntegrations[0] }, provide: { glFeatures: { httpIntegrationsList: true } }, loading: false, }); @@ -108,26 +118,66 @@ describe('AlertsSettingsWrapper', () => { jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue({ data: { createHttpIntegrationMutation: { integration: { id: '1' } } }, }); - wrapper.find(AlertsSettingsFormNew).vm.$emit('on-create-new-integration', { - type: 'HTTP', - variables: { name: 'Test 1', active: true }, + wrapper.find(AlertsSettingsFormNew).vm.$emit('create-new-integration', { + type: typeSet.http, + variables: createHttpVariables, }); expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledTimes(1); expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({ mutation: createHttpIntegrationMutation, update: expect.anything(), + variables: createHttpVariables, + }); + }); + + it('calls `$apollo.mutate` with `updateHttpIntegrationMutation`', () => { + createComponent({ + data: { integrations: { list: mockIntegrations }, currentIntegration: mockIntegrations[0] }, + provide: { glFeatures: { httpIntegrationsList: true } }, + loading: false, + }); + + jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue({ + data: { updateHttpIntegrationMutation: { integration: { id: '1' } } }, + }); + wrapper.find(AlertsSettingsFormNew).vm.$emit('update-integration', { + type: typeSet.http, + variables: updateHttpVariables, + }); + + expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({ + mutation: updateHttpIntegrationMutation, + variables: updateHttpVariables, + }); + }); + + it('calls `$apollo.mutate` with `resetHttpTokenMutation`', () => { + createComponent({ + data: { integrations: { list: mockIntegrations }, currentIntegration: mockIntegrations[0] }, + provide: { glFeatures: { httpIntegrationsList: true } }, + loading: false, + }); + + jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue({ + data: { resetHttpTokenMutation: { integration: { id: '1' } } }, + }); + wrapper.find(AlertsSettingsFormNew).vm.$emit('reset-token', { + type: typeSet.http, + variables: { id: ID }, + }); + + expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({ + mutation: resetHttpTokenMutation, variables: { - name: 'Test 1', - active: true, - projectPath, + id: ID, }, }); }); it('calls `$apollo.mutate` with `createPrometheusIntegrationMutation`', () => { createComponent({ - data: { integrations: { list: mockIntegrations } }, + data: { integrations: { list: mockIntegrations }, currentIntegration: mockIntegrations[0] }, provide: { glFeatures: { httpIntegrationsList: true } }, loading: false, }); @@ -135,33 +185,107 @@ describe('AlertsSettingsWrapper', () => { jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue({ data: { createPrometheusIntegrationMutation: { integration: { id: '2' } } }, }); - wrapper.find(AlertsSettingsFormNew).vm.$emit('on-create-new-integration', { - type: 'PROMETHEUS', - variables: { apiUrl: 'https://test.com', active: true }, + wrapper.find(AlertsSettingsFormNew).vm.$emit('create-new-integration', { + type: typeSet.prometheus, + variables: createPrometheusVariables, }); expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledTimes(1); expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({ mutation: createPrometheusIntegrationMutation, update: expect.anything(), + variables: createPrometheusVariables, + }); + }); + + it('calls `$apollo.mutate` with `updatePrometheusIntegrationMutation`', () => { + createComponent({ + data: { integrations: { list: mockIntegrations }, currentIntegration: mockIntegrations[0] }, + provide: { glFeatures: { httpIntegrationsList: true } }, + loading: false, + }); + + jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue({ + data: { updatePrometheusIntegrationMutation: { integration: { id: '2' } } }, + }); + wrapper.find(AlertsSettingsFormNew).vm.$emit('update-integration', { + type: typeSet.prometheus, + variables: updatePrometheusVariables, + }); + + expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({ + mutation: updatePrometheusIntegrationMutation, + variables: updatePrometheusVariables, + }); + }); + + it('calls `$apollo.mutate` with `resetPrometheusTokenMutation`', () => { + createComponent({ + data: { integrations: { list: mockIntegrations }, currentIntegration: mockIntegrations[0] }, + provide: { glFeatures: { httpIntegrationsList: true } }, + loading: false, + }); + + jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue({ + data: { resetPrometheusTokenMutation: { integration: { id: '1' } } }, + }); + wrapper.find(AlertsSettingsFormNew).vm.$emit('reset-token', { + type: typeSet.prometheus, + variables: { id: ID }, + }); + + expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({ + mutation: resetPrometheusTokenMutation, variables: { - apiUrl: 'https://test.com', - active: true, - projectPath, + id: ID, }, }); }); - it('shows error alert when integration creation fails ', () => { + it('shows error alert when integration creation fails ', async () => { const errorMsg = 'Something went wrong'; createComponent({ - data: { integrations: { list: mockIntegrations } }, + data: { integrations: { list: mockIntegrations }, currentIntegration: mockIntegrations[0] }, + provide: { glFeatures: { httpIntegrationsList: true } }, + loading: false, + }); + + jest.spyOn(wrapper.vm.$apollo, 'mutate').mockRejectedValue(errorMsg); + wrapper.find(AlertsSettingsFormNew).vm.$emit('create-new-integration', {}); + + setImmediate(() => { + expect(createFlash).toHaveBeenCalledWith({ message: errorMsg }); + }); + }); + + it('shows error alert when integration token reset fails ', () => { + const errorMsg = 'Something went wrong'; + createComponent({ + data: { integrations: { list: mockIntegrations }, currentIntegration: mockIntegrations[0] }, provide: { glFeatures: { httpIntegrationsList: true } }, loading: false, }); jest.spyOn(wrapper.vm.$apollo, 'mutate').mockRejectedValue(errorMsg); - wrapper.find(AlertsSettingsFormNew).vm.$emit('on-create-new-integration', {}); + + wrapper.find(AlertsSettingsFormNew).vm.$emit('reset-token', {}); + + setImmediate(() => { + expect(createFlash).toHaveBeenCalledWith({ message: errorMsg }); + }); + }); + + it('shows error alert when integration update fails ', () => { + const errorMsg = 'Something went wrong'; + createComponent({ + data: { integrations: { list: mockIntegrations }, currentIntegration: mockIntegrations[0] }, + provide: { glFeatures: { httpIntegrationsList: true } }, + loading: false, + }); + + jest.spyOn(wrapper.vm.$apollo, 'mutate').mockRejectedValue(errorMsg); + + wrapper.find(AlertsSettingsFormNew).vm.$emit('update-integration', {}); setImmediate(() => { expect(createFlash).toHaveBeenCalledWith({ message: errorMsg }); diff --git a/spec/frontend/alerts_settings/mocks/apollo_mock.js b/spec/frontend/alerts_settings/mocks/apollo_mock.js new file mode 100644 index 00000000000..d4cf0627c66 --- /dev/null +++ b/spec/frontend/alerts_settings/mocks/apollo_mock.js @@ -0,0 +1,26 @@ +const projectPath = ''; +export const ID = 'gid://gitlab/AlertManagement::HttpIntegration/7'; + +export const createHttpVariables = { + name: 'Test Pre', + active: true, + projectPath, +}; + +export const updateHttpVariables = { + name: 'Test Pre', + active: true, + id: ID, +}; + +export const createPrometheusVariables = { + apiUrl: 'https://test-pre.com', + active: true, + projectPath, +}; + +export const updatePrometheusVariables = { + apiUrl: 'https://test-pre.com', + active: true, + id: ID, +}; diff --git a/spec/frontend/design_management/components/upload/__snapshots__/button_spec.js.snap b/spec/frontend/design_management/components/upload/__snapshots__/button_spec.js.snap index a91ce43cda1..2f857247303 100644 --- a/spec/frontend/design_management/components/upload/__snapshots__/button_spec.js.snap +++ b/spec/frontend/design_management/components/upload/__snapshots__/button_spec.js.snap @@ -14,41 +14,7 @@ exports[`Design management upload button component renders inverted upload desig > Upload designs - - <!----> - </gl-button-stub> - - <input - accept="image/*" - class="hide" - multiple="multiple" - name="design_file" - type="file" - /> -</div> -`; - -exports[`Design management upload button component renders loading icon 1`] = ` -<div> - <gl-button-stub - buttontextclasses="" - category="primary" - disabled="true" - icon="" - size="small" - title="Adding a design with the same filename replaces the file in a new version." - variant="default" - > - - Upload designs - - <gl-loading-icon-stub - class="ml-1" - color="dark" - inline="true" - label="Loading" - size="sm" - /> + </gl-button-stub> <input @@ -73,8 +39,7 @@ exports[`Design management upload button component renders upload design button > Upload designs - - <!----> + </gl-button-stub> <input diff --git a/spec/frontend/design_management/components/upload/button_spec.js b/spec/frontend/design_management/components/upload/button_spec.js index c0a9693dc37..ea738496ad6 100644 --- a/spec/frontend/design_management/components/upload/button_spec.js +++ b/spec/frontend/design_management/components/upload/button_spec.js @@ -1,10 +1,11 @@ import { shallowMount } from '@vue/test-utils'; +import { GlButton } from '@gitlab/ui'; import UploadButton from '~/design_management/components/upload/button.vue'; describe('Design management upload button component', () => { let wrapper; - function createComponent(isSaving = false, isInverted = false) { + function createComponent({ isSaving = false, isInverted = false } = {}) { wrapper = shallowMount(UploadButton, { propsData: { isSaving, @@ -24,15 +25,19 @@ describe('Design management upload button component', () => { }); it('renders inverted upload design button', () => { - createComponent(false, true); + createComponent({ isInverted: true }); expect(wrapper.element).toMatchSnapshot(); }); - it('renders loading icon', () => { - createComponent(true); + describe('when `isSaving` prop is `true`', () => { + it('Button `loading` prop is `true`', () => { + createComponent({ isSaving: true }); - expect(wrapper.element).toMatchSnapshot(); + const button = wrapper.find(GlButton); + expect(button.exists()).toBe(true); + expect(button.props('loading')).toBe(true); + }); }); describe('onFileUploadChange', () => { diff --git a/spec/frontend/integrations/edit/components/confirmation_modal_spec.js b/spec/frontend/integrations/edit/components/confirmation_modal_spec.js index 02f311f579f..b570ab4e844 100644 --- a/spec/frontend/integrations/edit/components/confirmation_modal_spec.js +++ b/spec/frontend/integrations/edit/components/confirmation_modal_spec.js @@ -34,7 +34,7 @@ describe('ConfirmationModal', () => { 'Saving will update the default settings for all projects that are not using custom settings.', ); expect(findGlModal().text()).toContain( - 'Projects using custom settings will not be impacted unless the project owner chooses to use instance-level defaults.', + 'Projects using custom settings will not be impacted unless the project owner chooses to use parent level defaults.', ); }); diff --git a/spec/frontend/integrations/edit/components/integration_form_spec.js b/spec/frontend/integrations/edit/components/integration_form_spec.js index efcc727277a..4dd38c959f8 100644 --- a/spec/frontend/integrations/edit/components/integration_form_spec.js +++ b/spec/frontend/integrations/edit/components/integration_form_spec.js @@ -9,6 +9,7 @@ import JiraTriggerFields from '~/integrations/edit/components/jira_trigger_field import JiraIssuesFields from '~/integrations/edit/components/jira_issues_fields.vue'; import TriggerFields from '~/integrations/edit/components/trigger_fields.vue'; import DynamicField from '~/integrations/edit/components/dynamic_field.vue'; +import { integrationLevels } from '~/integrations/edit/constants'; describe('IntegrationForm', () => { let wrapper; @@ -69,14 +70,24 @@ describe('IntegrationForm', () => { describe('integrationLevel is instance', () => { it('renders ConfirmationModal', () => { createComponent({ - integrationLevel: 'instance', + integrationLevel: integrationLevels.INSTANCE, }); expect(findConfirmationModal().exists()).toBe(true); }); }); - describe('integrationLevel is not instance', () => { + describe('integrationLevel is group', () => { + it('renders ConfirmationModal', () => { + createComponent({ + integrationLevel: integrationLevels.GROUP, + }); + + expect(findConfirmationModal().exists()).toBe(true); + }); + }); + + describe('integrationLevel is project', () => { it('does not render ConfirmationModal', () => { createComponent({ integrationLevel: 'project', diff --git a/spec/frontend/invite_members/components/invite_members_modal_spec.js b/spec/frontend/invite_members/components/invite_members_modal_spec.js index 0be0fbbde2d..18c3699adc3 100644 --- a/spec/frontend/invite_members/components/invite_members_modal_spec.js +++ b/spec/frontend/invite_members/components/invite_members_modal_spec.js @@ -9,7 +9,7 @@ const accessLevels = { Guest: 10, Reporter: 20, Developer: 30, Maintainer: 40, O const defaultAccessLevel = '10'; const helpLink = 'https://example.com'; -const createComponent = () => { +const createComponent = (data = {}) => { return shallowMount(InviteMembersModal, { propsData: { groupId, @@ -18,9 +18,14 @@ const createComponent = () => { defaultAccessLevel, helpLink, }, + data() { + return data; + }, stubs: { - GlSprintf, 'gl-modal': '<div><slot name="modal-footer"></slot><slot></slot></div>', + 'gl-dropdown': true, + 'gl-dropdown-item': true, + GlSprintf, }, }); }; @@ -34,7 +39,7 @@ describe('InviteMembersModal', () => { }); const findDropdown = () => wrapper.find(GlDropdown); - const findDropdownItems = () => wrapper.findAll(GlDropdownItem); + const findDropdownItems = () => findDropdown().findAll(GlDropdownItem); const findDatepicker = () => wrapper.find(GlDatepicker); const findLink = () => wrapper.find(GlLink); const findCancelButton = () => wrapper.find({ ref: 'cancelButton' }); @@ -88,25 +93,69 @@ describe('InviteMembersModal', () => { format: 'json', }; - beforeEach(() => { - wrapper = createComponent(); + describe('when the invite was sent successfully', () => { + beforeEach(() => { + wrapper = createComponent(); + + wrapper.vm.$toast = { show: jest.fn() }; + jest.spyOn(Api, 'inviteGroupMember').mockResolvedValue({ data: postData }); - jest.spyOn(Api, 'inviteGroupMember').mockResolvedValue({ data: postData }); - wrapper.vm.$toast = { show: jest.fn() }; + wrapper.vm.submitForm(postData); + }); - wrapper.vm.submitForm(postData); + it('displays the successful toastMessage', () => { + const toastMessageSuccessful = 'Members were successfully added'; + + expect(wrapper.vm.$toast.show).toHaveBeenCalledWith( + toastMessageSuccessful, + wrapper.vm.toastOptions, + ); + }); + + it('calls Api inviteGroupMember with the correct params', () => { + expect(Api.inviteGroupMember).toHaveBeenCalledWith(groupId, postData); + }); }); - it('calls Api inviteGroupMember with the correct params', () => { - expect(Api.inviteGroupMember).toHaveBeenCalledWith(groupId, postData); + describe('when sending the invite for a single member returned an api error', () => { + const apiErrorMessage = 'Members already exists'; + + beforeEach(() => { + wrapper = createComponent({ newUsersToInvite: '123' }); + + wrapper.vm.$toast = { show: jest.fn() }; + jest + .spyOn(Api, 'inviteGroupMember') + .mockRejectedValue({ response: { data: { message: apiErrorMessage } } }); + + findInviteButton().vm.$emit('click'); + }); + + it('displays the api error message for the toastMessage', () => { + expect(wrapper.vm.$toast.show).toHaveBeenCalledWith( + apiErrorMessage, + wrapper.vm.toastOptions, + ); + }); }); - describe('when the invite was sent successfully', () => { - const toastMessageSuccessful = 'Users were succesfully added'; + describe('when sending the invite for multiple members returned any error', () => { + const genericErrorMessage = 'Some of the members could not be added'; - it('displays the successful toastMessage', () => { + beforeEach(() => { + wrapper = createComponent({ newUsersToInvite: '123' }); + + wrapper.vm.$toast = { show: jest.fn() }; + jest + .spyOn(Api, 'inviteGroupMember') + .mockRejectedValue({ response: { data: { success: false } } }); + + findInviteButton().vm.$emit('click'); + }); + + it('displays the expected toastMessage', () => { expect(wrapper.vm.$toast.show).toHaveBeenCalledWith( - toastMessageSuccessful, + genericErrorMessage, wrapper.vm.toastOptions, ); }); diff --git a/spec/frontend/invite_members/components/members_token_select_spec.js b/spec/frontend/invite_members/components/members_token_select_spec.js new file mode 100644 index 00000000000..fb0bd6bb195 --- /dev/null +++ b/spec/frontend/invite_members/components/members_token_select_spec.js @@ -0,0 +1,112 @@ +import { shallowMount } from '@vue/test-utils'; +import { nextTick } from 'vue'; +import { GlTokenSelector } from '@gitlab/ui'; +import waitForPromises from 'helpers/wait_for_promises'; +import Api from '~/api'; +import MembersTokenSelect from '~/invite_members/components/members_token_select.vue'; + +const label = 'testgroup'; +const placeholder = 'Search for a member'; +const user1 = { id: 1, name: 'Name One', username: 'one_1', avatar_url: '' }; +const user2 = { id: 2, name: 'Name Two', username: 'two_2', avatar_url: '' }; +const allUsers = [user1, user2]; + +const createComponent = () => { + return shallowMount(MembersTokenSelect, { + propsData: { + ariaLabelledby: label, + placeholder, + }, + }); +}; + +describe('MembersTokenSelect', () => { + let wrapper; + + beforeEach(() => { + jest.spyOn(Api, 'users').mockResolvedValue({ data: allUsers }); + wrapper = createComponent(); + }); + + afterEach(() => { + wrapper.destroy(); + wrapper = null; + }); + + const findTokenSelector = () => wrapper.find(GlTokenSelector); + + describe('rendering the token-selector component', () => { + it('renders with the correct props', () => { + const expectedProps = { + ariaLabelledby: label, + placeholder, + }; + + expect(findTokenSelector().props()).toEqual(expect.objectContaining(expectedProps)); + }); + }); + + describe('users', () => { + describe('when input is focused for the first time (modal auto-focus)', () => { + it('does not call the API', async () => { + findTokenSelector().vm.$emit('focus'); + + await waitForPromises(); + + expect(Api.users).not.toHaveBeenCalled(); + }); + }); + + describe('when input is manually focused', () => { + it('calls the API and sets dropdown items as request result', async () => { + const tokenSelector = findTokenSelector(); + + tokenSelector.vm.$emit('focus'); + tokenSelector.vm.$emit('blur'); + tokenSelector.vm.$emit('focus'); + + await waitForPromises(); + + expect(tokenSelector.props('dropdownItems')).toMatchObject(allUsers); + expect(tokenSelector.props('hideDropdownWithNoItems')).toBe(false); + }); + }); + + describe('when text input is typed in', () => { + it('calls the API with search parameter', async () => { + const searchParam = 'One'; + const tokenSelector = findTokenSelector(); + + tokenSelector.vm.$emit('text-input', searchParam); + + await waitForPromises(); + + expect(Api.users).toHaveBeenCalledWith(searchParam, wrapper.vm.$options.queryOptions); + expect(tokenSelector.props('hideDropdownWithNoItems')).toBe(false); + }); + }); + + describe('when user is selected', () => { + it('emits `input` event with selected users', () => { + findTokenSelector().vm.$emit('input', [ + { id: 1, name: 'John Smith' }, + { id: 2, name: 'Jane Doe' }, + ]); + + expect(wrapper.emitted().input[0][0]).toBe('1,2'); + }); + }); + }); + + describe('when text input is blurred', () => { + it('clears text input', async () => { + const tokenSelector = findTokenSelector(); + + tokenSelector.vm.$emit('blur'); + + await nextTick(); + + expect(tokenSelector.props('hideDropdownWithNoItems')).toBe(false); + }); + }); +}); diff --git a/spec/helpers/page_layout_helper_spec.rb b/spec/helpers/page_layout_helper_spec.rb index f49b09adea0..c7abed2c69e 100644 --- a/spec/helpers/page_layout_helper_spec.rb +++ b/spec/helpers/page_layout_helper_spec.rb @@ -208,4 +208,27 @@ RSpec.describe PageLayoutHelper do end end end + + describe '#page_itemtype' do + subject { helper.page_itemtype(itemtype) } + + context 'when itemtype is passed' do + let(:itemtype) { 'http://schema.org/Person' } + + it 'stores and returns the itemtype value' do + attrs = { itemscope: true, itemtype: itemtype } + + expect(subject).to eq attrs + expect(helper.page_itemtype(nil)).to eq attrs + end + end + + context 'when no itemtype is provided' do + let(:itemtype) { nil } + + it 'returns an empty hash' do + expect(subject).to eq({}) + end + end + end end diff --git a/spec/helpers/users_helper_spec.rb b/spec/helpers/users_helper_spec.rb index c9dc3fcff3f..9ebbf975903 100644 --- a/spec/helpers/users_helper_spec.rb +++ b/spec/helpers/users_helper_spec.rb @@ -204,40 +204,72 @@ RSpec.describe UsersHelper do end describe '#work_information' do - subject { helper.work_information(user) } + let(:with_schema_markup) { false } - context 'when both job_title and organization are present' do - let(:user) { build(:user, organization: 'GitLab', job_title: 'Frontend Engineer') } + subject { helper.work_information(user, with_schema_markup: with_schema_markup) } - it 'returns job title concatenated with organization' do - is_expected.to eq('Frontend Engineer at GitLab') - end + context 'when neither organization nor job_title are present' do + it { is_expected.to be_nil } end - context 'when only organization is present' do - let(:user) { build(:user, organization: 'GitLab') } + context 'when user parameter is nil' do + let(:user) { nil } - it "returns organization" do - is_expected.to eq('GitLab') - end + it { is_expected.to be_nil } end - context 'when only job_title is present' do - let(:user) { build(:user, job_title: 'Frontend Engineer') } + context 'without schema markup' do + context 'when both job_title and organization are present' do + let(:user) { build(:user, organization: 'GitLab', job_title: 'Frontend Engineer') } - it 'returns job title' do - is_expected.to eq('Frontend Engineer') + it 'returns job title concatenated with organization' do + is_expected.to eq('Frontend Engineer at GitLab') + end end - end - context 'when neither organization nor job_title are present' do - it { is_expected.to be_nil } + context 'when only organization is present' do + let(:user) { build(:user, organization: 'GitLab') } + + it "returns organization" do + is_expected.to eq('GitLab') + end + end + + context 'when only job_title is present' do + let(:user) { build(:user, job_title: 'Frontend Engineer') } + + it 'returns job title' do + is_expected.to eq('Frontend Engineer') + end + end end - context 'when user parameter is nil' do - let(:user) { nil } + context 'with schema markup' do + let(:with_schema_markup) { true } - it { is_expected.to be_nil } + context 'when both job_title and organization are present' do + let(:user) { build(:user, organization: 'GitLab', job_title: 'Frontend Engineer') } + + it 'returns job title concatenated with organization' do + is_expected.to eq('<span itemprop="jobTitle">Frontend Engineer</span> at <span itemprop="worksFor">GitLab</span>') + end + end + + context 'when only organization is present' do + let(:user) { build(:user, organization: 'GitLab') } + + it "returns organization" do + is_expected.to eq('<span itemprop="worksFor">GitLab</span>') + end + end + + context 'when only job_title is present' do + let(:user) { build(:user, job_title: 'Frontend Engineer') } + + it 'returns job title' do + is_expected.to eq('<span itemprop="jobTitle">Frontend Engineer</span>') + end + end end end end diff --git a/spec/lib/gitlab/danger/helper_spec.rb b/spec/lib/gitlab/danger/helper_spec.rb index 9866965589f..f400641706d 100644 --- a/spec/lib/gitlab/danger/helper_spec.rb +++ b/spec/lib/gitlab/danger/helper_spec.rb @@ -236,13 +236,16 @@ RSpec.describe Gitlab::Danger::Helper do '.gitlab/ci/frontend.gitlab-ci.yml' | %i[frontend engineering_productivity] - 'app/models/foo' | [:backend] - 'bin/foo' | [:backend] - 'config/foo' | [:backend] - 'lib/foo' | [:backend] - 'rubocop/foo' | [:backend] - 'spec/foo' | [:backend] - 'spec/foo/bar' | [:backend] + 'app/models/foo' | [:backend] + 'bin/foo' | [:backend] + 'config/foo' | [:backend] + 'lib/foo' | [:backend] + 'rubocop/foo' | [:backend] + '.rubocop.yml' | [:backend] + '.rubocop_todo.yml' | [:backend] + '.rubocop_manual_todo.yml' | [:backend] + 'spec/foo' | [:backend] + 'spec/foo/bar' | [:backend] 'ee/app/foo' | [:backend] 'ee/bin/foo' | [:backend] diff --git a/spec/models/key_spec.rb b/spec/models/key_spec.rb index 1e14864676c..3d33a39d353 100644 --- a/spec/models/key_spec.rb +++ b/spec/models/key_spec.rb @@ -108,7 +108,7 @@ RSpec.describe Key, :mailer do expect(build(:key, key: 'ssh-rsa an-invalid-key==')).not_to be_valid end - where(:factory, :chars, :expected_sections) do + where(:factory, :characters, :expected_sections) do [ [:key, ["\n", "\r\n"], 3], [:key, [' ', ' '], 3], @@ -122,7 +122,7 @@ RSpec.describe Key, :mailer do let!(:original_fingerprint_sha256) { key.fingerprint_sha256 } it 'accepts a key with blank space characters after stripping them' do - modified_key = key.key.insert(100, chars.first).insert(40, chars.last) + modified_key = key.key.insert(100, characters.first).insert(40, characters.last) _, content = modified_key.split key.update!(key: modified_key) diff --git a/spec/rubocop/cop/code_reuse/active_record_spec.rb b/spec/rubocop/cop/code_reuse/active_record_spec.rb deleted file mode 100644 index e15b9e11aed..00000000000 --- a/spec/rubocop/cop/code_reuse/active_record_spec.rb +++ /dev/null @@ -1,134 +0,0 @@ -# frozen_string_literal: true - -require 'fast_spec_helper' -require 'rubocop' -require_relative '../../../../rubocop/cop/code_reuse/active_record' - -RSpec.describe RuboCop::Cop::CodeReuse::ActiveRecord, type: :rubocop do - include CopHelper - - subject(:cop) { described_class.new } - - it 'flags the use of "where" without any arguments' do - expect_offense(<<~SOURCE) - def foo - User.where - ^^^^^ This method can only be used inside an ActiveRecord model: https://gitlab.com/gitlab-org/gitlab-foss/issues/49653 - end - SOURCE - end - - it 'flags the use of "where" with arguments' do - expect_offense(<<~SOURCE) - def foo - User.where(id: 10) - ^^^^^ This method can only be used inside an ActiveRecord model: https://gitlab.com/gitlab-org/gitlab-foss/issues/49653 - end - SOURCE - end - - it 'does not flag the use of "group" without any arguments' do - expect_no_offenses(<<~SOURCE) - def foo - project.group - end - SOURCE - end - - it 'flags the use of "group" with arguments' do - expect_offense(<<~SOURCE) - def foo - project.group(:name) - ^^^^^ This method can only be used inside an ActiveRecord model: https://gitlab.com/gitlab-org/gitlab-foss/issues/49653 - end - SOURCE - end - - it 'does not flag the use of ActiveRecord models in a model' do - path = rails_root_join('app', 'models', 'foo.rb').to_s - - expect_no_offenses(<<~SOURCE, path) - def foo - project.group(:name) - end - SOURCE - end - - it 'does not flag the use of ActiveRecord models in a spec' do - path = rails_root_join('spec', 'foo_spec.rb').to_s - - expect_no_offenses(<<~SOURCE, path) - def foo - project.group(:name) - end - SOURCE - end - - it 'does not flag the use of ActiveRecord models in a background migration' do - path = rails_root_join('lib', 'gitlab', 'background_migration', 'foo.rb').to_s - - expect_no_offenses(<<~SOURCE, path) - def foo - project.group(:name) - end - SOURCE - end - - it 'does not flag the use of ActiveRecord models in lib/gitlab/database' do - path = rails_root_join('lib', 'gitlab', 'database', 'foo.rb').to_s - - expect_no_offenses(<<~SOURCE, path) - def foo - project.group(:name) - end - SOURCE - end - - it 'autocorrects offenses in instance methods by allowing them' do - corrected = autocorrect_source(<<~SOURCE) - def foo - User.where - end - SOURCE - - expect(corrected).to eq(<<~SOURCE) - # rubocop: disable CodeReuse/ActiveRecord - def foo - User.where - end - # rubocop: enable CodeReuse/ActiveRecord - SOURCE - end - - it 'autocorrects offenses in class methods by allowing them' do - corrected = autocorrect_source(<<~SOURCE) - def self.foo - User.where - end - SOURCE - - expect(corrected).to eq(<<~SOURCE) - # rubocop: disable CodeReuse/ActiveRecord - def self.foo - User.where - end - # rubocop: enable CodeReuse/ActiveRecord - SOURCE - end - - it 'autocorrects offenses in blocks by allowing them' do - corrected = autocorrect_source(<<~SOURCE) - get '/' do - User.where - end - SOURCE - - expect(corrected).to eq(<<~SOURCE) - # rubocop: disable CodeReuse/ActiveRecord - get '/' do - User.where - end - # rubocop: enable CodeReuse/ActiveRecord - SOURCE - end -end diff --git a/spec/rubocop/cop/rspec/be_success_matcher_spec.rb b/spec/rubocop/cop/rspec/be_success_matcher_spec.rb index a16cd8b634f..b14cf39cbde 100644 --- a/spec/rubocop/cop/rspec/be_success_matcher_spec.rb +++ b/spec/rubocop/cop/rspec/be_success_matcher_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require 'fast_spec_helper' - +require 'rubocop' require_relative '../../../../rubocop/cop/rspec/be_success_matcher' RSpec.describe RuboCop::Cop::RSpec::BeSuccessMatcher, type: :rubocop do diff --git a/spec/support/helpers/cop_helper.rb b/spec/support/helpers/cop_helper.rb new file mode 100644 index 00000000000..d4c056eea8a --- /dev/null +++ b/spec/support/helpers/cop_helper.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true + +require 'tempfile' + +# This module provides methods that make it easier to test Cops. +module CopHelper + extend RSpec::SharedContext + + let(:ruby_version) { 2.4 } + let(:rails_version) { false } + + def inspect_source_file(source) + Tempfile.open('tmp') { |f| inspect_source(source, f) } + end + + def inspect_source(source, file = nil) + RuboCop::Formatter::DisabledConfigFormatter.config_to_allow_offenses = {} + RuboCop::Formatter::DisabledConfigFormatter.detected_styles = {} + processed_source = parse_source(source, file) + raise 'Error parsing example code' unless processed_source.valid_syntax? + + _investigate(cop, processed_source) + end + + def parse_source(source, file = nil) + if file&.respond_to?(:write) + file.write(source) + file.rewind + file = file.path + end + + RuboCop::ProcessedSource.new(source, ruby_version, file) + end + + def autocorrect_source_file(source) + Tempfile.open('tmp') { |f| autocorrect_source(source, f) } + end + + def autocorrect_source(source, file = nil) + RuboCop::Formatter::DisabledConfigFormatter.config_to_allow_offenses = {} + RuboCop::Formatter::DisabledConfigFormatter.detected_styles = {} + cop.instance_variable_get(:@options)[:auto_correct] = true + processed_source = parse_source(source, file) + _investigate(cop, processed_source) + + @last_corrector.rewrite + end + + def _investigate(cop, processed_source) + team = RuboCop::Cop::Team.new([cop], nil, raise_error: true) + report = team.investigate(processed_source) + @last_corrector = report.correctors.first || RuboCop::Cop::Corrector.new(processed_source) + report.offenses + end +end + +module RuboCop + module Cop + # Monkey-patch Cop for tests to provide easy access to messages and + # highlights. + # this file is an exact copy of source except for this line + # where we change to the new Base class defined in rubocop and skirt around our superclass mismatch for class Cop + # when running a rubocop spec. + class Base + def messages + offenses.sort.map(&:message) + end + + def highlights + offenses.sort.map { |o| o.location.source } + end + end + end +end diff --git a/spec/support/rspec.rb b/spec/support/rspec.rb index 861b57c9efa..558a6ee1e86 100644 --- a/spec/support/rspec.rb +++ b/spec/support/rspec.rb @@ -5,7 +5,8 @@ require_relative "helpers/stub_metrics" require_relative "helpers/stub_object_storage" require_relative "helpers/stub_env" require_relative "helpers/fast_rails_root" -require 'rubocop/rspec/support' + +require_relative 'rubocop_patch' RSpec.configure do |config| config.mock_with :rspec diff --git a/spec/support/rubocop_patch.rb b/spec/support/rubocop_patch.rb new file mode 100644 index 00000000000..f485ef32a87 --- /dev/null +++ b/spec/support/rubocop_patch.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +# There is an issue between rubocop versions 0.86 and 0.87 (verified by testing locally) +# where the monkey patching in cop_helper is referencing class Cop and should really be referencing class Base instead +# the gem's version of the cop_helper causes this issue when testing a rubocop cop locally and in CI +# The only difference in this file as compared to gem source file is that we include our own cop_helper instead +# which is a direct copy with a fix for the monkey patching part. +# Doing this, resolves the issue. +# Ideally we should move away from using the cop_helper at all as is the direction of rubocop as seen +# here - https://github.com/rubocop-hq/rubocop/issues/8003 +# more info https://gitlab.com/gitlab-org/gitlab/-/merge_requests/46477 + +require_relative 'helpers/cop_helper' +require 'rubocop/rspec/host_environment_simulation_helper' +require 'rubocop/rspec/shared_contexts' +require 'rubocop/rspec/expect_offense' + +RSpec.configure do |config| + config.include CopHelper + config.include HostEnvironmentSimulatorHelper +end diff --git a/tooling/overcommit/Gemfile b/tooling/overcommit/Gemfile index 615da316fd5..571ea1862a5 100644 --- a/tooling/overcommit/Gemfile +++ b/tooling/overcommit/Gemfile @@ -4,6 +4,6 @@ source 'https://rubygems.org' gem 'overcommit' -gem 'gitlab-styles', '~> 4.3.0', require: false +gem 'gitlab-styles', '~> 5.0.0', require: false gem 'scss_lint', '~> 0.56.0', require: false gem 'haml_lint', '~> 0.34.0', require: false diff --git a/tooling/overcommit/Gemfile.lock b/tooling/overcommit/Gemfile.lock index 15b4a0b0d04..6527ad3fcda 100644 --- a/tooling/overcommit/Gemfile.lock +++ b/tooling/overcommit/Gemfile.lock @@ -1,22 +1,22 @@ GEM remote: https://rubygems.org/ specs: - activesupport (6.0.3) + activesupport (6.0.3.4) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) zeitwerk (~> 2.2, >= 2.2.2) - ast (2.4.0) + ast (2.4.1) childprocess (3.0.0) - concurrent-ruby (1.1.6) + concurrent-ruby (1.1.7) ffi (1.12.2) - gitlab-styles (4.3.0) - rubocop (~> 0.82.0) + gitlab-styles (5.0.0) + rubocop (~> 0.89.1) rubocop-gitlab-security (~> 0.1.0) - rubocop-performance (~> 1.5.2) - rubocop-rails (~> 2.5) - rubocop-rspec (~> 1.36) + rubocop-performance (~> 1.8.1) + rubocop-rails (~> 2.8) + rubocop-rspec (~> 1.44) haml (5.1.2) temple (>= 0.8.0) tilt @@ -25,42 +25,47 @@ GEM rainbow rubocop (>= 0.50.0) sysexits (~> 1.1) - i18n (1.8.2) + i18n (1.8.5) concurrent-ruby (~> 1.0) iniparse (1.5.0) - jaro_winkler (1.5.4) - minitest (5.11.3) + minitest (5.14.2) overcommit (0.53.0) childprocess (>= 0.6.3, < 4) iniparse (~> 1.4) - parallel (1.19.1) - parser (2.7.1.2) - ast (~> 2.4.0) - rack (2.0.9) + parallel (1.19.2) + parser (2.7.2.0) + ast (~> 2.4.1) + rack (2.2.3) rainbow (3.0.0) rake (12.3.3) rb-fsevent (0.10.2) rb-inotify (0.9.10) ffi (>= 0.5.0, < 2) + regexp_parser (1.8.2) rexml (3.2.4) - rubocop (0.82.0) - jaro_winkler (~> 1.5.1) + rubocop (0.89.1) parallel (~> 1.10) - parser (>= 2.7.0.1) + parser (>= 2.7.1.1) rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.7) rexml + rubocop-ast (>= 0.3.0, < 1.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 1.4.0, < 2.0) + rubocop-ast (0.8.0) + parser (>= 2.7.1.5) rubocop-gitlab-security (0.1.1) rubocop (>= 0.51) - rubocop-performance (1.5.2) - rubocop (>= 0.71.0) - rubocop-rails (2.5.2) - activesupport + rubocop-performance (1.8.1) + rubocop (>= 0.87.0) + rubocop-ast (>= 0.4.0) + rubocop-rails (2.8.1) + activesupport (>= 4.2.0) rack (>= 1.1) - rubocop (>= 0.72.0) - rubocop-rspec (1.37.0) - rubocop (>= 0.68.1) + rubocop (>= 0.87.0) + rubocop-rspec (1.44.1) + rubocop (~> 0.87) + rubocop-ast (>= 0.7.1) ruby-progressbar (1.10.1) sass (3.5.5) sass-listen (~> 4.0.0) @@ -77,13 +82,13 @@ GEM tzinfo (1.2.7) thread_safe (~> 0.1) unicode-display_width (1.7.0) - zeitwerk (2.3.0) + zeitwerk (2.4.1) PLATFORMS ruby DEPENDENCIES - gitlab-styles (~> 4.3.0) + gitlab-styles (~> 5.0.0) haml_lint (~> 0.34.0) overcommit scss_lint (~> 0.56.0) |