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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-09-14 18:12:56 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-09-14 18:12:56 +0300
commitc014b6b4e5c33180dd5cbff1dd1bb4623d1eca80 (patch)
tree0aa4dbf0c9236ebd669b26240a18c08aef2cc50e
parent16daf112d6cfe2c87d8837382a00d88aa8c0ff5c (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.gitlab/CODEOWNERS6
-rw-r--r--.rubocop_todo/rails/application_controller.yml13
-rw-r--r--Gemfile11
-rw-r--r--Gemfile.lock56
-rw-r--r--app/assets/javascripts/releases/stores/modules/edit_new/actions.js50
-rw-r--r--app/assets/stylesheets/_page_specific_files.scss1
-rw-r--r--app/assets/stylesheets/framework/files.scss4
-rw-r--r--app/assets/stylesheets/page_bundles/editor.scss (renamed from app/assets/stylesheets/pages/editor.scss)18
-rw-r--r--app/assets/stylesheets/utilities.scss10
-rw-r--r--app/controllers/acme_challenges_controller.rb2
-rw-r--r--app/controllers/chaos_controller.rb2
-rw-r--r--app/controllers/health_controller.rb2
-rw-r--r--app/controllers/metrics_controller.rb2
-rw-r--r--app/models/ci/pipeline.rb4
-rw-r--r--app/services/releases/create_service.rb3
-rw-r--r--app/views/notify/remote_mirror_update_failed_email.html.haml18
-rw-r--r--app/views/notify/removed_milestone_merge_request_email.html.haml2
-rw-r--r--app/views/projects/blob/edit.html.haml1
-rw-r--r--app/views/projects/blob/new.html.haml1
-rw-r--r--app/views/projects/ci/pipeline_editor/show.html.haml1
-rw-r--r--config/application.rb1
-rw-r--r--config/feature_flags/development/ci_limit_active_jobs_early.yml8
-rw-r--r--config/initializers/omniauth.rb11
-rw-r--r--config/object_store_settings.rb17
-rw-r--r--data/removals/15_0/15-0-remove-background-upload-object-storage.yml5
-rw-r--r--doc/operations/error_tracking.md2
-rw-r--r--doc/operations/feature_flags.md16
-rw-r--r--doc/operations/incident_management/alerts.md6
-rw-r--r--doc/operations/incident_management/escalation_policies.md6
-rw-r--r--doc/operations/incident_management/incident_timeline_events.md8
-rw-r--r--doc/operations/incident_management/linked_resources.md6
-rw-r--r--doc/operations/incident_management/oncall_schedules.md12
-rw-r--r--doc/operations/incident_management/paging.md2
-rw-r--r--doc/operations/incident_management/status_page.md4
-rw-r--r--doc/operations/product_analytics.md2
-rw-r--r--doc/tutorials/make_your_first_git_commit.md4
-rw-r--r--doc/tutorials/move_personal_project_to_a_group.md8
-rw-r--r--doc/update/index.md2
-rw-r--r--doc/update/plan_your_upgrade.md2
-rw-r--r--doc/update/removals.md4
-rw-r--r--doc/user/crm/index.md18
-rw-r--r--doc/user/discussions/index.md6
-rw-r--r--doc/user/free_user_limit.md2
-rw-r--r--doc/user/group/access_and_permissions.md28
-rw-r--r--doc/user/group/manage.md69
-rw-r--r--doc/user/profile/account/create_accounts.md2
-rw-r--r--doc/user/profile/account/delete_account.md2
-rw-r--r--doc/user/profile/index.md4
-rw-r--r--doc/user/profile/notifications.md4
-rw-r--r--doc/user/project/issue_board.md34
-rw-r--r--doc/user/project/issues/managing_issues.md18
-rw-r--r--doc/user/project/merge_requests/cherry_pick_changes.md8
-rw-r--r--doc/user/project/merge_requests/commit_templates.md2
-rw-r--r--doc/user/project/merge_requests/creating_merge_requests.md10
-rw-r--r--doc/user/project/merge_requests/csv_export.md2
-rw-r--r--doc/user/project/merge_requests/dependencies.md6
-rw-r--r--doc/user/project/merge_requests/index.md8
-rw-r--r--doc/user/project/merge_requests/merge_when_pipeline_succeeds.md8
-rw-r--r--doc/user/project/merge_requests/methods/index.md2
-rw-r--r--doc/user/project/merge_requests/revert_changes.md4
-rw-r--r--doc/user/project/merge_requests/squash_and_merge.md2
-rw-r--r--doc/user/project/milestones/index.md14
-rw-r--r--doc/user/project/repository/branches/default.md8
-rw-r--r--doc/user/project/repository/gpg_signed_commits/index.md4
-rw-r--r--doc/user/project/repository/mirror/bidirectional.md2
-rw-r--r--doc/user/project/repository/mirror/index.md8
-rw-r--r--doc/user/project/repository/mirror/pull.md2
-rw-r--r--doc/user/project/repository/mirror/push.md2
-rw-r--r--doc/user/project/repository/push_rules.md4
-rw-r--r--doc/user/project/settings/index.md26
-rw-r--r--doc/user/project/web_ide/index.md2
-rw-r--r--doc/user/project/wiki/group.md4
-rw-r--r--doc/user/project/wiki/index.md8
-rw-r--r--doc/user/project/working_with_projects.md70
-rw-r--r--doc/user/usage_quotas.md2
-rw-r--r--lib/gitlab/base_doorkeeper_controller.rb2
-rw-r--r--lib/gitlab/ci/parsers/security/validators/schema_validator.rb16
-rw-r--r--lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/cluster-image-scanning-report-format.json946
-rw-r--r--lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/container-scanning-report-format.json880
-rw-r--r--lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/coverage-fuzzing-report-format.json836
-rw-r--r--lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/dast-report-format.json1241
-rw-r--r--lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/dependency-scanning-report-format.json944
-rw-r--r--lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/sast-report-format.json831
-rw-r--r--lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/secret-detection-report-format.json854
-rw-r--r--lib/gitlab/ci/pipeline/chain/command.rb8
-rw-r--r--lib/gitlab/ci/pipeline/chain/validate/external.rb2
-rw-r--r--lib/gitlab/request_forgery_protection.rb2
-rw-r--r--locale/gitlab.pot18
-rw-r--r--rubocop/code_reuse_helpers.rb2
-rw-r--r--rubocop/cop/active_model_errors_direct_manipulation.rb10
-rw-r--r--rubocop/cop/active_record_association_reload.rb4
-rw-r--r--rubocop/cop/api/base.rb14
-rw-r--r--rubocop/cop/api/grape_array_missing_coerce.rb2
-rw-r--r--rubocop/cop/avoid_becomes.rb4
-rw-r--r--rubocop/cop/avoid_break_from_strong_memoize.rb2
-rw-r--r--rubocop/cop/avoid_keyword_arguments_in_sidekiq_workers.rb4
-rw-r--r--rubocop/cop/avoid_return_from_blocks.rb2
-rw-r--r--rubocop/cop/avoid_route_redirect_leading_slash.rb14
-rw-r--r--rubocop/cop/ban_catch_throw.rb4
-rw-r--r--rubocop/cop/code_reuse/finder.rb2
-rw-r--r--rubocop/cop/code_reuse/presenter.rb2
-rw-r--r--rubocop/cop/code_reuse/serializer.rb2
-rw-r--r--rubocop/cop/code_reuse/service_class.rb2
-rw-r--r--rubocop/cop/code_reuse/worker.rb2
-rw-r--r--rubocop/cop/database/disable_referential_integrity.rb2
-rw-r--r--rubocop/cop/database/establish_connection.rb4
-rw-r--r--rubocop/cop/database/multiple_databases.rb4
-rw-r--r--rubocop/cop/database/rescue_query_canceled.rb2
-rw-r--r--rubocop/cop/database/rescue_statement_timeout.rb2
-rw-r--r--rubocop/cop/default_scope.rb4
-rw-r--r--rubocop/cop/destroy_all.rb4
-rw-r--r--rubocop/cop/file_decompression.rb4
-rw-r--r--rubocop/cop/filename_length.rb8
-rw-r--r--rubocop/cop/gitlab/avoid_feature_category_not_owned.rb4
-rw-r--r--rubocop/cop/gitlab/avoid_feature_get.rb4
-rw-r--r--rubocop/cop/gitlab/avoid_uploaded_file_from_params.rb4
-rw-r--r--rubocop/cop/gitlab/bulk_insert.rb4
-rw-r--r--rubocop/cop/gitlab/change_timezone.rb2
-rw-r--r--rubocop/cop/gitlab/const_get_inherit_false.rb10
-rw-r--r--rubocop/cop/gitlab/delegate_predicate_methods.rb2
-rw-r--r--rubocop/cop/gitlab/deprecate_track_redis_hll_event.rb4
-rw-r--r--rubocop/cop/gitlab/event_store_subscriber.rb2
-rw-r--r--rubocop/cop/gitlab/except.rb4
-rw-r--r--rubocop/cop/gitlab/feature_available_usage.rb6
-rw-r--r--rubocop/cop/gitlab/finder_with_find_by.rb14
-rw-r--r--rubocop/cop/gitlab/httparty.rb41
-rw-r--r--rubocop/cop/gitlab/intersect.rb4
-rw-r--r--rubocop/cop/gitlab/json.rb18
-rw-r--r--rubocop/cop/gitlab/mark_used_feature_flags.rb2
-rw-r--r--rubocop/cop/gitlab/module_with_instance_variables.rb6
-rw-r--r--rubocop/cop/gitlab/policy_rule_boolean.rb2
-rw-r--r--rubocop/cop/gitlab/predicate_memoization.rb2
-rw-r--r--rubocop/cop/gitlab/rails_logger.rb2
-rw-r--r--rubocop/cop/gitlab/union.rb4
-rw-r--r--rubocop/cop/graphql/authorize_types.rb4
-rw-r--r--rubocop/cop/graphql/descriptions.rb20
-rw-r--r--rubocop/cop/graphql/gid_expected_type.rb2
-rw-r--r--rubocop/cop/graphql/graphql_name_position.rb4
-rw-r--r--rubocop/cop/graphql/id_type.rb2
-rw-r--r--rubocop/cop/graphql/json_type.rb4
-rw-r--r--rubocop/cop/graphql/old_types.rb4
-rw-r--r--rubocop/cop/graphql/resolver_type.rb4
-rw-r--r--rubocop/cop/group_public_or_visible_to_user.rb4
-rw-r--r--rubocop/cop/ignored_columns.rb6
-rw-r--r--rubocop/cop/include_sidekiq_worker.rb12
-rw-r--r--rubocop/cop/inject_enterprise_edition_module.rb14
-rw-r--r--rubocop/cop/lint/last_keyword_argument.rb10
-rw-r--r--rubocop/cop/migration/add_column_with_default.rb4
-rw-r--r--rubocop/cop/migration/add_columns_to_wide_tables.rb4
-rw-r--r--rubocop/cop/migration/add_concurrent_foreign_key.rb4
-rw-r--r--rubocop/cop/migration/add_concurrent_index.rb10
-rw-r--r--rubocop/cop/migration/add_index.rb4
-rw-r--r--rubocop/cop/migration/add_limit_to_text_columns.rb6
-rw-r--r--rubocop/cop/migration/add_reference.rb6
-rw-r--r--rubocop/cop/migration/add_timestamps.rb4
-rw-r--r--rubocop/cop/migration/background_migration_base_class.rb4
-rw-r--r--rubocop/cop/migration/background_migration_record.rb6
-rw-r--r--rubocop/cop/migration/background_migrations.rb4
-rw-r--r--rubocop/cop/migration/complex_indexes_require_name.rb4
-rw-r--r--rubocop/cop/migration/create_table_with_foreign_keys.rb2
-rw-r--r--rubocop/cop/migration/datetime.rb6
-rw-r--r--rubocop/cop/migration/drop_table.rb4
-rw-r--r--rubocop/cop/migration/migration_record.rb4
-rw-r--r--rubocop/cop/migration/prevent_global_enable_lock_retries_with_disable_ddl_transaction.rb2
-rw-r--r--rubocop/cop/migration/prevent_index_creation.rb4
-rw-r--r--rubocop/cop/migration/prevent_strings.rb4
-rw-r--r--rubocop/cop/migration/refer_to_index_by_name.rb4
-rw-r--r--rubocop/cop/migration/remove_column.rb4
-rw-r--r--rubocop/cop/migration/remove_concurrent_index.rb8
-rw-r--r--rubocop/cop/migration/remove_index.rb4
-rw-r--r--rubocop/cop/migration/safer_boolean_column.rb4
-rw-r--r--rubocop/cop/migration/schedule_async.rb4
-rw-r--r--rubocop/cop/migration/sidekiq_queue_migrate.rb4
-rw-r--r--rubocop/cop/migration/timestamps.rb4
-rw-r--r--rubocop/cop/migration/update_column_in_batches.rb8
-rw-r--r--rubocop/cop/migration/versioned_migration_class.rb6
-rw-r--r--rubocop/cop/migration/with_lock_retries_disallowed_method.rb6
-rw-r--r--rubocop/cop/migration/with_lock_retries_with_change.rb8
-rw-r--r--rubocop/cop/performance/active_record_subtransaction_methods.rb4
-rw-r--r--rubocop/cop/performance/active_record_subtransactions.rb2
-rw-r--r--rubocop/cop/performance/ar_count_each.rb4
-rw-r--r--rubocop/cop/performance/ar_exists_and_present_blank.rb6
-rw-r--r--rubocop/cop/performance/readlines_each.rb11
-rw-r--r--rubocop/cop/prefer_class_methods_over_module.rb14
-rw-r--r--rubocop/cop/project_path_helper.rb18
-rw-r--r--rubocop/cop/put_group_routes_under_scope.rb2
-rw-r--r--rubocop/cop/put_project_routes_under_scope.rb2
-rw-r--r--rubocop/cop/qa/ambiguous_page_object_name.rb2
-rw-r--r--rubocop/cop/qa/element_with_pattern.rb2
-rw-r--r--rubocop/cop/qa/selector_usage.rb2
-rw-r--r--rubocop/cop/rspec/any_instance_of.rb29
-rw-r--r--rubocop/cop/rspec/be_success_matcher.rb10
-rw-r--r--rubocop/cop/rspec/env_assignment.rb10
-rw-r--r--rubocop/cop/rspec/expect_gitlab_tracking.rb2
-rw-r--r--rubocop/cop/rspec/factories_in_migration_specs.rb4
-rw-r--r--rubocop/cop/rspec/factory_bot/inline_association.rb10
-rw-r--r--rubocop/cop/rspec/have_gitlab_http_status.rb22
-rw-r--r--rubocop/cop/rspec/httparty_basic_auth.rb12
-rw-r--r--rubocop/cop/rspec/modify_sidekiq_middleware.rb10
-rw-r--r--rubocop/cop/rspec/timecop_freeze.rb10
-rw-r--r--rubocop/cop/rspec/timecop_travel.rb10
-rw-r--r--rubocop/cop/rspec/web_mock_enable.rb14
-rw-r--r--rubocop/cop/ruby_interpolation_in_translation.rb2
-rw-r--r--rubocop/cop/safe_params.rb4
-rw-r--r--rubocop/cop/scalability/bulk_perform_with_context.rb4
-rw-r--r--rubocop/cop/scalability/cron_worker_context.rb4
-rw-r--r--rubocop/cop/scalability/file_uploads.rb4
-rw-r--r--rubocop/cop/scalability/idempotent_worker.rb4
-rw-r--r--rubocop/cop/sidekiq_load_balancing/worker_data_consistency.rb4
-rw-r--r--rubocop/cop/sidekiq_options_queue.rb4
-rw-r--r--rubocop/cop/static_translation_definition.rb2
-rw-r--r--rubocop/cop/usage_data/distinct_count_by_large_foreign_key.rb4
-rw-r--r--rubocop/cop/usage_data/histogram_with_large_table.rb8
-rw-r--r--rubocop/cop/usage_data/instrumentation_superclass.rb2
-rw-r--r--rubocop/cop/usage_data/large_table.rb4
-rw-r--r--rubocop/cop/user_admin.rb4
-rw-r--r--spec/config/object_store_settings_spec.rb69
-rw-r--r--spec/controllers/concerns/continue_params_spec.rb2
-rw-r--r--spec/frontend/releases/stores/modules/detail/actions_spec.js26
-rw-r--r--spec/graphql/mutations/releases/create_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb42
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/sequence_spec.rb39
-rw-r--r--spec/models/ci/pipeline_spec.rb42
-rw-r--r--spec/rubocop/code_reuse_helpers_spec.rb2
-rw-r--r--spec/rubocop/cop/active_model_errors_direct_manipulation_spec.rb2
-rw-r--r--spec/rubocop/cop/active_record_association_reload_spec.rb2
-rw-r--r--spec/rubocop/cop/api/base_spec.rb2
-rw-r--r--spec/rubocop/cop/api/grape_array_missing_coerce_spec.rb2
-rw-r--r--spec/rubocop/cop/avoid_becomes_spec.rb2
-rw-r--r--spec/rubocop/cop/avoid_break_from_strong_memoize_spec.rb2
-rw-r--r--spec/rubocop/cop/avoid_keyword_arguments_in_sidekiq_workers_spec.rb2
-rw-r--r--spec/rubocop/cop/avoid_return_from_blocks_spec.rb2
-rw-r--r--spec/rubocop/cop/avoid_route_redirect_leading_slash_spec.rb2
-rw-r--r--spec/rubocop/cop/ban_catch_throw_spec.rb2
-rw-r--r--spec/rubocop/cop/code_reuse/finder_spec.rb2
-rw-r--r--spec/rubocop/cop/code_reuse/presenter_spec.rb2
-rw-r--r--spec/rubocop/cop/code_reuse/serializer_spec.rb2
-rw-r--r--spec/rubocop/cop/code_reuse/service_class_spec.rb2
-rw-r--r--spec/rubocop/cop/code_reuse/worker_spec.rb2
-rw-r--r--spec/rubocop/cop/database/disable_referential_integrity_spec.rb2
-rw-r--r--spec/rubocop/cop/database/establish_connection_spec.rb2
-rw-r--r--spec/rubocop/cop/database/multiple_databases_spec.rb2
-rw-r--r--spec/rubocop/cop/database/rescue_query_canceled_spec.rb2
-rw-r--r--spec/rubocop/cop/database/rescue_statement_timeout_spec.rb2
-rw-r--r--spec/rubocop/cop/default_scope_spec.rb2
-rw-r--r--spec/rubocop/cop/destroy_all_spec.rb8
-rw-r--r--spec/rubocop/cop/file_decompression_spec.rb2
-rw-r--r--spec/rubocop/cop/filename_length_spec.rb2
-rw-r--r--spec/rubocop/cop/gemspec/avoid_executing_git_spec.rb2
-rw-r--r--spec/rubocop/cop/gitlab/avoid_feature_category_not_owned_spec.rb8
-rw-r--r--spec/rubocop/cop/gitlab/avoid_uploaded_file_from_params_spec.rb2
-rw-r--r--spec/rubocop/cop/gitlab/bulk_insert_spec.rb2
-rw-r--r--spec/rubocop/cop/gitlab/change_timezone_spec.rb2
-rw-r--r--spec/rubocop/cop/gitlab/const_get_inherit_false_spec.rb2
-rw-r--r--spec/rubocop/cop/gitlab/delegate_predicate_methods_spec.rb2
-rw-r--r--spec/rubocop/cop/gitlab/deprecate_track_redis_hll_event_spec.rb2
-rw-r--r--spec/rubocop/cop/gitlab/duplicate_spec_location_spec.rb2
-rw-r--r--spec/rubocop/cop/gitlab/event_store_subscriber_spec.rb2
-rw-r--r--spec/rubocop/cop/gitlab/except_spec.rb2
-rw-r--r--spec/rubocop/cop/gitlab/feature_available_usage_spec.rb2
-rw-r--r--spec/rubocop/cop/gitlab/finder_with_find_by_spec.rb2
-rw-r--r--spec/rubocop/cop/gitlab/httparty_spec.rb2
-rw-r--r--spec/rubocop/cop/gitlab/intersect_spec.rb2
-rw-r--r--spec/rubocop/cop/gitlab/json_spec.rb2
-rw-r--r--spec/rubocop/cop/gitlab/mark_used_feature_flags_spec.rb2
-rw-r--r--spec/rubocop/cop/gitlab/module_with_instance_variables_spec.rb2
-rw-r--r--spec/rubocop/cop/gitlab/namespaced_class_spec.rb2
-rw-r--r--spec/rubocop/cop/gitlab/policy_rule_boolean_spec.rb2
-rw-r--r--spec/rubocop/cop/gitlab/predicate_memoization_spec.rb2
-rw-r--r--spec/rubocop/cop/gitlab/rails_logger_spec.rb2
-rw-r--r--spec/rubocop/cop/gitlab/union_spec.rb2
-rw-r--r--spec/rubocop/cop/graphql/authorize_types_spec.rb2
-rw-r--r--spec/rubocop/cop/graphql/descriptions_spec.rb2
-rw-r--r--spec/rubocop/cop/graphql/gid_expected_type_spec.rb2
-rw-r--r--spec/rubocop/cop/graphql/graphql_name_position_spec.rb2
-rw-r--r--spec/rubocop/cop/graphql/id_type_spec.rb2
-rw-r--r--spec/rubocop/cop/graphql/json_type_spec.rb2
-rw-r--r--spec/rubocop/cop/graphql/old_types_spec.rb2
-rw-r--r--spec/rubocop/cop/graphql/resolver_type_spec.rb2
-rw-r--r--spec/rubocop/cop/group_public_or_visible_to_user_spec.rb2
-rw-r--r--spec/rubocop/cop/ignored_columns_spec.rb2
-rw-r--r--spec/rubocop/cop/include_sidekiq_worker_spec.rb2
-rw-r--r--spec/rubocop/cop/inject_enterprise_edition_module_spec.rb2
-rw-r--r--spec/rubocop/cop/lint/last_keyword_argument_spec.rb10
-rw-r--r--spec/rubocop/cop/migration/add_concurrent_index_spec.rb2
-rw-r--r--spec/rubocop/cop/migration/add_index_spec.rb2
-rw-r--r--spec/rubocop/cop/migration/add_limit_to_text_columns_spec.rb2
-rw-r--r--spec/rubocop/cop/migration/add_timestamps_spec.rb2
-rw-r--r--spec/rubocop/cop/migration/background_migration_base_class_spec.rb2
-rw-r--r--spec/rubocop/cop/migration/background_migration_record_spec.rb2
-rw-r--r--spec/rubocop/cop/migration/complex_indexes_require_name_spec.rb2
-rw-r--r--spec/rubocop/cop/migration/datetime_spec.rb2
-rw-r--r--spec/rubocop/cop/migration/drop_table_spec.rb2
-rw-r--r--spec/rubocop/cop/migration/migration_record_spec.rb2
-rw-r--r--spec/rubocop/cop/migration/prevent_global_enable_lock_retries_with_disable_ddl_transaction_spec.rb2
-rw-r--r--spec/rubocop/cop/migration/prevent_index_creation_spec.rb2
-rw-r--r--spec/rubocop/cop/migration/prevent_strings_spec.rb2
-rw-r--r--spec/rubocop/cop/migration/refer_to_index_by_name_spec.rb2
-rw-r--r--spec/rubocop/cop/migration/remove_column_spec.rb2
-rw-r--r--spec/rubocop/cop/migration/remove_concurrent_index_spec.rb2
-rw-r--r--spec/rubocop/cop/migration/remove_index_spec.rb2
-rw-r--r--spec/rubocop/cop/migration/safer_boolean_column_spec.rb2
-rw-r--r--spec/rubocop/cop/migration/sidekiq_queue_migrate_spec.rb2
-rw-r--r--spec/rubocop/cop/migration/timestamps_spec.rb2
-rw-r--r--spec/rubocop/cop/migration/versioned_migration_class_spec.rb2
-rw-r--r--spec/rubocop/cop/migration/with_lock_retries_disallowed_method_spec.rb2
-rw-r--r--spec/rubocop/cop/migration/with_lock_retries_with_change_spec.rb2
-rw-r--r--spec/rubocop/cop/performance/active_record_subtransaction_methods_spec.rb2
-rw-r--r--spec/rubocop/cop/performance/active_record_subtransactions_spec.rb2
-rw-r--r--spec/rubocop/cop/performance/ar_count_each_spec.rb6
-rw-r--r--spec/rubocop/cop/performance/ar_exists_and_present_blank_spec.rb6
-rw-r--r--spec/rubocop/cop/performance/readlines_each_spec.rb2
-rw-r--r--spec/rubocop/cop/prefer_class_methods_over_module_spec.rb2
-rw-r--r--spec/rubocop/cop/project_path_helper_spec.rb2
-rw-r--r--spec/rubocop/cop/put_group_routes_under_scope_spec.rb2
-rw-r--r--spec/rubocop/cop/put_project_routes_under_scope_spec.rb2
-rw-r--r--spec/rubocop/cop/qa/ambiguous_page_object_name_spec.rb2
-rw-r--r--spec/rubocop/cop/qa/element_with_pattern_spec.rb2
-rw-r--r--spec/rubocop/cop/qa/selector_usage_spec.rb2
-rw-r--r--spec/rubocop/cop/rspec/any_instance_of_spec.rb2
-rw-r--r--spec/rubocop/cop/rspec/be_success_matcher_spec.rb2
-rw-r--r--spec/rubocop/cop/rspec/env_assignment_spec.rb2
-rw-r--r--spec/rubocop/cop/rspec/expect_gitlab_tracking_spec.rb2
-rw-r--r--spec/rubocop/cop/rspec/factories_in_migration_specs_spec.rb2
-rw-r--r--spec/rubocop/cop/rspec/factory_bot/inline_association_spec.rb2
-rw-r--r--spec/rubocop/cop/rspec/have_gitlab_http_status_spec.rb2
-rw-r--r--spec/rubocop/cop/rspec/htt_party_basic_auth_spec.rb2
-rw-r--r--spec/rubocop/cop/rspec/modify_sidekiq_middleware_spec.rb2
-rw-r--r--spec/rubocop/cop/rspec/timecop_freeze_spec.rb2
-rw-r--r--spec/rubocop/cop/rspec/timecop_travel_spec.rb2
-rw-r--r--spec/rubocop/cop/rspec/top_level_describe_path_spec.rb2
-rw-r--r--spec/rubocop/cop/rspec/web_mock_enable_spec.rb2
-rw-r--r--spec/rubocop/cop/ruby_interpolation_in_translation_spec.rb2
-rw-r--r--spec/rubocop/cop/safe_params_spec.rb2
-rw-r--r--spec/rubocop/cop/scalability/bulk_perform_with_context_spec.rb2
-rw-r--r--spec/rubocop/cop/scalability/cron_worker_context_spec.rb2
-rw-r--r--spec/rubocop/cop/scalability/file_uploads_spec.rb2
-rw-r--r--spec/rubocop/cop/scalability/idempotent_worker_spec.rb2
-rw-r--r--spec/rubocop/cop/sidekiq_load_balancing/worker_data_consistency_spec.rb2
-rw-r--r--spec/rubocop/cop/sidekiq_options_queue_spec.rb2
-rw-r--r--spec/rubocop/cop/static_translation_definition_spec.rb2
-rw-r--r--spec/rubocop/cop/usage_data/distinct_count_by_large_foreign_key_spec.rb2
-rw-r--r--spec/rubocop/cop/usage_data/histogram_with_large_table_spec.rb2
-rw-r--r--spec/rubocop/cop/usage_data/instrumentation_superclass_spec.rb2
-rw-r--r--spec/rubocop/cop/usage_data/large_table_spec.rb2
-rw-r--r--spec/rubocop/cop/user_admin_spec.rb2
-rw-r--r--spec/rubocop_spec_helper.rb3
-rw-r--r--spec/services/releases/create_service_spec.rb22
-rw-r--r--spec/spec_helper.rb3
-rw-r--r--spec/support/rspec.rb3
-rw-r--r--vendor/gems/omniauth-azure-oauth2/Gemfile.lock13
-rw-r--r--vendor/gems/omniauth-azure-oauth2/lib/omniauth/strategies/azure_oauth2.rb4
-rw-r--r--vendor/gems/omniauth-azure-oauth2/omniauth-azure-oauth2.gemspec2
-rw-r--r--vendor/gems/omniauth-cas3/Gemfile.lock21
-rw-r--r--vendor/gems/omniauth-cas3/omniauth-cas3.gemspec2
-rw-r--r--vendor/gems/omniauth-gitlab/Gemfile.lock11
-rw-r--r--vendor/gems/omniauth-gitlab/omniauth-gitlab.gemspec2
-rw-r--r--vendor/gems/omniauth-google-oauth2/CHANGELOG.md101
-rw-r--r--vendor/gems/omniauth-google-oauth2/Gemfile.lock14
-rw-r--r--vendor/gems/omniauth-google-oauth2/README.md90
-rw-r--r--vendor/gems/omniauth-google-oauth2/examples/Gemfile3
-rw-r--r--vendor/gems/omniauth-google-oauth2/examples/omni_auth.rb4
-rw-r--r--vendor/gems/omniauth-google-oauth2/lib/omniauth/google_oauth2/version.rb2
-rw-r--r--vendor/gems/omniauth-google-oauth2/lib/omniauth/strategies/google_oauth2.rb86
-rw-r--r--vendor/gems/omniauth-google-oauth2/omniauth-google-oauth2.gemspec9
-rw-r--r--vendor/gems/omniauth-google-oauth2/spec/omniauth/strategies/google_oauth2_spec.rb170
-rw-r--r--vendor/gems/omniauth-salesforce/Gemfile.lock15
-rwxr-xr-xvendor/gems/omniauth-salesforce/omniauth-salesforce.gemspec2
-rw-r--r--vendor/gems/omniauth_crowd/Gemfile.lock9
-rw-r--r--vendor/gems/omniauth_crowd/omniauth_crowd.gemspec2
370 files changed, 7555 insertions, 1595 deletions
diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS
index bc01f80007c..c57c2965101 100644
--- a/.gitlab/CODEOWNERS
+++ b/.gitlab/CODEOWNERS
@@ -11,7 +11,9 @@ docs/CODEOWNERS @clefelhocz1 @timzallmann @cdu1 @whaber @dsatcher @sgoldstein @j
## Allows release tooling to update the Gitaly Version
GITALY_SERVER_VERSION @project_278964_bot6 @gitlab-org/maintainers/rails-backend @gitlab-org/delivery
-## Excludes documentation files and deprecation/removal announcements from required approval
+## Files that are excluded from required approval
+/.gitlab/issue_templates/
+/.gitlab/merge_request_templates/
/doc/*.md
/doc/**/*.md
/doc/**/*.png
@@ -332,8 +334,8 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
^[Documentation Directories]
.markdownlint.yml @marcel.amirault @eread @aqualls @dianalogan @kpaizee
-/doc/.markdownlint @marcel.amirault @eread @aqualls @dianalogan @kpaizee
/doc/ @gl-docsteam
+/doc/.markdownlint/ @marcel.amirault @eread @aqualls @dianalogan @kpaizee
/doc/.vale/ @marcel.amirault @eread @aqualls @dianalogan @kpaizee
^[Documentation Pages]
diff --git a/.rubocop_todo/rails/application_controller.yml b/.rubocop_todo/rails/application_controller.yml
deleted file mode 100644
index d53fd3411d3..00000000000
--- a/.rubocop_todo/rails/application_controller.yml
+++ /dev/null
@@ -1,13 +0,0 @@
----
-# Cop supports --auto-correct.
-Rails/ApplicationController:
- Exclude:
- - 'app/controllers/acme_challenges_controller.rb'
- - 'app/controllers/chaos_controller.rb'
- - 'app/controllers/health_controller.rb'
- - 'app/controllers/metrics_controller.rb'
- - 'ee/app/controllers/oauth/geo_auth_controller.rb'
- - 'ee/spec/helpers/ee/integrations_helper_spec.rb'
- - 'lib/gitlab/base_doorkeeper_controller.rb'
- - 'lib/gitlab/request_forgery_protection.rb'
- - 'spec/controllers/concerns/continue_params_spec.rb'
diff --git a/Gemfile b/Gemfile
index f5e43a5493b..c2e8019a26b 100644
--- a/Gemfile
+++ b/Gemfile
@@ -36,8 +36,7 @@ gem 'doorkeeper', '~> 5.5.0.rc2'
gem 'doorkeeper-openid_connect', '~> 1.7.5'
gem 'rexml', '~> 3.2.5'
gem 'ruby-saml', '~> 1.13.0'
-gem 'omniauth-rails_csrf_protection'
-gem 'omniauth', '~> 2.1.0'
+gem 'omniauth', '~> 1.8'
gem 'omniauth-auth0', '~> 2.0.0'
gem 'omniauth-azure-activedirectory-v2', '~> 1.0'
gem 'omniauth-azure-oauth2', '~> 0.0.9', path: 'vendor/gems/omniauth-azure-oauth2' # See gem README.md
@@ -45,16 +44,16 @@ gem 'omniauth-cas3', '~> 1.1.4', path: 'vendor/gems/omniauth-cas3' # See vendor/
gem 'omniauth-dingtalk-oauth2', '~> 1.0'
gem 'omniauth-alicloud', '~> 1.0.1'
gem 'omniauth-facebook', '~> 4.0.0'
-gem 'omniauth-github', '2.0.0'
+gem 'omniauth-github', '~> 1.4'
gem 'omniauth-gitlab', '~> 4.0.0', path: 'vendor/gems/omniauth-gitlab' # See vendor/gems/omniauth-gitlab/README.md
-gem 'omniauth-google-oauth2', '~> 1.0.1', path: 'vendor/gems/omniauth-google-oauth2' # See gem README.md
+gem 'omniauth-google-oauth2', '~> 0.6.0', path: 'vendor/gems/omniauth-google-oauth2' # See gem README.md
gem 'omniauth-oauth2-generic', '~> 0.2.2'
-gem 'omniauth-saml', '~> 2.1.0'
+gem 'omniauth-saml', '~> 1.10'
gem 'omniauth-shibboleth', '~> 1.3.0'
gem 'omniauth-twitter', '~> 1.4'
gem 'omniauth_crowd', '~> 2.4.0', path: 'vendor/gems/omniauth_crowd' # See vendor/gems/omniauth_crowd/README.md
gem 'omniauth-authentiq', '~> 0.3.3'
-gem 'gitlab-omniauth-openid-connect', '~> 0.10.0', require: 'omniauth_openid_connect'
+gem 'gitlab-omniauth-openid-connect', '~> 0.9.0', require: 'omniauth_openid_connect'
gem 'omniauth-salesforce', '~> 1.0.5', path: 'vendor/gems/omniauth-salesforce' # See gem README.md
gem 'omniauth-atlassian-oauth2', '~> 0.2.0'
gem 'rack-oauth2', '~> 1.21.2'
diff --git a/Gemfile.lock b/Gemfile.lock
index 6178c733c8f..74a89c79d5e 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -29,7 +29,7 @@ PATH
specs:
omniauth-azure-oauth2 (0.0.10)
jwt (>= 1.0, < 3.0)
- omniauth (~> 2.0)
+ omniauth (~> 1.0, < 3)
omniauth-oauth2 (~> 1.4)
PATH
@@ -38,29 +38,28 @@ PATH
omniauth-cas3 (1.1.4)
addressable (~> 2.3)
nokogiri (~> 1.7, >= 1.7.1)
- omniauth (~> 2.0)
+ omniauth (~> 1.2, < 3)
PATH
remote: vendor/gems/omniauth-gitlab
specs:
omniauth-gitlab (4.0.0)
- omniauth (~> 2.0)
+ omniauth (~> 1.0)
omniauth-oauth2 (~> 1.7.1)
PATH
remote: vendor/gems/omniauth-google-oauth2
specs:
- omniauth-google-oauth2 (1.0.1)
+ omniauth-google-oauth2 (0.6.0)
jwt (>= 2.0)
- oauth2 (~> 2.0)
- omniauth (~> 2.0)
- omniauth-oauth2 (~> 1.7.1)
+ omniauth (>= 1.9, < 3)
+ omniauth-oauth2 (>= 1.5)
PATH
remote: vendor/gems/omniauth-salesforce
specs:
omniauth-salesforce (1.0.5)
- omniauth (~> 2.0)
+ omniauth (~> 1.0, < 3)
omniauth-oauth2 (~> 1.0)
PATH
@@ -69,7 +68,7 @@ PATH
omniauth_crowd (2.4.0)
activesupport
nokogiri (>= 1.4.4)
- omniauth (~> 2.0)
+ omniauth (~> 1.0, < 3)
GEM
remote: https://rubygems.org/
@@ -566,9 +565,9 @@ GEM
gitlab-mail_room (0.0.9)
gitlab-markup (1.8.0)
gitlab-net-dns (0.9.1)
- gitlab-omniauth-openid-connect (0.10.0)
+ gitlab-omniauth-openid-connect (0.9.1)
addressable (~> 2.7)
- omniauth (>= 1.9, < 3)
+ omniauth (~> 1.9)
openid_connect (~> 1.2)
gitlab-sidekiq-fetcher (0.8.0)
sidekiq (~> 6.1)
@@ -914,10 +913,9 @@ GEM
train-core
wmi-lite (~> 1.0)
oj (3.13.21)
- omniauth (2.1.0)
+ omniauth (1.9.1)
hashie (>= 3.4.6)
- rack (>= 2.2.3)
- rack-protection
+ rack (>= 1.6.2, < 3)
omniauth-alicloud (1.0.1)
omniauth-oauth2 (~> 1.7.1)
omniauth-atlassian-oauth2 (0.2.0)
@@ -934,9 +932,9 @@ GEM
omniauth-oauth2 (~> 1.7)
omniauth-facebook (4.0.0)
omniauth-oauth2 (~> 1.2)
- omniauth-github (2.0.0)
- omniauth (~> 2.0)
- omniauth-oauth2 (~> 1.7.1)
+ omniauth-github (1.4.0)
+ omniauth (~> 1.5)
+ omniauth-oauth2 (>= 1.4.0, < 2.0)
omniauth-oauth (1.2.0)
oauth
omniauth (>= 1.0, < 3)
@@ -945,12 +943,9 @@ GEM
omniauth (>= 1.9, < 3)
omniauth-oauth2-generic (0.2.2)
omniauth-oauth2 (~> 1.0)
- omniauth-rails_csrf_protection (1.0.1)
- actionpack (>= 4.2)
- omniauth (~> 2.0)
- omniauth-saml (2.1.0)
- omniauth (~> 2.0)
- ruby-saml (~> 1.12)
+ omniauth-saml (1.10.0)
+ omniauth (~> 1.3, >= 1.3.2)
+ ruby-saml (~> 1.7)
omniauth-shibboleth (1.3.0)
omniauth (>= 1.0.0)
omniauth-twitter (1.4.0)
@@ -1059,8 +1054,6 @@ GEM
httpclient
json-jwt (>= 1.11.0)
rack (>= 2.1.0)
- rack-protection (2.2.2)
- rack
rack-proxy (0.7.2)
rack
rack-test (1.1.0)
@@ -1453,7 +1446,7 @@ GEM
validate_email (0.1.6)
activemodel (>= 3.0)
mail (>= 2.2.5)
- validate_url (1.0.15)
+ validate_url (1.0.13)
activemodel (>= 3.0.0)
public_suffix
validates_hostname (1.0.11)
@@ -1606,7 +1599,7 @@ DEPENDENCIES
gitlab-mail_room (~> 0.0.9)
gitlab-markup (~> 1.8.0)
gitlab-net-dns (~> 0.9.1)
- gitlab-omniauth-openid-connect (~> 0.10.0)
+ gitlab-omniauth-openid-connect (~> 0.9.0)
gitlab-sidekiq-fetcher (= 0.8.0)
gitlab-styles (~> 8.0.0)
gitlab_chronic_duration (~> 0.10.6.2)
@@ -1673,7 +1666,7 @@ DEPENDENCIES
octokit (~> 4.15)
ohai (~> 16.10)
oj (~> 3.13.21)
- omniauth (~> 2.1.0)
+ omniauth (~> 1.8)
omniauth-alicloud (~> 1.0.1)
omniauth-atlassian-oauth2 (~> 0.2.0)
omniauth-auth0 (~> 2.0.0)
@@ -1683,13 +1676,12 @@ DEPENDENCIES
omniauth-cas3 (~> 1.1.4)!
omniauth-dingtalk-oauth2 (~> 1.0)
omniauth-facebook (~> 4.0.0)
- omniauth-github (= 2.0.0)
+ omniauth-github (~> 1.4)
omniauth-gitlab (~> 4.0.0)!
- omniauth-google-oauth2 (~> 1.0.1)!
+ omniauth-google-oauth2 (~> 0.6.0)!
omniauth-oauth2-generic (~> 0.2.2)
- omniauth-rails_csrf_protection
omniauth-salesforce (~> 1.0.5)!
- omniauth-saml (~> 2.1.0)
+ omniauth-saml (~> 1.10)
omniauth-shibboleth (~> 1.3.0)
omniauth-twitter (~> 1.4)
omniauth_crowd (~> 2.4.0)!
diff --git a/app/assets/javascripts/releases/stores/modules/edit_new/actions.js b/app/assets/javascripts/releases/stores/modules/edit_new/actions.js
index a71a8125d65..669e5928143 100644
--- a/app/assets/javascripts/releases/stores/modules/edit_new/actions.js
+++ b/app/assets/javascripts/releases/stores/modules/edit_new/actions.js
@@ -16,6 +16,8 @@ import {
import * as types from './mutation_types';
+class GraphQLError extends Error {}
+
export const initializeRelease = ({ commit, dispatch, state }) => {
if (state.isExistingRelease) {
// When editing an existing release,
@@ -110,35 +112,35 @@ export const saveRelease = ({ commit, dispatch, state }) => {
*
* @param {Object} gqlResponse The response object returned by the GraphQL client
* @param {String} mutationName The name of the mutation that was executed
- * @param {String} messageIfError An message to build into the error object if something went wrong
*/
-const checkForErrorsAsData = (gqlResponse, mutationName, messageIfError) => {
+const checkForErrorsAsData = (gqlResponse, mutationName) => {
const allErrors = gqlResponse.data[mutationName].errors;
if (allErrors.length > 0) {
- const allErrorMessages = JSON.stringify(allErrors);
- throw new Error(`${messageIfError}: ${allErrorMessages}`);
+ throw new GraphQLError(allErrors[0]);
}
};
-export const createRelease = async ({ commit, dispatch, state, getters }) => {
+export const createRelease = async ({ commit, dispatch, getters }) => {
try {
const response = await gqClient.mutate({
mutation: createReleaseMutation,
variables: getters.releaseCreateMutatationVariables,
});
- checkForErrorsAsData(
- response,
- 'releaseCreate',
- `Something went wrong while creating a new release with projectPath "${state.projectPath}" and tagName "${state.release.tagName}"`,
- );
+ checkForErrorsAsData(response, 'releaseCreate');
dispatch('receiveSaveReleaseSuccess', response.data.releaseCreate.release.links.selfUrl);
} catch (error) {
commit(types.RECEIVE_SAVE_RELEASE_ERROR, error);
- createFlash({
- message: s__('Release|Something went wrong while creating a new release.'),
- });
+ if (error instanceof GraphQLError) {
+ createFlash({
+ message: error.message,
+ });
+ } else {
+ createFlash({
+ message: s__('Release|Something went wrong while creating a new release.'),
+ });
+ }
}
};
@@ -146,7 +148,7 @@ export const createRelease = async ({ commit, dispatch, state, getters }) => {
* Deletes a single release link.
* Throws an error if any network or validation errors occur.
*/
-const deleteReleaseLinks = async ({ state, id }) => {
+const deleteReleaseLinks = async ({ id }) => {
const deleteResponse = await gqClient.mutate({
mutation: deleteReleaseAssetLinkMutation,
variables: {
@@ -154,11 +156,7 @@ const deleteReleaseLinks = async ({ state, id }) => {
},
});
- checkForErrorsAsData(
- deleteResponse,
- 'releaseAssetLinkDelete',
- `Something went wrong while deleting release asset link for release with projectPath "${state.projectPath}", tagName "${state.tagName}", and link id "${id}"`,
- );
+ checkForErrorsAsData(deleteResponse, 'releaseAssetLinkDelete');
};
/**
@@ -180,11 +178,7 @@ const createReleaseLink = async ({ state, link }) => {
},
});
- checkForErrorsAsData(
- createResponse,
- 'releaseAssetLinkCreate',
- `Something went wrong while creating a release asset link for release with projectPath "${state.projectPath}" and tagName "${state.tagName}"`,
- );
+ checkForErrorsAsData(createResponse, 'releaseAssetLinkCreate');
};
export const updateRelease = async ({ commit, dispatch, state, getters }) => {
@@ -210,11 +204,7 @@ export const updateRelease = async ({ commit, dispatch, state, getters }) => {
variables: getters.releaseUpdateMutatationVariables,
});
- checkForErrorsAsData(
- updateReleaseResponse,
- 'releaseUpdate',
- `Something went wrong while updating release with projectPath "${state.projectPath}" and tagName "${state.tagName}"`,
- );
+ checkForErrorsAsData(updateReleaseResponse, 'releaseUpdate');
// Delete all links currently associated with this Release
await Promise.all(
@@ -266,7 +256,7 @@ export const deleteRelease = ({ commit, getters, dispatch, state }) => {
mutation: deleteReleaseMutation,
variables: getters.releaseDeleteMutationVariables,
})
- .then((response) => checkForErrorsAsData(response, 'releaseDelete', ''))
+ .then((response) => checkForErrorsAsData(response, 'releaseDelete'))
.then(() => {
window.sessionStorage.setItem(
deleteReleaseSessionKey(state.projectPath),
diff --git a/app/assets/stylesheets/_page_specific_files.scss b/app/assets/stylesheets/_page_specific_files.scss
index d0b3f5bda8e..9e81e1d4771 100644
--- a/app/assets/stylesheets/_page_specific_files.scss
+++ b/app/assets/stylesheets/_page_specific_files.scss
@@ -4,7 +4,6 @@
@import './pages/commits';
@import './pages/deploy_keys';
@import './pages/detail_page';
-@import './pages/editor';
@import './pages/environment_logs';
@import './pages/events';
@import './pages/groups';
diff --git a/app/assets/stylesheets/framework/files.scss b/app/assets/stylesheets/framework/files.scss
index cba8f48071b..07516275e58 100644
--- a/app/assets/stylesheets/framework/files.scss
+++ b/app/assets/stylesheets/framework/files.scss
@@ -39,8 +39,8 @@
.file-title {
position: relative;
- background-color: $gray-light;
- border-bottom: 1px solid $border-color;
+ background-color: var(--gray-10, $gray-10);
+ border-bottom: 1px solid var(--border-color, $border-color);
margin: 0;
text-align: left;
padding: 10px $gl-padding;
diff --git a/app/assets/stylesheets/pages/editor.scss b/app/assets/stylesheets/page_bundles/editor.scss
index c177d0b74a2..b7b698b2128 100644
--- a/app/assets/stylesheets/pages/editor.scss
+++ b/app/assets/stylesheets/page_bundles/editor.scss
@@ -1,11 +1,13 @@
+@import 'page_bundles/mixins_and_variables_and_functions';
+
.file-editor {
.nav-links {
- border-top: 1px solid $border-color;
- border-right: 1px solid $border-color;
- border-left: 1px solid $border-color;
+ border-top: 1px solid var(--border-color, $border-color);
+ border-right: 1px solid var(--border-color, $border-color);
+ border-left: 1px solid var(--border-color, $border-color);
border-bottom: 0;
border-radius: $border-radius-small $border-radius-small 0 0;
- background: $gray-normal;
+ background: var(--gray-50, $gray-50);
}
#editor,
@@ -23,10 +25,6 @@
}
}
- .ace_gutter-cell {
- background-color: $gray-light;
- }
-
.cancel-btn {
color: $red-600;
@@ -40,9 +38,9 @@
}
.editor-ref {
- background: $gray-light;
+ background: var(--gray-10, $gray-10);
padding-right: $gl-padding;
- border-right: 1px solid $border-color;
+ border-right: 1px solid var(--border-color, $border-color);
display: block;
float: left;
margin-right: 10px;
diff --git a/app/assets/stylesheets/utilities.scss b/app/assets/stylesheets/utilities.scss
index 6cc4d166af7..e5b6c9811b5 100644
--- a/app/assets/stylesheets/utilities.scss
+++ b/app/assets/stylesheets/utilities.scss
@@ -383,3 +383,13 @@ to @gitlab/ui by https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1709
.gl-flex-flow-row-wrap {
flex-flow: row wrap;
}
+
+/*
+ * The below style will be moved to @gitlab/ui by
+ * https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1963
+ */
+.gl-gap-y-3 {
+ > * + * {
+ margin-top: $gl-spacing-scale-3;
+ }
+}
diff --git a/app/controllers/acme_challenges_controller.rb b/app/controllers/acme_challenges_controller.rb
index 67a39d8870b..4a7706db94e 100644
--- a/app/controllers/acme_challenges_controller.rb
+++ b/app/controllers/acme_challenges_controller.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
+# rubocop:disable Rails/ApplicationController
class AcmeChallengesController < ActionController::Base
def show
if acme_order
@@ -15,3 +16,4 @@ class AcmeChallengesController < ActionController::Base
@acme_order ||= PagesDomainAcmeOrder.find_by_domain_and_token(params[:domain], params[:token])
end
end
+# rubocop:enable Rails/ApplicationController
diff --git a/app/controllers/chaos_controller.rb b/app/controllers/chaos_controller.rb
index 4e5af1945a4..6139168d29f 100644
--- a/app/controllers/chaos_controller.rb
+++ b/app/controllers/chaos_controller.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
+# rubocop:disable Rails/ApplicationController
class ChaosController < ActionController::Base
before_action :validate_chaos_secret, unless: :development_or_test?
@@ -93,3 +94,4 @@ class ChaosController < ActionController::Base
Rails.env.development? || Rails.env.test?
end
end
+# rubocop:enable Rails/ApplicationController
diff --git a/app/controllers/health_controller.rb b/app/controllers/health_controller.rb
index 0e74ac420b4..5fac7c0d663 100644
--- a/app/controllers/health_controller.rb
+++ b/app/controllers/health_controller.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
+# rubocop:disable Rails/ApplicationController
class HealthController < ActionController::Base
protect_from_forgery with: :exception, prepend: true
include RequiresWhitelistedMonitoringClient
@@ -39,3 +40,4 @@ class HealthController < ActionController::Base
render json: result.json, status: result.http_status
end
end
+# rubocop:enable Rails/ApplicationController
diff --git a/app/controllers/metrics_controller.rb b/app/controllers/metrics_controller.rb
index a0c307a0a03..bfd6181a940 100644
--- a/app/controllers/metrics_controller.rb
+++ b/app/controllers/metrics_controller.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
+# rubocop:disable Rails/ApplicationController
class MetricsController < ActionController::Base
include RequiresWhitelistedMonitoringClient
@@ -34,3 +35,4 @@ class MetricsController < ActionController::Base
)
end
end
+# rubocop:enable Rails/ApplicationController
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index 3a3e5f65c9b..f0568f33b1f 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -428,6 +428,10 @@ module Ci
end
def self.jobs_count_in_alive_pipelines
+ created_after(24.hours.ago).alive.joins(:statuses).count
+ end
+
+ def self.builds_count_in_alive_pipelines
created_after(24.hours.ago).alive.joins(:builds).count
end
diff --git a/app/services/releases/create_service.rb b/app/services/releases/create_service.rb
index 2588d2187a5..b7df201824a 100644
--- a/app/services/releases/create_service.rb
+++ b/app/services/releases/create_service.rb
@@ -4,6 +4,7 @@ module Releases
class CreateService < Releases::BaseService
def execute
return error('Access Denied', 403) unless allowed?
+ return error('You are not allowed to create this tag as it is protected.', 403) unless can_create_tag?
return error('Release already exists', 409) if release
return error("Milestone(s) not found: #{inexistent_milestones.join(', ')}", 400) if inexistent_milestones.any?
@@ -38,7 +39,7 @@ module Releases
end
def allowed?
- Ability.allowed?(current_user, :create_release, project) && can_create_tag?
+ Ability.allowed?(current_user, :create_release, project)
end
def can_create_tag?
diff --git a/app/views/notify/remote_mirror_update_failed_email.html.haml b/app/views/notify/remote_mirror_update_failed_email.html.haml
index 4fb0a4c5a8a..db95398d2d6 100644
--- a/app/views/notify/remote_mirror_update_failed_email.html.haml
+++ b/app/views/notify/remote_mirror_update_failed_email.html.haml
@@ -6,7 +6,7 @@
%td{ style: "vertical-align:middle;color:#ffffff;text-align:center;padding-right:5px;line-height:1;" }
%img{ alt: "✖", height: "13", src: image_url('mailers/ci_pipeline_notif_v1/icon-x-red-inverted.gif'), style: "display:block;", width: "13" }/
%td{ style: "vertical-align:middle;color:#ffffff;text-align:center;" }
- A remote mirror update has failed.
+ = s_('Notify|A remote mirror update has failed.')
%tr.spacer{ style: "font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif;" }
%td{ style: "height:18px;font-size:18px;line-height:18px;" }
&nbsp;
@@ -15,7 +15,8 @@
%table.table-info{ border: "0", cellpadding: "0", cellspacing: "0", style: "width:100%;" }
%tbody{ style: "font-size:15px;line-height:1.4;color:#8c8c8c;" }
%tr
- %td{ style: "font-weight:300;padding:14px 0;margin:0;" } Project
+ %td{ style: "font-weight:300;padding:14px 0;margin:0;" }
+ = _('Project')
%td{ style: "font-weight:500;padding:14px 0;margin:0;color:#333333;width:75%;padding-left:5px;" }
- namespace_url = @project.group ? group_url(@project.group) : user_url(@project.namespace.owner)
%a.muted{ href: namespace_url, style: "color:#333333;text-decoration:none;" }
@@ -24,17 +25,20 @@
%a.muted{ href: project_url(@project), style: "color:#333333;text-decoration:none;" }
= @project.name
%tr
- %td{ style: "font-weight:300;padding:14px 0;margin:0;border-top:1px solid #ededed;" } Remote mirror
+ %td{ style: "font-weight:300;padding:14px 0;margin:0;border-top:1px solid #ededed;" }
+ = s_('Notify|Remote mirror')
%td{ style: "font-weight:500;padding:14px 0;margin:0;color:#333333;width:75%;padding-left:5px;border-top:1px solid #ededed;" }
= @remote_mirror.safe_url
%tr
- %td{ style: "font-weight:300;padding:14px 0;margin:0;border-top:1px solid #ededed;" } Last update at
- %td{ style: "font-weight:500;padding:14px 0;margin:0;color:#333333;width:75%;padding-left:5px;border-top:1px solid #ededed;" }
- = @remote_mirror.last_update_at
+ - update_at_start = '<td style="font-weight:300;padding:14px 0;margin:0;border-top:1px solid #ededed;">'.html_safe
+ - update_at_mid = '</td><td style="font-weight:500;padding:14px 0;margin:0;color:#333333;width:75%;padding-left:5px;border-top:1px solid #ededed;">'.html_safe
+ - update_at_end = '</td>'.html_safe
+ = html_escape(s_('Notify|%{update_at_start} Last update at %{update_at_mid} %{last_update_at} %{update_at_end}')) % {update_at_start: update_at_start, update_at_mid: update_at_mid, last_update_at: @remote_mirror.last_update_at, update_at_end: update_at_end}
+
%tr.table-warning{ style: "font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif;" }
%td{ style: "border: 1px solid #ededed; border-bottom: 0; border-radius: 4px 4px 0 0; overflow: hidden; background-color: #fdf4f6; color: #d22852; font-size: 14px; line-height: 1.4; text-align: center; padding: 8px 16px;" }
- Logs may contain sensitive data. Please consider before forwarding this email.
+ = s_('Notify|Logs may contain sensitive data. Please consider before forwarding this email.')
%tr.section{ style: "font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif;" }
%td{ style: "padding: 0 16px; border: 1px solid #ededed; border-radius: 4px; overflow: hidden; border-top: 0; border-radius: 0 0 4px 4px;" }
%table.builds{ border: "0", cellpadding: "0", cellspacing: "0", style: "width: 100%; border-collapse: collapse;" }
diff --git a/app/views/notify/removed_milestone_merge_request_email.html.haml b/app/views/notify/removed_milestone_merge_request_email.html.haml
index 7e9205b6491..f411ea23832 100644
--- a/app/views/notify/removed_milestone_merge_request_email.html.haml
+++ b/app/views/notify/removed_milestone_merge_request_email.html.haml
@@ -1,2 +1,2 @@
%p
- Milestone removed
+ = s_('Notify|Milestone removed')
diff --git a/app/views/projects/blob/edit.html.haml b/app/views/projects/blob/edit.html.haml
index 220319d31b5..528999f5c89 100644
--- a/app/views/projects/blob/edit.html.haml
+++ b/app/views/projects/blob/edit.html.haml
@@ -2,6 +2,7 @@
- page_title _("Edit"), @blob.path, @ref
- content_for :prefetch_asset_tags do
- webpack_preload_asset_tag('monaco')
+- add_page_specific_style 'page_bundles/editor'
- if @conflict
= render Pajamas::AlertComponent.new(alert_options: { class: 'gl-mb-5 gl-mt-5' },
diff --git a/app/views/projects/blob/new.html.haml b/app/views/projects/blob/new.html.haml
index 27f64104cf4..81b2715b228 100644
--- a/app/views/projects/blob/new.html.haml
+++ b/app/views/projects/blob/new.html.haml
@@ -1,5 +1,6 @@
- breadcrumb_title _("Repository")
- page_title _("New File"), @path.presence, @ref
+- add_page_specific_style 'page_bundles/editor'
%h1.page-title.blob-new-page-title.gl-font-size-h-display
= _('New file')
diff --git a/app/views/projects/ci/pipeline_editor/show.html.haml b/app/views/projects/ci/pipeline_editor/show.html.haml
index 18eac48d42a..bc352ff6c7d 100644
--- a/app/views/projects/ci/pipeline_editor/show.html.haml
+++ b/app/views/projects/ci/pipeline_editor/show.html.haml
@@ -1,4 +1,5 @@
- @force_fluid_layout = true
+- add_page_specific_style 'page_bundles/editor'
- add_page_specific_style 'page_bundles/pipelines'
- add_page_specific_style 'page_bundles/pipeline_editor'
diff --git a/config/application.rb b/config/application.rb
index c93c0ae1efe..03c8eadc4b0 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -264,6 +264,7 @@ module Gitlab
config.assets.precompile << "page_bundles/cycle_analytics.css"
config.assets.precompile << "page_bundles/dashboard_projects.css"
config.assets.precompile << "page_bundles/dev_ops_reports.css"
+ config.assets.precompile << "page_bundles/editor.css"
config.assets.precompile << "page_bundles/environments.css"
config.assets.precompile << "page_bundles/epics.css"
config.assets.precompile << "page_bundles/error_tracking_details.css"
diff --git a/config/feature_flags/development/ci_limit_active_jobs_early.yml b/config/feature_flags/development/ci_limit_active_jobs_early.yml
new file mode 100644
index 00000000000..b7dba0f81e9
--- /dev/null
+++ b/config/feature_flags/development/ci_limit_active_jobs_early.yml
@@ -0,0 +1,8 @@
+---
+name: ci_limit_active_jobs_early
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/97700
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/373284
+milestone: '15.4'
+type: development
+group: group::pipeline execution
+default_enabled: false
diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb
index 2454b5ea818..38bd1034b36 100644
--- a/config/initializers/omniauth.rb
+++ b/config/initializers/omniauth.rb
@@ -11,17 +11,6 @@ if Gitlab::Auth::Ldap::Config.enabled?
end
end
-module OmniAuth
- module Strategies
- class AzureActivedirectoryV2
- # override until https://github.com/RIPAGlobal/omniauth-azure-activedirectory-v2/pull/6 is merged
- def callback_url
- full_host + callback_path
- end
- end
- end
-end
-
OmniAuth.config.full_host = Gitlab::OmniauthInitializer.full_host
OmniAuth.config.allowed_request_methods = [:post]
diff --git a/config/object_store_settings.rb b/config/object_store_settings.rb
index 3280bc284ad..e55032d3987 100644
--- a/config/object_store_settings.rb
+++ b/config/object_store_settings.rb
@@ -16,10 +16,6 @@ class ObjectStoreSettings
# we don't need to raise an error in that case
ALLOWED_INCOMPLETE_TYPES = %w(pages).freeze
- # A fallback switch in case anyone gets a trouble with background upload removal
- # Epic: https://gitlab.com/groups/gitlab-com/gl-infra/-/epics/734
- LEGACY_BACKGROUND_UPLOADS_ENV = "GITLAB_LEGACY_BACKGROUND_UPLOADS"
-
attr_accessor :settings
# Legacy parser
@@ -30,13 +26,8 @@ class ObjectStoreSettings
object_store['remote_directory']
)
- if support_legacy_background_upload?(object_store_type)
- object_store['direct_upload'] = false
- object_store['background_upload'] = true
- else
- object_store['direct_upload'] = true
- object_store['background_upload'] = false
- end
+ object_store['direct_upload'] = true
+ object_store['background_upload'] = false
object_store['proxy_download'] = false if object_store['proxy_download'].nil?
object_store['storage_options'] ||= {}
@@ -46,10 +37,6 @@ class ObjectStoreSettings
object_store
end
- def self.support_legacy_background_upload?(object_store_type)
- ENV[LEGACY_BACKGROUND_UPLOADS_ENV].to_s.split(',').map(&:strip).include?(object_store_type)
- end
-
def self.split_bucket_prefix(bucket)
return [nil, nil] unless bucket.present?
diff --git a/data/removals/15_0/15-0-remove-background-upload-object-storage.yml b/data/removals/15_0/15-0-remove-background-upload-object-storage.yml
index 16aab3d14c2..dac96032359 100644
--- a/data/removals/15_0/15-0-remove-background-upload-object-storage.yml
+++ b/data/removals/15_0/15-0-remove-background-upload-object-storage.yml
@@ -43,9 +43,8 @@
gitlab_rails['env'] = { 'GITLAB_LEGACY_BACKGROUND_UPLOADS' => 'artifacts,external_diffs,lfs,uploads,packages,dependency_proxy,terraform_state,pages' }
```
- Prefixes will be supported officially in [GitLab 15.2](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91307).
- This workaround will be dropped, so we encourage migrating to consolidated object storage.
-
+ Support for prefixes was restored in GitLab 15.2 via [this MR](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91307).
+ Support for setting `GITLAB_LEGACY_BACKGROUND_UPLOADS` will be removed in GitLab 15.4.
stage: Enablement
tiers: [Core, Premium, Ultimate]
diff --git a/doc/operations/error_tracking.md b/doc/operations/error_tracking.md
index a42aa3c19b0..22e21c01fbd 100644
--- a/doc/operations/error_tracking.md
+++ b/doc/operations/error_tracking.md
@@ -46,7 +46,7 @@ least Maintainer [permissions](../user/permissions.md) to enable the Sentry inte
Make sure to give the token at least the following scopes: `project:read`, `event:read`, and
`event:write` (for resolving events).
1. In GitLab, enable error tracking:
- 1. On the top bar, select **Menu > Projects** and find your project.
+ 1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > Error Tracking**.
1. Select **Enable error tracking**.
1. In GitLab, ensure error tracking is active.
diff --git a/doc/operations/feature_flags.md b/doc/operations/feature_flags.md
index 9e7d452c259..0dccaa6bfe9 100644
--- a/doc/operations/feature_flags.md
+++ b/doc/operations/feature_flags.md
@@ -37,7 +37,7 @@ with GitLab, so it's up to developers to use a compatible client library and
To create and enable a feature flag:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Deployments > Feature Flags**.
1. Select **New feature flag**.
1. Enter a name that starts with a letter and contains only lowercase letters, digits, underscores (`_`),
@@ -180,7 +180,7 @@ For example:
To create a user list:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Deployments > Feature Flags**.
1. Select **View user lists**
1. Select **New user list**.
@@ -196,7 +196,7 @@ When viewing a list, you can rename it by selecting **Edit** (**{pencil}**).
To add users to a user list:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Deployments > Feature Flags**.
1. Select **Edit** (**{pencil}**) next to the list you want to add users to.
1. Select **Add Users**.
@@ -210,7 +210,7 @@ To add users to a user list:
To remove users from a user list:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Deployments > Feature Flags**.
1. Select **Edit** (**{pencil}**) next to the list you want to change.
1. Select **Remove** (**{remove}**) next to the ID you want to remove.
@@ -224,7 +224,7 @@ code so that you can clean it up when it's time to remove the feature flag.
To search for code references of a feature flag:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Deployments > Feature Flags**.
1. Edit the feature flag you want to remove.
1. Select **More actions** (**{ellipsis_v}**).
@@ -235,7 +235,7 @@ To search for code references of a feature flag:
In [GitLab 13.0 and earlier](https://gitlab.com/gitlab-org/gitlab/-/issues/8621),
to disable a feature flag for a specific environment:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Deployments > Feature Flags**.
1. For the feature flag you want to disable, select **Edit** (**{pencil}**).
1. To disable the flag:
@@ -250,7 +250,7 @@ to disable a feature flag for a specific environment:
To disable a feature flag for all environments:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Deployments > Feature Flags**.
1. For the feature flag you want to disable, slide the Status toggle to **Disabled**.
@@ -265,7 +265,7 @@ Then prepare your application with a client library.
To get the access credentials that your application needs to communicate with GitLab:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Deployments > Feature Flags**.
1. Select **Configure** to view the following:
- **API URL**: URL where the client (application) connects to get a list of feature flags.
diff --git a/doc/operations/incident_management/alerts.md b/doc/operations/incident_management/alerts.md
index a4b34807094..7e4223c0820 100644
--- a/doc/operations/incident_management/alerts.md
+++ b/doc/operations/incident_management/alerts.md
@@ -120,7 +120,7 @@ Prerequisite:
To view the logs for an alert:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > Alerts**.
1. Select the alert you want to view.
1. Below the title of the alert, select the **Metrics** tab.
@@ -198,7 +198,7 @@ To assign an alert:
1. Display the list of current alerts:
- 1. On the top bar, select **Menu > Projects** and find your project.
+ 1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > Alerts**.
1. Select your desired alert to display its details.
@@ -226,7 +226,7 @@ add a to-do item:
1. Display the list of current alerts:
- 1. On the top bar, select **Menu > Projects** and find your project.
+ 1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > Alerts**.
1. Select your desired alert to display its **Alert Management Details View**.
diff --git a/doc/operations/incident_management/escalation_policies.md b/doc/operations/incident_management/escalation_policies.md
index c24824e55f8..56ff733e395 100644
--- a/doc/operations/incident_management/escalation_policies.md
+++ b/doc/operations/incident_management/escalation_policies.md
@@ -22,7 +22,7 @@ Prerequisite:
To create an escalation policy:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > Escalation Policies**.
1. Select **Add an escalation policy**.
1. Enter the policy's name and description, and
@@ -46,7 +46,7 @@ the paged users is created on the alert.
To update an escalation policy:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > Escalation Policies**.
1. Select **Edit escalation policy** (**{pencil}**).
1. Edit the information.
@@ -56,7 +56,7 @@ To update an escalation policy:
To delete an escalation policy:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > Escalation Policies**.
1. Select **Delete escalation policy** (**{remove}**).
1. On the confirmation dialog, select **Delete escalation policy**.
diff --git a/doc/operations/incident_management/incident_timeline_events.md b/doc/operations/incident_management/incident_timeline_events.md
index a360cac0d01..743f9b429d6 100644
--- a/doc/operations/incident_management/incident_timeline_events.md
+++ b/doc/operations/incident_management/incident_timeline_events.md
@@ -25,7 +25,7 @@ They are grouped with dates and are listed in ascending order of the time when t
To view the event timeline of an incident:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > Incidents**.
1. Select an incident.
1. Select the **Timeline** tab.
@@ -44,7 +44,7 @@ Prerequisites:
To create a timeline event:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > Incidents**.
1. Select an incident.
1. Select the **Timeline** tab.
@@ -68,7 +68,7 @@ Prerequisites:
To create a timeline event from a comment on the incident:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > Incidents**.
1. Select an incident.
1. Create a comment or choose an existing comment.
@@ -86,7 +86,7 @@ Prerequisites:
To delete a timeline event:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > Incidents**.
1. Select an incident.
1. Select the **Timeline** tab.
diff --git a/doc/operations/incident_management/linked_resources.md b/doc/operations/incident_management/linked_resources.md
index f2a1e60e9c0..3fe4a325cdb 100644
--- a/doc/operations/incident_management/linked_resources.md
+++ b/doc/operations/incident_management/linked_resources.md
@@ -29,7 +29,7 @@ Linked resources for an incident are listed under the **Summary** tab.
To view the linked resources of an incident:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > Incidents**.
1. Select an incident.
@@ -43,7 +43,7 @@ Prerequisites:
To add a linked resource:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > Incidents**.
1. Select an incident.
1. In the **Linked resources** section, select the plus icon (**{plus-square}**).
@@ -76,7 +76,7 @@ Prerequisites:
To remove a linked resource:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > Incidents**.
1. Select an incident.
1. In the **Linked resources** section, select **Remove** (**{close}**).
diff --git a/doc/operations/incident_management/oncall_schedules.md b/doc/operations/incident_management/oncall_schedules.md
index 9b2e9159429..f1fb3503195 100644
--- a/doc/operations/incident_management/oncall_schedules.md
+++ b/doc/operations/incident_management/oncall_schedules.md
@@ -28,7 +28,7 @@ Prerequisite:
To create an on-call schedule:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > On-call Schedules**.
1. Select **Add a schedule**.
1. Enter the schedule's name and description and select a time zone.
@@ -43,7 +43,7 @@ create [rotations](#rotations) for your schedule.
To update a schedule:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > On-call Schedules**.
1. Select **Edit schedule** (**{pencil}**).
1. Edit the information.
@@ -56,7 +56,7 @@ interval (if one is set) to the corresponding times in the new time zone.
To delete a schedule:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > On-call Schedules**.
1. Select **Delete escalation policy** (**{remove}**).
1. On the confirmation dialog, select **Delete schedule**.
@@ -67,7 +67,7 @@ Add rotations to an existing schedule to put your team members on-call.
To create a rotation:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > On-call Schedules**.
1. Select the **Add a rotation** link.
1. Enter the following information:
@@ -85,7 +85,7 @@ To create a rotation:
To edit a rotation:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > On-call Schedules**.
1. In the **Rotations** section, select **Edit rotation** (**{pencil}**).
1. Edit the information.
@@ -95,7 +95,7 @@ To edit a rotation:
To delete a rotation:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > On-call Schedules**.
1. In the **Rotations** section, select **Delete rotation** (**{remove}**).
1. On the confirmation dialog, select **Delete rotation**.
diff --git a/doc/operations/incident_management/paging.md b/doc/operations/incident_management/paging.md
index 3eeeb67bf51..837fc9c72f5 100644
--- a/doc/operations/incident_management/paging.md
+++ b/doc/operations/incident_management/paging.md
@@ -27,7 +27,7 @@ Email notifications are available in projects for triggered alerts. Project
members with the **Owner** or **Maintainer** roles have the option to receive
a single email notification for new alerts.
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Settings > Monitor**.
1. Expand **Alerts**.
1. On the **Alert settings** tab, select the
diff --git a/doc/operations/incident_management/status_page.md b/doc/operations/incident_management/status_page.md
index fe75c1812c8..ae4d75396ae 100644
--- a/doc/operations/incident_management/status_page.md
+++ b/doc/operations/incident_management/status_page.md
@@ -45,7 +45,7 @@ Prerequisite:
To provide GitLab with the AWS account information needed to push content to your Status Page:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Settings > Monitor**.
1. Expand **Status Page**.
1. Select the **Active** checkbox.
@@ -96,7 +96,7 @@ the issue can potentially [publish comments to your GitLab Status Page](#publish
After creating the CI/CD variables, configure the Project you want to use for
Incident issues:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Settings > Monitor**.
1. Expand **Status page**.
1. Fill in your cloud provider's credentials and make sure to select the **Active** checkbox.
diff --git a/doc/operations/product_analytics.md b/doc/operations/product_analytics.md
index a897e1d26e8..e21770bc579 100644
--- a/doc/operations/product_analytics.md
+++ b/doc/operations/product_analytics.md
@@ -28,7 +28,7 @@ Prerequisite:
To access Product Analytics:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > Product Analytics**.
The Product Analytics interface contains:
diff --git a/doc/tutorials/make_your_first_git_commit.md b/doc/tutorials/make_your_first_git_commit.md
index fafc440c6a3..879257fc3b8 100644
--- a/doc/tutorials/make_your_first_git_commit.md
+++ b/doc/tutorials/make_your_first_git_commit.md
@@ -83,8 +83,8 @@ Here's an overview of what we're going to do:
To start, create a sample project in GitLab.
-1. In GitLab, on the top bar, select **Menu > Projects > Create new project**.
-1. Select **Create blank project**.
+1. In GitLab, on the top bar, select **Main menu > Projects > View all projects**.
+1. On the right of the page, select **New project**.
1. For **Project name**, enter `My sample project`. The project slug is generated for you.
This slug is the URL you can use to access the project after it's created.
1. Ensure **Initialize repository with a README** is selected.
diff --git a/doc/tutorials/move_personal_project_to_a_group.md b/doc/tutorials/move_personal_project_to_a_group.md
index 5ebbf813ab9..4f94f77e2bd 100644
--- a/doc/tutorials/move_personal_project_to_a_group.md
+++ b/doc/tutorials/move_personal_project_to_a_group.md
@@ -46,8 +46,8 @@ Maintainer role for the group.
If you don't have a group, create one:
-1. On the top bar, select **Menu > Groups > Create group**
-1. Select **Create group**.
+1. On the top bar, select **Main menu > Groups > View all groups**
+1. On the right of the page, select **New group**.
1. In **Group name**, enter a name for the group.
1. In **Group URL**, enter a path for the group, which is used as the namespace.
1. Choose the [visibility level](../user/public_access.md).
@@ -64,7 +64,7 @@ Before you move your project to a group:
Now you're ready to move your project:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects > View all projects** and find your project.
1. On the left sidebar, select **Settings > General**.
1. Expand **Advanced**.
1. Under **Transfer project**, choose the group to transfer the project to.
@@ -85,7 +85,7 @@ your related resources and tools, such as websites and package managers.
You can now view your project in your group:
-1. On the top bar, select **Menu > Groups** and find your group.
+1. On the top bar, select **Main menu > Groups > View all groups** and find your group.
1. Look for your project under **Subgroups and projects**.
Start enjoying the benefits of a group! For example, as the group Owner, you can
diff --git a/doc/update/index.md b/doc/update/index.md
index dd3a62570db..41f3f9fbf67 100644
--- a/doc/update/index.md
+++ b/doc/update/index.md
@@ -147,7 +147,7 @@ Some installations [may need to run GitLab 14.0 for at least a day](#1400) to co
To check the status of batched background migrations:
-1. On the top bar, select **Menu > Admin**.
+1. On the top bar, select **Main menu > Admin**.
1. On the left sidebar, select **Monitoring > Background Migrations**.
![queued batched background migrations table](img/batched_background_migrations_queued_v14_0.png)
diff --git a/doc/update/plan_your_upgrade.md b/doc/update/plan_your_upgrade.md
index 9dfdb7c530b..03bdf161756 100644
--- a/doc/update/plan_your_upgrade.md
+++ b/doc/update/plan_your_upgrade.md
@@ -132,7 +132,7 @@ to your instance and then upgrade it for any relevant features you're using.
[turning on maintenance mode](../administration/maintenance_mode/index.md) during the
upgrade.
- About PostgreSQL:
- - On the top bar, select **Menu > Admin**, and look for the version of
+ - On the top bar, select **Main menu > Admin**, and look for the version of
PostgreSQL you are using.
If [a PostgreSQL upgrade is needed](../administration/package_information/postgresql_versions.md),
account for the relevant
diff --git a/doc/update/removals.md b/doc/update/removals.md
index 1f9b92d6600..feec0f1b29d 100644
--- a/doc/update/removals.md
+++ b/doc/update/removals.md
@@ -140,8 +140,8 @@ If you have set a prefix, you can use a workaround to revert to background uploa
gitlab_rails['env'] = { 'GITLAB_LEGACY_BACKGROUND_UPLOADS' => 'artifacts,external_diffs,lfs,uploads,packages,dependency_proxy,terraform_state,pages' }
```
-Prefixes will be supported officially in [GitLab 15.2](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91307).
-This workaround will be dropped, so we encourage migrating to consolidated object storage.
+Support for prefixes was restored in GitLab 15.2 via [this MR](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91307).
+Support for setting `GITLAB_LEGACY_BACKGROUND_UPLOADS` will be removed in GitLab 15.4.
### Container Network and Host Security
diff --git a/doc/user/crm/index.md b/doc/user/crm/index.md
index e71a983ccfd..56ada837d54 100644
--- a/doc/user/crm/index.md
+++ b/doc/user/crm/index.md
@@ -36,7 +36,7 @@ you must enable CRM features for the subgroup.
To enable customer relations management in a group or subgroup:
-1. On the top bar, select **Menu > Groups** and find your group or subgroup.
+1. On the top bar, select **Main menu > Groups** and find your group or subgroup.
1. On the left sidebar, select **Settings > General**.
1. Expand the **Permissions and group features** section.
1. Select **Customer relations is enabled**.
@@ -48,7 +48,7 @@ To enable customer relations management in a group or subgroup:
To view a group's contacts:
-1. On the top bar, select **Menu > Groups** and find your group.
+1. On the top bar, select **Main menu > Groups** and find your group.
1. On the left sidebar, select **Customer relations > Contacts**.
![Contacts list](crm_contacts_v14_10.png)
@@ -57,7 +57,7 @@ To view a group's contacts:
To create a contact:
-1. On the top bar, select **Menu > Groups** and find your group.
+1. On the top bar, select **Main menu > Groups** and find your group.
1. On the left sidebar, select **Customer relations > Contacts**.
1. Select **New contact**.
1. Complete all required fields.
@@ -70,7 +70,7 @@ contacts using the GraphQL API.
To edit an existing contact:
-1. On the top bar, select **Menu > Groups** and find your group.
+1. On the top bar, select **Main menu > Groups** and find your group.
1. On the left sidebar, select **Customer relations > Contacts**.
1. Next to the contact you wish to edit, select **Edit** (**{pencil}**).
1. Edit the required fields.
@@ -85,7 +85,7 @@ contacts using the GraphQL API.
To view a group's organizations:
-1. On the top bar, select **Menu > Groups** and find your group.
+1. On the top bar, select **Main menu > Groups** and find your group.
1. On the left sidebar, select **Customer relations > Organizations**.
![Organizations list](crm_organizations_v14_10.png)
@@ -94,7 +94,7 @@ To view a group's organizations:
To create an organization:
-1. On the top bar, select **Menu > Groups** and find your group.
+1. On the top bar, select **Main menu > Groups** and find your group.
1. On the left sidebar, select **Customer relations > Organizations**.
1. Select **New organization**.
1. Complete all required fields.
@@ -107,7 +107,7 @@ organizations using the GraphQL API.
To edit an existing organization:
-1. On the top bar, select **Menu > Groups** and find your group.
+1. On the top bar, select **Main menu > Groups** and find your group.
1. On the left sidebar, select **Customer relations > Organizations**.
1. Next to the organization you wish to edit, select **Edit** (**{pencil}**).
1. Edit the required fields.
@@ -125,7 +125,7 @@ issues are linked to contacts matching the email addresses in the sender and CC
To view a contact's issues, select a contact from the issue sidebar, or:
-1. On the top bar, select **Menu > Groups** and find your group.
+1. On the top bar, select **Main menu > Groups** and find your group.
1. On the left sidebar, select **Customer relations > Contacts**.
1. Next to the contact whose issues you wish to view, select **View issues** (**{issues}**).
@@ -133,7 +133,7 @@ To view a contact's issues, select a contact from the issue sidebar, or:
To view an organization's issues:
-1. On the top bar, select **Menu > Groups** and find your group.
+1. On the top bar, select **Main menu > Groups** and find your group.
1. On the left sidebar, select **Customer relations > Organizations**.
1. Next to the organization whose issues you wish to view, select **View issues** (**{issues}**).
diff --git a/doc/user/discussions/index.md b/doc/user/discussions/index.md
index d82a6ab5e8e..ed0bcec9f49 100644
--- a/doc/user/discussions/index.md
+++ b/doc/user/discussions/index.md
@@ -91,7 +91,7 @@ For example, `28719b171a056960dfdc0012b625d0b47b123196` becomes
You can add comments and threads to a particular commit.
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Repository > Commits**.
1. Below the commits, in the **Comment** field, enter a comment.
1. Select **Comment** or select the down arrow (**{chevron-down}**) to select **Start thread**.
@@ -339,7 +339,7 @@ You can prevent merge requests from being merged until all threads are
resolved. When this setting is enabled, the **Unresolved threads** counter in a merge request
is shown in orange when at least one thread remains unresolved.
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Settings > Merge requests**.
1. In the **Merge checks** section, select the **All threads must be resolved** checkbox.
1. Select **Save changes**.
@@ -349,7 +349,7 @@ is shown in orange when at least one thread remains unresolved.
You can set merge requests to automatically resolve threads when lines are modified
with a new push.
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Settings > Merge requests**.
1. In the **Merge options** section, select
**Automatically resolve merge request diff threads when they become outdated**.
diff --git a/doc/user/free_user_limit.md b/doc/user/free_user_limit.md
index e364624a630..60091449256 100644
--- a/doc/user/free_user_limit.md
+++ b/doc/user/free_user_limit.md
@@ -37,7 +37,7 @@ Prerequisite:
- You must have the Owner role for the group.
-1. On the top bar, select **Menu > Groups** and find your group.
+1. On the top bar, select **Main menu > Groups > View all groups** and find your group.
1. On the left sidebar, select **Settings > Usage Quotas**.
1. To view all members, select the **Seats** tab.
1. To remove a member, select **Remove user**.
diff --git a/doc/user/group/access_and_permissions.md b/doc/user/group/access_and_permissions.md
index aaf475733ab..949587209d6 100644
--- a/doc/user/group/access_and_permissions.md
+++ b/doc/user/group/access_and_permissions.md
@@ -19,7 +19,7 @@ Group push rules allow group maintainers to set
In GitLab 15.4 and later, to configure push rules for a group:
-1. On the left sidebar, select Push rules.
+1. On the left sidebar, select **Push rules**.
1. Select the settings you want.
1. Select **Save Push Rules**.
@@ -50,7 +50,8 @@ configured by an administrator.
To change the permitted Git access protocols for a group:
-1. Go to the group's **Settings > General** page.
+1. On the top bar, select **Main menu > Groups > View all groups** and find your group.
+1. On the left sidebar, select **Settings > General**.
1. Expand the **Permissions and group features** section.
1. Choose the permitted protocols from **Enabled Git access protocols**.
1. Select **Save changes**.
@@ -90,7 +91,8 @@ You should consider some security implications before configuring IP address res
To restrict group access by IP address:
-1. Go to the group's **Settings > General** page.
+1. On the top bar, select **Main menu > Groups > View all groups** and find your group.
+1. On the left sidebar, select **Settings > General**.
1. Expand the **Permissions and group features** section.
1. In the **Restrict access by IP address** field, enter IPv4 or IPv6 address ranges in CIDR notation.
1. Select **Save changes**.
@@ -109,7 +111,8 @@ You can prevent users with email addresses in specific domains from being added
To restrict group access by domain:
-1. Go to the group's **Settings > General** page.
+1. On the top bar, select **Main menu > Groups > View all groups** and find your group.
+1. On the left sidebar, select **Settings > General**.
1. Expand the **Permissions and group features** section.
1. In the **Restrict membership by email** field, enter the domain names.
1. Select **Save changes**.
@@ -152,7 +155,7 @@ If you prevent group sharing outside the hierarchy for the **Animals** group:
To prevent sharing outside of the group's hierarchy:
-1. On the top bar, select **Menu > Groups** and find your group.
+1. On the top bar, select **Main menu > Groups > View all groups** and find your group.
1. On the left sidebar, select **Settings > General**.
1. Expand **Permissions and group features**.
1. Select **Members cannot invite groups outside of `<group_name>` and its subgroups**.
@@ -166,7 +169,8 @@ to enable tighter control over project access.
To prevent a project from being shared with other groups:
-1. Go to the group's **Settings > General** page.
+1. On the top bar, select **Main menu > Groups > View all groups** and find your group.
+1. On the left sidebar, select **Settings > General**.
1. Expand the **Permissions and group features** section.
1. Select **Projects in `<group_name>` cannot be shared with other groups**.
1. Select **Save changes**.
@@ -179,7 +183,7 @@ added to a project lose access when the setting is enabled.
As a group owner, you can prevent non-members from requesting access to
your group.
-1. On the top bar, select **Menu > Groups**.
+1. On the top bar, **Main menu > Groups > View all groups** and find your group.
1. Select **Your Groups**.
1. Find the group and select it.
1. From the left menu, select **Settings > General**.
@@ -201,7 +205,8 @@ If even one is set to `true`, then the group does not allow outside forks.
To prevent projects from being forked outside the group:
-1. Go to the top-level group's **Settings > General** page.
+1. On the top bar, select **Main menu > Groups > View all groups** and find your group.
+1. On the left sidebar, select **Settings > General**.
1. Expand the **Permissions and group features** section.
1. Check **Prevent project forking outside current group**.
1. Select **Save changes**.
@@ -222,8 +227,8 @@ The setting does not cascade. Projects in subgroups observe the subgroup configu
To prevent members from being added to projects in a group:
-1. Go to the group's **Settings > General** page.
-1. Expand the **Permissions and group features** section.
+1. On the top bar, select **Main menu > Groups > View all groups** and find your group.
+1. On the left sidebar, select **Settings > General**.
1. Under **Membership**, select **Users cannot be added to projects in this group**.
1. Select **Save changes**.
@@ -269,7 +274,8 @@ To create group links via filter:
LDAP user permissions can be manually overridden by an administrator. To override a user's permissions:
-1. Go to your group's **Group information > Members** page.
+1. On the top bar, select **Main menu > Groups > View all groups** and find your group.
+1. On the left sidebar, select **Group information > Members**.
1. In the row for the user you are editing, select the pencil (**{pencil}**) icon.
1. Select **Edit permissions** in the modal.
diff --git a/doc/user/group/manage.md b/doc/user/group/manage.md
index 78e65297d32..d55d410acea 100644
--- a/doc/user/group/manage.md
+++ b/doc/user/group/manage.md
@@ -10,8 +10,7 @@ Use groups to manage one or more related projects at the same time.
## View groups
-1. On the top bar, select **Menu > Groups**.
-1. Select **Explore groups**.
+To view groups, on the top bar, select **Main menu > Groups > View all groups**.
The **Groups** page shows a list of groups, sorted by last updated date.
@@ -25,7 +24,7 @@ The **Groups** page shows a list of groups, sorted by last updated date.
To create a group:
1. On the top bar, either:
- - Select **Menu > Groups**, and on the right, select **Create group**.
+ - Select **Main menu > Groups > View all groups**, and on the right, select **New group**.
- To the left of the search box, select the plus sign and then **New group**.
1. Select **Create group**.
1. Enter a name for the group in **Group name**. For a list of words that cannot be used as group names, see
@@ -45,7 +44,7 @@ For details about groups, watch [GitLab Namespaces (users, groups and subgroups)
To remove a group and its contents:
-1. On the top bar, select **Menu > Groups** and find your group.
+1. On the top bar, select **Main menu > Groups > View all groups** and find your group.
1. On the left sidebar, select **Settings > General**.
1. Expand the **Advanced** section.
1. In the **Remove group** section, select **Remove group**.
@@ -54,7 +53,7 @@ To remove a group and its contents:
A group can also be removed from the groups dashboard:
-1. On the top bar, select **Menu > Groups**.
+1. On the top bar, select **Main menu > Groups > View all groups**.
1. Select **Your Groups**.
1. Select (**{ellipsis_v}**) for the group you want to delete.
1. Select **Delete**.
@@ -83,7 +82,7 @@ Prerequisites:
To immediately remove a group marked for deletion:
-1. On the top bar, select **Menu > Groups** and find your group.
+1. On the top bar, select **Main menu > Groups > View all groups** and find your group.
1. On the left sidebar, select **Settings > General**.
1. Expand **Advanced**.
1. In the "Permanently remove group" section, select **Remove group**.
@@ -98,7 +97,8 @@ are deleted.
To restore a group that is marked for deletion:
-1. Go to your group's **Settings > General** page.
+1. On the top bar, select **Main menu > Groups > View all groups** and find your group.
+1. Select **Settings > General**.
1. Expand the **Path, transfer, remove** section.
1. In the Restore group section, select **Restore group**.
@@ -106,7 +106,7 @@ To restore a group that is marked for deletion:
As a user, you can request to be a member of a group, if an administrator allows it.
-1. On the top bar, select **Menu > Groups** and find your group.
+1. On the top bar, select **Main menu > Groups > View all groups** and find your group.
1. Under the group name, select **Request Access**.
As many as ten of the most-recently-active group owners receive an email with your request.
@@ -127,7 +127,7 @@ To find members in a group, you can sort, filter, or search.
Filter a group to find members. By default, all members in the group and subgroups are displayed.
-1. Go to the group and select **Group information > Members**.
+1. On the top bar, select **Main menu > Groups > View all groups** and find your group.
1. Above the list of members, in the **Filter members** box, enter filter criteria.
- To view members in the group only, select **Membership = Direct**.
- To view members of the group and its subgroups, select **Membership = Inherited**.
@@ -138,7 +138,8 @@ Filter a group to find members. By default, all members in the group and subgrou
You can search for members by name, username, or email.
-1. Go to the group and select **Group information > Members**.
+1. On the top bar, select **Main menu > Groups > View all groups** and find your group.
+1. On the left sidebar, select **Group information > Members**.
1. Above the list of members, in the **Filter members** box, enter search criteria.
1. To the right of the **Filter members** box, select the magnifying glass (**{search}**).
@@ -146,7 +147,8 @@ You can search for members by name, username, or email.
You can sort members by **Account**, **Access granted**, **Max role**, or **Last sign-in**.
-1. Go to the group and select **Group information > Members**.
+1. On the top bar, select **Main menu > Groups > View all groups** and find your group.
+1. On the left sidebar, select **Group information > Members**.
1. Above the list of members, on the top right, from the **Account** list, select
the criteria to filter by.
1. To switch the sort between ascending and descending, to the right of the **Account** list, select the
@@ -156,7 +158,7 @@ You can sort members by **Account**, **Access granted**, **Max role**, or **Last
You can give a user access to all projects in a group.
-1. On the top bar, select **Menu > Groups** and find your group.
+1. On the top bar, select **Main menu > Groups > View all groups** and find your group.
1. On the left sidebar, select **Group information > Members**.
1. Select **Invite members**.
1. Fill in the fields.
@@ -182,8 +184,8 @@ Prerequisites:
To remove a member from a group:
-1. Go to the group.
-1. From the left menu, select **Group information > Members**.
+1. On the top bar, select **Main menu > Groups > View all groups** and find your group.
+1. On the left sidebar, select **Group information > Members**.
1. Next to the member you want to remove, select **Remove member**.
1. Optional. On the **Remove member** confirmation box:
- To remove direct user membership from subgroups and projects, select the **Also remove direct user membership from subgroups and projects** checkbox.
@@ -208,7 +210,7 @@ By default, users with at least the Developer role can create projects under a g
To change this setting for a specific group:
-1. On the top bar, select **Menu > Groups**.
+1. On the top bar, select **Main menu > Groups > View all groups**.
1. Select **Your Groups**.
1. Find the group and select it.
1. From the left menu, select **Settings > General**.
@@ -224,11 +226,13 @@ You can change the owner of a group. Each group must always have at least one
member with the Owner role.
- As an administrator:
- 1. Go to the group and from the left menu, select **Group information > Members**.
+ 1. On the top bar, select **Main menu > Groups > View all groups** and find your group.
+ 1. On the left sidebar, select **Group information > Members**.
1. Give a different member the **Owner** role.
1. Refresh the page. You can now remove the **Owner** role from the original owner.
- As the current group's owner:
- 1. Go to the group and from the left menu, select **Group information > Members**.
+ 1. On the top bar, select **Main menu > Groups > View all groups** and find your group.
+ 1. On the left sidebar, select **Group information > Members**.
1. Give a different member the **Owner** role.
1. Have the new owner sign in and remove the **Owner** role from you.
@@ -247,7 +251,8 @@ create a new group and transfer projects to it instead.
To change your group path (group URL):
-1. Go to your group's **Settings > General** page.
+1. On the top bar, select **Main menu > Groups > View all groups** and find your group.
+1. On the left sidebar, select **Settings > General** page.
1. Expand the **Advanced** section.
1. Under **Change group URL**, enter a new name.
1. Select **Change group URL**.
@@ -327,7 +332,7 @@ When transferring groups, note:
To transfer a group:
-1. On the top bar, select **Menu > Groups** and find your group.
+1. On the top bar, select **Main menu > Groups > View all groups** and find your group.
1. On the left sidebar, select **Settings > General**.
1. Expand the **Advanced** section.
1. In the **Remove group** section, select **Transfer group**.
@@ -357,7 +362,8 @@ the default setting.
To enable delayed deletion of projects in a group:
-1. Go to the group's **Settings > General** page.
+1. On the top bar, select **Main menu > Groups > View all groups** and find your group.
+1. On the left sidebar, select **Settings > General**.
1. Expand the **Permissions and group features** section.
1. Scroll to:
- (GitLab 15.1 and later) **Deletion protection** and select **Keep deleted projects**.
@@ -378,7 +384,8 @@ You can disable all email notifications related to the group, which includes its
To disable email notifications:
-1. Go to the group's **Settings > General** page.
+1. On the top bar, select **Main menu > Groups > View all groups** and find your group.
+1. On the left sidebar, select **Settings > General**.
1. Expand the **Permissions and group features** section.
1. Select **Email notifications are disabled**.
1. Select **Save changes**.
@@ -397,7 +404,8 @@ This is particularly helpful for groups with a large number of users.
To disable group mentions:
-1. Go to the group's **Settings > General** page.
+1. On the top bar, select **Main menu > Groups > View all groups** and find your group.
+1. On the left sidebar, select **Settings > General**.
1. Expand the **Permissions and group features** section.
1. Select **Group mentions are disabled**.
1. Select **Save changes**.
@@ -409,7 +417,8 @@ To disable group mentions:
You can export a list of members in a group or subgroup as a CSV.
-1. Go to your group or subgroup and select either **Group information > Members** or **Subgroup information > Members**.
+1. On the top bar, select **Main menu > Groups > View all groups** and find your group or subgroup.
+1. On the left sidebar, select either **Group information > Members** or **Subgroup information > Members**.
1. Select **Export as CSV**.
1. After the CSV file has been generated, it is emailed as an attachment to the user that requested it.
@@ -435,7 +444,7 @@ Prerequisite:
To specify a user cap:
-1. On the top bar, select **Menu > Groups** and find your group.
+1. On the top bar, select **Main menu > Groups > View all groups** and find your group.
You can set a cap on the top-level group only.
1. On the left sidebar, select **Settings > General**.
1. Expand **Permissions and group features**.
@@ -457,7 +466,7 @@ Prerequisite:
To remove the user cap:
-1. On the top bar, select **Menu > Groups** and find your group.
+1. On the top bar, select **Main menu > Groups > View all groups** and find your group.
1. On the left sidebar, select **Settings > General**.
1. Expand **Permissions and group features**.
1. In the **User cap** box, delete the value.
@@ -478,7 +487,7 @@ Prerequisite:
To approve members that are pending because they've exceeded the user cap:
-1. On the top bar, select **Menu > Groups** and find your group.
+1. On the top bar, select **Main menu > Groups > View all groups** and find your group.
1. On the left sidebar, select **Settings > Usage Quotas**.
1. On the **Seats** tab, under the alert, select **View pending approvals**.
1. For each member you want to approve, select **Approve**.
@@ -509,7 +518,8 @@ Define project templates at a group level by setting a group as the template sou
To enable group file templates:
-1. Go to the group's **Settings > General** page.
+1. On the top bar, select **Main menu > Groups > View all groups** and find your group.
+1. On the left sidebar, select **Settings > General**.
1. Expand the **Templates** section.
1. Choose a project to act as the template repository.
1. Select **Save changes**.
@@ -526,7 +536,8 @@ that belong to the group.
To view the merge request approval settings for a group:
-1. Go to the top-level group's **Settings > General** page.
+1. On the top bar, select **Main menu > Groups > View all groups** and find your group.
+1. On the left sidebar, select **Settings > General**.
1. Expand the **Merge request approvals** section.
1. Select the settings you want.
1. Select **Save changes**.
@@ -549,7 +560,7 @@ Changes to [group wikis](../project/wiki/group.md) do not appear in group activi
You can view the most recent actions taken in a group, either in your browser or in an RSS feed:
-1. On the top bar, select **Menu > Groups**.
+1. On the top bar, select **Main menu > Groups > View all groups**.
1. Select **Your Groups**.
1. Find the group and select it.
1. On the left sidebar, select **Group information > Activity**.
diff --git a/doc/user/profile/account/create_accounts.md b/doc/user/profile/account/create_accounts.md
index 694ed02a694..e3f7d47038d 100644
--- a/doc/user/profile/account/create_accounts.md
+++ b/doc/user/profile/account/create_accounts.md
@@ -33,7 +33,7 @@ Prerequisites:
To create a user manually:
-1. On the top bar, select **Menu > Admin**.
+1. On the top bar, select **Main menu > Admin**.
1. On the left sidebar, select **Overview > Users** (`/admin/users`).
1. Select **New user**.
1. Complete the fields.
diff --git a/doc/user/profile/account/delete_account.md b/doc/user/profile/account/delete_account.md
index 5ec29814e06..d2e0c1ad834 100644
--- a/doc/user/profile/account/delete_account.md
+++ b/doc/user/profile/account/delete_account.md
@@ -28,7 +28,7 @@ As a user, to delete your own account:
As an administrator, to delete a user account:
-1. On the top bar, select **Menu > Admin**.
+1. On the top bar, select **Main menu > Admin**.
1. On the left sidebar, select **Overview > Users**.
1. Select a user.
1. Under the **Account** tab, select:
diff --git a/doc/user/profile/index.md b/doc/user/profile/index.md
index f1f9783878d..ad67fe4bfd8 100644
--- a/doc/user/profile/index.md
+++ b/doc/user/profile/index.md
@@ -111,7 +111,7 @@ the README file with information, it's included on your profile page.
To create a new project and add its README to your profile:
-1. On the top bar, select **Menu > Project**.
+1. On the top bar, select **Main menu > Projects**.
1. Select **Create new project**.
1. Select **Create blank project**.
1. Enter the project details:
@@ -421,7 +421,7 @@ When you sign in to the main GitLab application, a `_gitlab_session` cookie is
set. When you close your browser, the cookie is cleared client-side
and it expires after a set duration. GitLab administrators can determine the duration:
-1. On the top bar, select **Menu > Admin**.
+1. On the top bar, select **Main menu > Admin**.
1. On the left sidebar, select **Settings > General**.
1. Expand **Account and limit**. The set duration is in **Session duration (minutes)**.
diff --git a/doc/user/profile/notifications.md b/doc/user/profile/notifications.md
index 0245f0615e0..1b737f14f68 100644
--- a/doc/user/profile/notifications.md
+++ b/doc/user/profile/notifications.md
@@ -108,7 +108,7 @@ To select a notification level for a group, use either of these methods:
Or:
-1. On the top bar, select **Menu > Groups** and find your group.
+1. On the top bar, select **Main menu > Groups** and find your group.
1. Select the notification dropdown, next to the bell icon (**{notifications}**).
1. Select the desired [notification level](#notification-levels).
@@ -139,7 +139,7 @@ To select a notification level for a project, use either of these methods:
Or:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. Select the notification dropdown, next to the bell icon (**{notifications}**).
1. Select the desired [notification level](#notification-levels).
diff --git a/doc/user/project/issue_board.md b/doc/user/project/issue_board.md
index 3e980717313..916d566bb20 100644
--- a/doc/user/project/issue_board.md
+++ b/doc/user/project/issue_board.md
@@ -618,6 +618,40 @@ into a different list. Learn about possible effects in [Dragging issues between
To move a list, select its top bar, and drag it horizontally.
You can't move the **Open** and **Closed** lists, but you can hide them when editing an issue board.
+#### Move an issue to the start of the list
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/367473) in GitLab 15.4.
+
+You can move issues to the top of the list with a menu shortcut.
+
+Your issue is moved to the top of the list even if other issues are hidden by a filter.
+
+Prerequisites:
+
+- You must at least have the Reporter role for the project.
+
+To move an issue to the start of the list:
+
+1. In an issue board, hover over the card of the issue you want to move.
+1. Select the vertical ellipsis (**{ellipsis_v}**), then **Move to start of list**.
+
+#### Move an issue to the end of the list
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/367473) in GitLab 15.4.
+
+You can move issues to the bottom of the list with a menu shortcut.
+
+Your issue is moved to the bottom of the list even if other issues are hidden by a filter.
+
+Prerequisites:
+
+- You must at least have the Reporter role for the project.
+
+To move an issue to the end of the list:
+
+1. In an issue board, hover over the card of the issue you want to move.
+1. Select the vertical ellipsis (**{ellipsis_v}**), then **Move to end of list**.
+
#### Dragging issues between lists
To move an issue to another list, select the issue card and drag it onto that list.
diff --git a/doc/user/project/issues/managing_issues.md b/doc/user/project/issues/managing_issues.md
index 1fe0b511551..4647631343b 100644
--- a/doc/user/project/issues/managing_issues.md
+++ b/doc/user/project/issues/managing_issues.md
@@ -33,7 +33,7 @@ Prerequisites:
To create an issue:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. Either:
- On the left sidebar, select **Issues**, and then, in the top right corner, select **New issue**.
@@ -56,7 +56,7 @@ Prerequisites:
To create an issue from a group:
-1. On the top bar, select **Menu > Groups** and find your group.
+1. On the top bar, select **Main menu > Groups** and find your group.
1. On the left sidebar, select **Issues**.
1. In the top right corner, select **Select project to create issue**.
1. Select the project you'd like to create an issue for. The button now reflects the selected
@@ -103,7 +103,7 @@ Prerequisites:
To create an issue from a project issue board:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. Select **Issues > Boards**.
1. At the top of a board list, select **New issue** (**{plus-square}**).
1. Enter the issue's title.
@@ -111,7 +111,7 @@ To create an issue from a project issue board:
To create an issue from a group issue board:
-1. On the top bar, select **Menu > Groups** and find your group.
+1. On the top bar, select **Main menu > Groups** and find your group.
1. Select **Issues > Boards**.
1. At the top of a board list, select **New issue** (**{plus-square}**).
1. Enter the issue's title.
@@ -138,7 +138,7 @@ Prerequisites:
To email an issue to a project:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. Select **Issues**.
1. At the bottom of the page, select **Email a new issue to this project**.
1. To copy the email address, select **Copy** (**{copy-to-clipboard}**).
@@ -271,7 +271,7 @@ Prerequisites:
To edit multiple issues at the same time:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Issues**.
1. Select **Edit issues**. A sidebar on the right of your screen appears.
1. Select the checkboxes next to each issue you want to edit.
@@ -304,7 +304,7 @@ Prerequisites:
To edit multiple issues at the same time:
-1. On the top bar, select **Menu > Groups** and find your group.
+1. On the top bar, select **Main menu > Groups** and find your group.
1. On the left sidebar, select **Issues**.
1. Select **Edit issues**. A sidebar on the right of your screen appears.
1. Select the checkboxes next to each issue you want to edit.
@@ -470,7 +470,7 @@ Prerequisites:
To disable automatic issue closing:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Settings > Repository**.
1. Expand **Default branch**.
1. Clear the **Auto-close referenced issues on default branch** checkbox.
@@ -598,7 +598,7 @@ GitLab displays the results on-screen, but you can also
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/39908) in GitLab 12.1.
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Issues > List**.
1. In the **Search** box, type the issue ID. For example, enter filter `#10` to return only issue 10.
diff --git a/doc/user/project/merge_requests/cherry_pick_changes.md b/doc/user/project/merge_requests/cherry_pick_changes.md
index f238678b662..7d12fdac87a 100644
--- a/doc/user/project/merge_requests/cherry_pick_changes.md
+++ b/doc/user/project/merge_requests/cherry_pick_changes.md
@@ -51,7 +51,7 @@ Commit `G` is added after the cherry-pick.
After a merge request is merged, you can cherry-pick all changes introduced
by the merge request:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Merge requests**, and find your merge request.
1. Scroll to the merge request reports section, and find the **Merged by** report.
1. In the top right, select **Cherry-pick**:
@@ -69,7 +69,7 @@ You can cherry-pick a single commit from multiple locations in your GitLab proje
To cherry-pick a commit from the list of all commits for a project:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Repository > Commits**.
1. Select the title of the commit you want to cherry-pick.
1. In the modal window, select the project and branch to cherry-pick into.
@@ -82,7 +82,7 @@ You can cherry-pick commits from any merge request in your project, regardless o
whether the merge request is open or closed. To cherry-pick a commit from the
list of commits included in a merge request:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Merge requests**, and find your merge request.
1. In the merge request's secondary menu, select **Commits** to display the commit details page.
1. Select the title of the commit you want to cherry-pick.
@@ -96,7 +96,7 @@ list of commits included in a merge request:
You can cherry-pick from the list of previous commits affecting an individual file
when you view that file in your project's Git repository:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Repository > Files** and go to the file
changed by the commit.
1. Select **History**, then select the title of the commit you want to cherry-pick.
diff --git a/doc/user/project/merge_requests/commit_templates.md b/doc/user/project/merge_requests/commit_templates.md
index 6b27ea4471c..99a1739b1a4 100644
--- a/doc/user/project/merge_requests/commit_templates.md
+++ b/doc/user/project/merge_requests/commit_templates.md
@@ -29,7 +29,7 @@ Prerequisite:
To do this:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Settings > Merge requests**.
1. Depending on the type of template you want to create, scroll to either
[**Merge commit message template**](#default-template-for-merge-commits) or
diff --git a/doc/user/project/merge_requests/creating_merge_requests.md b/doc/user/project/merge_requests/creating_merge_requests.md
index f30b20e9d34..232c951dd17 100644
--- a/doc/user/project/merge_requests/creating_merge_requests.md
+++ b/doc/user/project/merge_requests/creating_merge_requests.md
@@ -14,7 +14,7 @@ There are many different ways to create a merge request.
You can create a merge request from the list of merge requests.
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left menu, select **Merge requests**.
1. In the top right, select **New merge request**.
1. Select a source and target branch and then **Compare branches and continue**.
@@ -43,7 +43,7 @@ You can create a merge request when you add, edit, or upload a file to a reposit
You can create a merge request when you create a branch.
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left menu, select **Repository > Branches**.
1. Type a branch name and select **New branch**.
1. Above the file list, on the right side, select **Create merge request**.
@@ -90,7 +90,7 @@ to reduce the need for editing merge requests manually through the UI.
You can create a merge request from your fork to contribute back to the main project.
-1. On the top bar, select **Menu > Project**.
+1. On the top bar, select **Main menu > Project**.
1. Select your fork of the repository.
1. On the left menu, go to **Merge requests**, and select **New merge request**.
1. In the **Source branch** drop-down list box, select the branch in your forked repository as the source branch.
@@ -120,7 +120,7 @@ Prerequisites:
To create a merge request by sending an email:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left menu, select **Merge requests**.
1. In the top right, select **Email a new merge request to this project**.
An email address is displayed. Copy this address.
@@ -165,7 +165,7 @@ scenarios when you create a new merge request:
To have merge requests from a fork by default target your own fork
(instead of the upstream project), you can change the default.
-1. On the top bar, select **Menu > Project**.
+1. On the top bar, select **Main menu > Project**.
1. On the left menu, select **Settings > General > Merge requests**.
1. In the **Target project** section, select the option you want to use for
your default target project.
diff --git a/doc/user/project/merge_requests/csv_export.md b/doc/user/project/merge_requests/csv_export.md
index 954687212e7..f997898f5a5 100644
--- a/doc/user/project/merge_requests/csv_export.md
+++ b/doc/user/project/merge_requests/csv_export.md
@@ -12,7 +12,7 @@ Export all the data collected from a project's merge requests into a comma-separ
To export merge requests to a CSV file:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Merge requests** .
1. Add any searches or filters. This can help you keep the size of the CSV file under the 15MB limit. The limit ensures
the file can be emailed to a variety of email providers.
diff --git a/doc/user/project/merge_requests/dependencies.md b/doc/user/project/merge_requests/dependencies.md
index 0c481554401..5b88e69357c 100644
--- a/doc/user/project/merge_requests/dependencies.md
+++ b/doc/user/project/merge_requests/dependencies.md
@@ -57,7 +57,7 @@ information about the dependency:
To view dependency information on a merge request:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Merge requests** and identify your merge request.
1. Scroll to the merge request reports area. Dependent merge requests display information
about the total number of dependencies set, such as
@@ -105,7 +105,7 @@ Prerequisite:
To do this:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Merge requests** and identify your merge request.
1. Select **Edit**.
1. In **Merge request dependencies**, paste either the reference or the full URL
@@ -120,7 +120,7 @@ Prerequisite:
- You must have a role in the project that allows you to edit merge requests.
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Merge requests** and identify your merge request.
1. Select **Edit**.
1. Scroll to **Merge request dependencies** and select **Remove** next to the reference
diff --git a/doc/user/project/merge_requests/index.md b/doc/user/project/merge_requests/index.md
index 35ec075c674..ca40b724d95 100644
--- a/doc/user/project/merge_requests/index.md
+++ b/doc/user/project/merge_requests/index.md
@@ -27,7 +27,7 @@ You can view merge requests for your project, group, or yourself.
To view all merge requests for a project:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Merge requests**.
Or, to use a [keyboard shortcut](../../shortcuts.md), press <kbd>g</kbd> + <kbd>m</kbd>.
@@ -36,7 +36,7 @@ Or, to use a [keyboard shortcut](../../shortcuts.md), press <kbd>g</kbd> + <kbd>
To view merge requests for all projects in a group:
-1. On the top bar, select **Menu > Groups** and find your group.
+1. On the top bar, select **Main menu > Groups** and find your group.
1. On the left sidebar, select **Merge requests**.
If your group contains subgroups, this view also displays merge requests from the subgroup projects.
@@ -166,7 +166,7 @@ To assign the merge request to someone else, use the `/assign @user`
[quick action](../quick_actions.md#issues-merge-requests-and-epics) in a text area in
a merge request, or:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Merge requests** and find your merge request.
1. On the right sidebar, expand the right sidebar and locate the **Assignees** section.
1. Select **Edit**.
@@ -186,7 +186,7 @@ accountable for it:
To assign multiple assignees to a merge request, use the `/assign @user`
[quick action](../quick_actions.md#issues-merge-requests-and-epics) in a text area, or:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Merge requests** and find your merge request.
1. On the right sidebar, expand the right sidebar and locate the **Assignees** section.
1. Select **Edit** and, from the dropdown list, select all users you want
diff --git a/doc/user/project/merge_requests/merge_when_pipeline_succeeds.md b/doc/user/project/merge_requests/merge_when_pipeline_succeeds.md
index 6aac57ad144..57c4ff455cb 100644
--- a/doc/user/project/merge_requests/merge_when_pipeline_succeeds.md
+++ b/doc/user/project/merge_requests/merge_when_pipeline_succeeds.md
@@ -34,7 +34,7 @@ To do this when pushing from the command line, use the `merge_request.merge_when
To do this from the GitLab user interface:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Merge requests**.
1. Scroll to the merge request reports section.
1. Optional. Select your desired merge options, such as **Delete source branch**,
@@ -57,7 +57,7 @@ Prerequisites:
To do this:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Merge requests**.
1. Scroll to the merge request reports section.
1. Select **Cancel auto-merge**.
@@ -83,7 +83,7 @@ Prerequisites:
To enable this setting:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Settings > Merge requests**.
1. Scroll to **Merge checks**, and select **Pipelines must succeed**.
This setting also prevents merge requests from being merged if there is no pipeline,
@@ -104,7 +104,7 @@ Prerequisite:
To change this behavior:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Settings > General**.
1. Expand **Merge requests**.
1. Under **Merge checks**:
diff --git a/doc/user/project/merge_requests/methods/index.md b/doc/user/project/merge_requests/methods/index.md
index 02a784a321c..68dd6477408 100644
--- a/doc/user/project/merge_requests/methods/index.md
+++ b/doc/user/project/merge_requests/methods/index.md
@@ -12,7 +12,7 @@ merge requests are merged into an existing branch.
## Configure a project's merge method
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Settings > Merge requests**.
1. In the **Merge method** section, select your desired merge method.
1. Select **Save changes**.
diff --git a/doc/user/project/merge_requests/revert_changes.md b/doc/user/project/merge_requests/revert_changes.md
index bee7ed2cc02..a6e0740ff78 100644
--- a/doc/user/project/merge_requests/revert_changes.md
+++ b/doc/user/project/merge_requests/revert_changes.md
@@ -30,7 +30,7 @@ Prerequisites:
To do this:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Merge requests** and identify your merge request.
1. Scroll to the merge request reports area, and find the report showing when the
merge request was merged.
@@ -55,7 +55,7 @@ Prerequisites:
To do this:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. If you know the merge request that contains the commit:
1. On the left sidebar, select **Merge requests** and identify your merge request.
1. Select **Commits**, then select the title of the commit you want to revert. GitLab displays the contents of the commit.
diff --git a/doc/user/project/merge_requests/squash_and_merge.md b/doc/user/project/merge_requests/squash_and_merge.md
index e113dcfdb58..066149afbb5 100644
--- a/doc/user/project/merge_requests/squash_and_merge.md
+++ b/doc/user/project/merge_requests/squash_and_merge.md
@@ -60,7 +60,7 @@ squash the commits as part of the merge process:
To configure the default squashing behavior for all merge requests in your project:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Settings > Merge requests**.
1. In the **Squash commits when merging** section, select your desired behavior:
- **Do not allow**: Squashing is never performed, and the option is not displayed.
diff --git a/doc/user/project/milestones/index.md b/doc/user/project/milestones/index.md
index 61b4b311e96..723ca17ee56 100644
--- a/doc/user/project/milestones/index.md
+++ b/doc/user/project/milestones/index.md
@@ -37,8 +37,8 @@ For information about project and group milestones API, see:
To view the milestone list:
-1. On the top bar, select **Menu > Projects** and find your project or
- **Menu > Groups** and find your group.
+1. On the top bar, select **Main menu > Projects** and find your project or
+ **Main menu > Groups** and find your group.
1. Select **Issues > Milestones**.
In a project, GitLab displays milestones that belong to the project.
@@ -66,7 +66,7 @@ Improving this experience is tracked in issue [339009](https://gitlab.com/gitlab
You can view all the milestones you have access to in the entire GitLab namespace.
You might not see some milestones because they're in projects or groups you're not a member of.
-To do so, on the top bar select **Menu > Milestones**.
+To do so, on the top bar select **Main menu > Milestones**.
### View milestone details
@@ -119,7 +119,7 @@ Prerequisites:
To create a milestone:
-1. On the top bar, select **Menu > Projects** and find your project or **Menu > Groups** and find your group.
+1. On the top bar, select **Main menu > Projects** and find your project or **Main menu > Groups** and find your group.
1. On the left sidebar, select **Issues > Milestones**.
1. Select **New milestone**.
1. Enter the title.
@@ -138,7 +138,7 @@ Prerequisites:
To edit a milestone:
-1. On the top bar, select **Menu > Projects** and find your project or **Menu > Groups** and find your group.
+1. On the top bar, select **Main menu > Projects** and find your project or **Main menu > Groups** and find your group.
1. Select a milestone's title.
1. Select **Edit**.
1. Edit the title, start date, due date, or description.
@@ -154,7 +154,7 @@ Prerequisites:
To edit a milestone:
-1. On the top bar, select **Menu > Projects** and find your project or **Menu > Groups** and find your group.
+1. On the top bar, select **Main menu > Projects** and find your project or **Main menu > Groups** and find your group.
1. Select a milestone's title.
1. Select **Delete**.
1. Select **Delete milestone**.
@@ -179,7 +179,7 @@ Prerequisites:
To promote a project milestone:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. Either:
- Select **Promote to Group Milestone** (**{level-up}**).
- Select the milestone title, and then select **Promote**.
diff --git a/doc/user/project/repository/branches/default.md b/doc/user/project/repository/branches/default.md
index 3083ca5da3c..d31c64f4640 100644
--- a/doc/user/project/repository/branches/default.md
+++ b/doc/user/project/repository/branches/default.md
@@ -64,7 +64,7 @@ GitLab [administrators](../../../permissions.md) of self-managed instances can
customize the initial branch for projects hosted on that instance. Individual
groups and subgroups can override this instance-wide setting for their projects.
-1. On the top bar, select **Menu > Admin**.
+1. On the top bar, select **Main menu > Admin**.
1. On the left sidebar, select **Settings > Repository**.
1. Expand **Default initial branch name**.
1. Change the default initial branch to a custom name of your choice.
@@ -115,7 +115,7 @@ you must either:
Administrators of self-managed instances can customize the initial default branch protection for projects hosted on that instance. Individual
groups and subgroups can override this instance-wide setting for their projects.
-1. On the top bar, select **Menu > Admin**.
+1. On the top bar, select **Main menu > Admin**.
1. On the left sidebar, select **Settings > Repository**.
1. Expand **Default branch**.
1. Select [**Initial default branch protection**](#protect-initial-default-branches).
@@ -132,7 +132,7 @@ can be overridden on a per-group basis by the group's owner. In
[GitLab Premium or higher](https://about.gitlab.com/pricing/), GitLab administrators can
disable this privilege for group owners, enforcing the instance-level protection rule:
-1. On the top bar, select **Menu > Admin**.
+1. On the top bar, select **Main menu > Admin**.
1. On the left sidebar, select **Settings > Repository**.
1. Expand the **Default branch** section.
1. Clear the **Allow owners to manage default branch protection per group** checkbox.
@@ -152,7 +152,7 @@ can be overridden on a per-group basis by the group's owner. In
[enforce protection of initial default branches](#prevent-overrides-of-default-branch-protection)
which locks this setting for group owners.
-1. On the top bar, select **Menu > Groups** and find your group.
+1. On the top bar, select **Main menu > Groups** and find your group.
1. On the left sidebar, select **Settings > Repository**.
1. Expand **Default branch**.
1. Select [**Initial default branch protection**](#protect-initial-default-branches).
diff --git a/doc/user/project/repository/gpg_signed_commits/index.md b/doc/user/project/repository/gpg_signed_commits/index.md
index b2a6c8848ce..d307a6a8580 100644
--- a/doc/user/project/repository/gpg_signed_commits/index.md
+++ b/doc/user/project/repository/gpg_signed_commits/index.md
@@ -193,10 +193,10 @@ you can sign individual commits manually, or configure Git to default to signed
You can review commits for a merge request, or for an entire project:
1. To review commits for a project:
- 1. On the top bar, select **Menu > Projects** and find your project.
+ 1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Repository > Commits**.
1. To review commits for a merge request:
- 1. On the top bar, select **Menu > Projects** and find your project.
+ 1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Merge requests**, then select your merge request.
1. Select **Commits**.
1. Identify the commit you want to review. Signed commits show either a **Verified**
diff --git a/doc/user/project/repository/mirror/bidirectional.md b/doc/user/project/repository/mirror/bidirectional.md
index 340d7b48a47..793ca2a5f1f 100644
--- a/doc/user/project/repository/mirror/bidirectional.md
+++ b/doc/user/project/repository/mirror/bidirectional.md
@@ -45,7 +45,7 @@ and [pull](pull.md#pull-from-a-remote-repository) mirrors in the upstream GitLab
To create the webhook in the downstream instance:
1. Create a [personal access token](../../../profile/personal_access_tokens.md) with `API` scope.
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Settings > Webhooks**.
1. Add the webhook **URL**, which (in this case) uses the
[Pull Mirror API](../../../../api/projects.md#start-the-pull-mirroring-process-for-a-project)
diff --git a/doc/user/project/repository/mirror/index.md b/doc/user/project/repository/mirror/index.md
index b08530c34b3..176461aeba7 100644
--- a/doc/user/project/repository/mirror/index.md
+++ b/doc/user/project/repository/mirror/index.md
@@ -41,7 +41,7 @@ Prerequisite:
- If your mirror connects with `ssh://`, the host key must be detectable on the server,
or you must have a local copy of the key.
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Settings > Repository**.
1. Expand **Mirroring repositories**.
1. Enter a **Git repository URL**. For security reasons, the URL to the original
@@ -89,7 +89,7 @@ Prerequisite:
- You must have at least the Maintainer role for the project.
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Settings > Repository**.
1. Expand **Mirroring repositories**.
1. Scroll to **Mirrored repositories** and identify the mirror to update.
@@ -141,7 +141,7 @@ When you mirror a repository and select the **SSH public key** as your
authentication method, GitLab generates a public key for you. The non-GitLab server
needs this key to establish trust with your GitLab repository. To copy your SSH public key:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Settings > Repository**.
1. Expand **Mirroring repositories**.
1. Scroll to **Mirrored repositories**.
@@ -249,7 +249,7 @@ If you receive this error after creating a new project using
Check if the repository owner is specified in the URL of your mirrored repository:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Settings > Repository**.
1. Expand **Mirroring repositories**.
1. If no repository owner is specified, delete and add the URL again in this format,
diff --git a/doc/user/project/repository/mirror/pull.md b/doc/user/project/repository/mirror/pull.md
index d0f2b9a8088..159580dcfa5 100644
--- a/doc/user/project/repository/mirror/pull.md
+++ b/doc/user/project/repository/mirror/pull.md
@@ -61,7 +61,7 @@ Prerequisite:
with the `repo` scope. If 2FA is enabled, this personal access
token serves as your GitHub password.
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Settings > Repository**.
1. Expand **Mirroring repositories**.
1. Enter the **Git repository URL**. Include the username
diff --git a/doc/user/project/repository/mirror/push.md b/doc/user/project/repository/mirror/push.md
index c00ebf415c9..10bdc54ecee 100644
--- a/doc/user/project/repository/mirror/push.md
+++ b/doc/user/project/repository/mirror/push.md
@@ -33,7 +33,7 @@ section.
To set up push mirroring for an existing project:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Settings > Repository**.
1. Expand **Mirroring repositories**.
1. Enter a repository URL.
diff --git a/doc/user/project/repository/push_rules.md b/doc/user/project/repository/push_rules.md
index 46a9585604e..90d2fdb89d0 100644
--- a/doc/user/project/repository/push_rules.md
+++ b/doc/user/project/repository/push_rules.md
@@ -36,7 +36,7 @@ Prerequisite:
To create global push rules:
-1. On the top bar, select **Menu > Admin**.
+1. On the top bar, select **Main menu > Admin**.
1. On the left sidebar, select **Push Rules**.
1. Expand **Push rules**.
1. Set the rule you want.
@@ -48,7 +48,7 @@ The push rule of an individual project overrides the global push rule.
To override global push rules for a specific project, or to update the rules
for an existing project to match new global push rules:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Settings > Repository**.
1. Expand **Push rules**.
1. Set the rule you want.
diff --git a/doc/user/project/settings/index.md b/doc/user/project/settings/index.md
index 900e2bd1ca9..dd5cc6b89ff 100644
--- a/doc/user/project/settings/index.md
+++ b/doc/user/project/settings/index.md
@@ -13,7 +13,7 @@ Use the **Settings** page to manage the configuration options in your [project](
You must have at least the Maintainer role to view project settings.
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects > View all projects** and find your project.
1. On the left sidebar, select **Settings > General**.
1. To display all settings in a section, select **Expand**.
1. Optional. Use the search box to find a setting.
@@ -23,7 +23,7 @@ You must have at least the Maintainer role to view project settings.
Use the project general settings to edit your project details.
1. Sign in to GitLab with at least the Maintainer role.
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects > View all projects** and find your project.
1. On the left sidebar, select **Settings > General**.
1. In the **Project name** text box, enter your project name.
1. In the **Project description** text box, enter your project description.
@@ -35,7 +35,7 @@ Use topics to categorize projects and find similar new projects.
To assign topics to a project:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects > View all projects** and find your project.
1. On the left sidebar, select **Settings** > **General**.
1. In the **Topics** text box, enter the project topics. Popular topics are suggested as you type.
1. Select **Save changes**.
@@ -226,7 +226,7 @@ This alternative ensures the compliance pipeline does not re-start the parent pi
To configure visibility, features, and permissions for a project:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects > View all projects** and find your project.
1. On the left sidebar, select **Settings > General**.
1. Expand the **Visibility, project features, permissions** section.
1. To change the project visibility, select the dropdown list. If you select to **Public**, you limit access to some features to **Only Project Members**.
@@ -286,7 +286,7 @@ In some environments, users can submit a [CVE identifier request](../../applicat
To disable the CVE identifier request option in issues in your project:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects > View all projects** and find your project.
1. On the left sidebar, select **Settings > General**.
1. Expand the **Visibility, project features, permissions** section.
1. Under **Issues**, turn off the **CVE ID requests in the issue sidebar** toggle.
@@ -298,7 +298,7 @@ Prerequisites:
- You must be an Owner of the project to disable email notifications related to the project.
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects > View all projects** and find your project.
1. On the left sidebar, select **Settings > General**.
1. Expand the **Visibility, project features, permissions** section.
1. Clear the **Disable email notifications** checkbox.
@@ -339,7 +339,7 @@ other features are read-only. Archived projects are also hidden from project lis
To archive a project:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects > View all projects** and find your project.
1. On the left sidebar, select **Settings > General**.
1. Expand **Advanced**.
1. In the **Archive project** section, select **Archive project**.
@@ -355,7 +355,7 @@ Prerequisites:
- To unarchive a project, you must be an administrator or a project Owner.
1. Find the archived project.
- 1. On the top bar, select **Menu > Project**.
+ 1. On the top bar, select **Main menu > Projects > View all projects**.
1. Select **Explore projects**.
1. In the **Sort projects** dropdown list, select **Show archived projects**.
1. In the **Filter by name** field, enter the project name.
@@ -380,7 +380,7 @@ When you change the repository path, users may experience issues if they push to
To rename a repository:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects > View all projects** and find your project.
1. On the left sidebar, select **Settings > General**.
1. Expand the **Advanced** section.
1. In the **Change path** text box, edit the path.
@@ -402,7 +402,7 @@ Prerequisites:
To transfer a project:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects > View all projects** and find your project.
1. On the left sidebar, select **Settings > General**.
1. Expand **Advanced**.
1. Under **Transfer project**, choose the namespace to transfer the project to.
@@ -433,7 +433,7 @@ Prerequisite:
To delete a project:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects > View all projects** and find your project.
1. On the left sidebar, select **Settings > General**.
1. Expand **Advanced**.
1. In the "Delete project" section, select **Delete project**.
@@ -472,7 +472,7 @@ Prerequisites:
To immediately delete a project marked for deletion:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects > View all projects** and find your project.
1. On the left sidebar, select **Settings > General**.
1. Expand **Advanced**.
1. In the "Permanently delete project" section, select **Delete project**.
@@ -504,7 +504,7 @@ To restore the fork relationship, [use the API](../../../api/projects.md#create-
To remove a fork relationship:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects > View all projects** and find your project.
1. On the left sidebar, select **Settings > General**.
1. Expand **Advanced**.
1. In the **Remove fork relationship** section, select **Remove fork relationship**.
diff --git a/doc/user/project/web_ide/index.md b/doc/user/project/web_ide/index.md
index 5a4e300a210..2a197c733cf 100644
--- a/doc/user/project/web_ide/index.md
+++ b/doc/user/project/web_ide/index.md
@@ -260,7 +260,7 @@ a `main` entry point inside the Web IDE.
Live Preview is enabled for all projects on GitLab.com. If you are an administrator
of a self-managed GitLab instance, and you want to enable Live Preview:
-1. On the top bar, select **Menu > Admin**.
+1. On the top bar, select **Main menu > Admin**.
1. On the left sidebar, select **Settings > General**.
1. Scroll to **Web IDE** and select **Expand**:
![Administrator Live Preview setting](img/admin_live_preview_v13_0.png)
diff --git a/doc/user/project/wiki/group.md b/doc/user/project/wiki/group.md
index a3ba5789d39..03838a62d59 100644
--- a/doc/user/project/wiki/group.md
+++ b/doc/user/project/wiki/group.md
@@ -29,7 +29,7 @@ and higher can edit group wikis. Group wiki repositories can be moved using the
To access a group wiki:
-1. On the top bar, select **Menu > Groups** and find your group.
+1. On the top bar, select **Main menu > Groups** and find your group.
1. To display the wiki, either:
- On the left sidebar, select **Wiki**.
- On any page in the project, use the <kbd>g</kbd> + <kbd>w</kbd>
@@ -69,7 +69,7 @@ can enable or disable a group wiki through the group settings.
To open group settings:
-1. On the top bar, select **Menu > Groups** and find your group.
+1. On the top bar, select **Main menu > Groups** and find your group.
1. On the left sidebar, select **Settings > General**.
1. Expand **Permissions and group features**.
1. Scroll to **Wiki** and select one of these options:
diff --git a/doc/user/project/wiki/index.md b/doc/user/project/wiki/index.md
index c7f675417bb..dbb4c0ce097 100644
--- a/doc/user/project/wiki/index.md
+++ b/doc/user/project/wiki/index.md
@@ -31,7 +31,7 @@ with sibling pages listed in alphabetical order. To view a list of all pages, se
To access a project wiki:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. To display the wiki, either:
- On the left sidebar, select **Wiki**.
- On any page in the project, use the <kbd>g</kbd> + <kbd>w</kbd>
@@ -284,7 +284,7 @@ You can disable group wikis from the [group settings](group.md#configure-group-w
To add a link to an external wiki from a project's left sidebar:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Settings > Integrations**.
1. Select **External wiki**.
1. Add the URL to your external wiki.
@@ -300,7 +300,7 @@ To hide the internal wiki from the sidebar, [disable the project's wiki](#disabl
To hide the link to an external wiki:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Settings > Integrations**.
1. Select **External wiki**.
1. In the **Enable integration** section, clear the **Active** checkbox.
@@ -310,7 +310,7 @@ To hide the link to an external wiki:
To disable a project's internal wiki:
-1. On the top bar, select **Menu > Projects** and find your project.
+1. On the top bar, select **Main menu > Projects** and find your project.
1. Go to your project and select **Settings > General**.
1. Expand **Visibility, project features, permissions**.
1. Scroll down to find **Wiki** and toggle it off (in gray).
diff --git a/doc/user/project/working_with_projects.md b/doc/user/project/working_with_projects.md
index 2501fa8b45c..ee85c079f04 100644
--- a/doc/user/project/working_with_projects.md
+++ b/doc/user/project/working_with_projects.md
@@ -11,22 +11,9 @@ code are saved in projects, and most features are in the scope of projects.
## View projects
-To explore projects:
+To view projects, on the top bar, select **Main menu > Projects > View all projects**.
-1. On the top bar, select **Menu > Projects**.
-1. Select **Explore projects**.
-
-The **Projects** page shows a list of projects, sorted by last updated date.
-
-- To view projects with the most [stars](#star-a-project), select **Most stars**.
-- To view projects with the largest number of comments in the past month, select **Trending**.
-
-NOTE:
-The **Explore projects** tab is visible to unauthenticated users unless the
-[**Public** visibility level](../admin_area/settings/visibility_and_access_controls.md#restrict-visibility-levels)
-is restricted. Then the tab is visible only to signed-in users.
-
-### Who can view the **Projects** page
+### Who can view the Projects page
When you select a project, the project landing page shows the project contents.
@@ -53,11 +40,16 @@ visit the `/projects/:id` URL in your browser or other tool accessing the projec
To explore project topics:
-1. On the top bar, select **Menu > Projects**.
-1. Select **Explore topics**.
+1. On the top bar, select **Main menu > Projects > View all projects**.
+1. Select the **Explore topics** tab.
+1. To view projects associated with a topic, select a topic.
+
+The **Explore topics** tab shows a list of topics sorted by the number of associated projects.
-The **Projects** page shows list of topics sorted by the number of associated projects.
-To view projects associated with a topic, select a topic from the list.
+NOTE:
+The **Explore projects** tab is visible to unauthenticated users unless the
+[**Public** visibility level](../admin_area/settings/visibility_and_access_controls.md#restrict-visibility-levels)
+is restricted. Then the tab is visible only to signed-in users.
You can assign topics to a project on the [Project Settings page](settings/index.md#assign-topics-to-a-project).
@@ -68,8 +60,9 @@ If you're an instance administrator, you can administer all project topics from
To create a project in GitLab:
-1. On the top bar, select **Menu > Project > Create new project**.
-1. On the **Create new project** page, choose if you want to:
+1. On the top bar, select **Main menu > Projects > View all projects**.
+1. On the right of the page, select **New project**.
+1. On the **Create new project** page, select an option:
- Create a [blank project](#create-a-blank-project).
- Create a project from a:
- [built-in template](#create-a-project-from-a-built-in-template).
@@ -88,7 +81,8 @@ To create a project in GitLab:
To create a blank project:
-1. On the top bar, select **Menu > Projects > Create new project**.
+1. On the top bar, select **Main menu > Projects > View all projects**.
+1. On the right of the page, select **New project**.
1. Select **Create blank project**.
1. Enter the project details:
- In the **Project name** field, enter the name of your project. You cannot use special characters at
@@ -119,7 +113,8 @@ Anyone can [contribute a built-in template](../../development/project_templates.
To create a project from a built-in template:
-1. On the top bar, select **Menu > Projects > Create new project**.
+1. On the top bar, select **Main menu > Projects > View all projects**.
+1. On the right of the page, select **New project**.
1. Select **Create from template**.
1. Select the **Built-in** tab.
1. From the list of templates:
@@ -145,7 +140,8 @@ Custom project templates are available at:
- The [instance-level](../../user/admin_area/custom_project_templates.md)
- The [group-level](../../user/group/custom_project_templates.md)
-1. On the top bar, select **Menu > Projects > Create new project**.
+1. On the top bar, select **Main menu > Projects > View all projects**.
+1. On the right of the page, select **New project**.
1. Select **Create from template**.
1. Select the **Instance** or **Group** tab.
1. From the list of templates:
@@ -171,7 +167,8 @@ HIPAA Audit Protocol published by the U.S Department of Health and Human Service
To create a project from the HIPAA Audit Protocol template:
-1. On the top bar, select **Menu > Projects > Create new project**.
+1. On the top bar, select **Main menu > Projects > View all projects**.
+1. On the right of the page, select **New project**.
1. Select **Create from template**.
1. Select the **Built-in** tab.
1. Locate the **HIPAA Audit Protocol** template:
@@ -210,8 +207,7 @@ Prerequisites:
[added to your GitLab account](../ssh.md#add-an-ssh-key-to-your-gitlab-account).
- You must have permission to add new projects to a namespace. To check if you have permission:
- 1. On the top bar, select **Menu > Projects**.
- 1. Select **Groups**.
+ 1. On the top bar, select **Main menu > Groups > View all groups**.
1. Select a group.
1. Confirm that **New project** is visible in the upper right
corner. Contact your GitLab
@@ -258,15 +254,14 @@ You can add a star to projects you use frequently to make them easier to find.
To add a star to a project:
-1. On the top bar, select **Menu > Projects**.
-1. Select **Your projects** or **Explore projects**.
+1. On the top bar, select **Main menu > Projects > View all projects**.
1. Select a project.
1. In the upper right corner of the page, select **Star**.
## View starred projects
-1. On the top bar, select **Menu > Projects**.
-1. Select **Starred projects**.
+1. On the top bar, select **Main menu > Projects > View all projects**.
+1. Select the **Starred projects** tab.
1. GitLab displays information about your starred projects, including:
- Project description, including name, description, and icon.
@@ -284,7 +279,7 @@ called `my-project` under your username, the project is created at `https://gitl
To view your personal projects:
-1. On the top bar, select **Menu > Projects > Your Projects**.
+1. On the top bar, select **Main menu > Projects > View all projects**.
1. Under **Your projects**, select **Personal**.
## Delete a project
@@ -294,8 +289,7 @@ you can [enable delayed project removal](../group/manage.md#enable-delayed-proje
To delete a project:
-1. On the top bar, select **Menu > Projects**.
-1. Select **Your projects** or **Explore projects**.
+1. On the top bar, select **Main menu > Projects > View all projects**.
1. Select a project.
1. Select **Settings > General**.
1. Expand the **Advanced** section.
@@ -315,7 +309,7 @@ projects within that group are not deleted immediately, but only after a delay.
To view a list of all projects that are pending deletion:
-1. On the top bar, select **Menu > Projects > Explore projects**.
+1. On the top bar, select **Main menu > Projects > View all projects**.
1. Based on your GitLab version:
- GitLab 14.6 and later: select the **Pending deletion** tab.
- GitLab 14.5 and earlier: select the **Deleted projects** tab.
@@ -330,8 +324,7 @@ Each project in the list shows:
To view the activity of a project:
-1. On the top bar, select **Menu > Projects**.
-1. Select **Your projects** or **Explore projects**.
+1. On the top bar, select **Main menu > Projects > View all projects**.
1. Select a project.
1. On the left sidebar, select **Project information > Activity**.
1. Select a tab to view the type of project activity.
@@ -366,8 +359,7 @@ member and cannot contribute.
To leave a project:
-1. On the top bar, select **Menu > Projects**.
-1. Select **Your projects** or **Explore projects**.
+1. On the top bar, select **Main menu > Projects > View all projects**.
1. Select a project.
1. Select **Leave project**. The **Leave project** option only displays
on the project dashboard when a project is part of a group under a
diff --git a/doc/user/usage_quotas.md b/doc/user/usage_quotas.md
index 56220fb9906..1f3a69944e8 100644
--- a/doc/user/usage_quotas.md
+++ b/doc/user/usage_quotas.md
@@ -61,7 +61,7 @@ Prerequisites:
- To view storage usage for a namespace, you must have the Owner role for the namespace.
1. Go to your project or namespace:
- - For a project, on the top bar, select **Menu > Projects** and find your project.
+ - For a project, on the top bar, select **Main menu > Projects > View all projects** and find your project.
- For a namespace, enter the URL in your browser's toolbar.
1. From the left sidebar, select **Settings > Usage Quotas**.
1. Select the **Storage** tab.
diff --git a/lib/gitlab/base_doorkeeper_controller.rb b/lib/gitlab/base_doorkeeper_controller.rb
index 81b01395542..c8520993b8e 100644
--- a/lib/gitlab/base_doorkeeper_controller.rb
+++ b/lib/gitlab/base_doorkeeper_controller.rb
@@ -3,6 +3,7 @@
# This is a base controller for doorkeeper.
# It adds the `can?` helper used in the views.
module Gitlab
+ # rubocop:disable Rails/ApplicationController
class BaseDoorkeeperController < ActionController::Base
include Gitlab::Allowable
include EnforcesTwoFactorAuthentication
@@ -12,4 +13,5 @@ module Gitlab
helper_method :can?
end
+ # rubocop:enable Rails/ApplicationController
end
diff --git a/lib/gitlab/ci/parsers/security/validators/schema_validator.rb b/lib/gitlab/ci/parsers/security/validators/schema_validator.rb
index d776b6060d5..28d6620e5c4 100644
--- a/lib/gitlab/ci/parsers/security/validators/schema_validator.rb
+++ b/lib/gitlab/ci/parsers/security/validators/schema_validator.rb
@@ -7,14 +7,14 @@ module Gitlab
module Validators
class SchemaValidator
SUPPORTED_VERSIONS = {
- cluster_image_scanning: %w[14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3],
- container_scanning: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3],
- coverage_fuzzing: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3],
- dast: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3],
- api_fuzzing: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3],
- dependency_scanning: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3],
- sast: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3],
- secret_detection: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3]
+ cluster_image_scanning: %w[14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0],
+ container_scanning: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0],
+ coverage_fuzzing: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0],
+ dast: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0],
+ api_fuzzing: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0],
+ dependency_scanning: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0],
+ sast: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0],
+ secret_detection: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0]
}.freeze
VERSIONS_TO_REMOVE_IN_16_0 = [].freeze
diff --git a/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/cluster-image-scanning-report-format.json b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/cluster-image-scanning-report-format.json
new file mode 100644
index 00000000000..7ccb39a2b8e
--- /dev/null
+++ b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/cluster-image-scanning-report-format.json
@@ -0,0 +1,946 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/raw/master/dist/cluster-image-scanning-report-format.json",
+ "title": "Report format for GitLab Cluster Image Scanning",
+ "description": "This schema provides the the report format for Cluster Image Scanning (https://docs.gitlab.com/ee/user/application_security/cluster_image_scanning/).",
+ "definitions": {
+ "detail_type": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/named_list"
+ },
+ {
+ "$ref": "#/definitions/list"
+ },
+ {
+ "$ref": "#/definitions/table"
+ },
+ {
+ "$ref": "#/definitions/text"
+ },
+ {
+ "$ref": "#/definitions/url"
+ },
+ {
+ "$ref": "#/definitions/code"
+ },
+ {
+ "$ref": "#/definitions/value"
+ },
+ {
+ "$ref": "#/definitions/diff"
+ },
+ {
+ "$ref": "#/definitions/markdown"
+ },
+ {
+ "$ref": "#/definitions/commit"
+ },
+ {
+ "$ref": "#/definitions/file_location"
+ },
+ {
+ "$ref": "#/definitions/module_location"
+ }
+ ]
+ },
+ "text_value": {
+ "type": "string"
+ },
+ "named_field": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/text_value",
+ "minLength": 1
+ },
+ "description": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "named_list": {
+ "type": "object",
+ "description": "An object with named and typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "named-list"
+ },
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "allOf": [
+ {
+ "$ref": "#/definitions/named_field"
+ },
+ {
+ "$ref": "#/definitions/detail_type"
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "list": {
+ "type": "object",
+ "description": "A list of typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "list"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ },
+ "table": {
+ "type": "object",
+ "description": "A table of typed fields",
+ "required": [
+ "type",
+ "rows"
+ ],
+ "properties": {
+ "type": {
+ "const": "table"
+ },
+ "header": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ },
+ "rows": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ }
+ },
+ "text": {
+ "type": "object",
+ "description": "Raw text",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "text"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "url": {
+ "type": "object",
+ "description": "A single URL",
+ "required": [
+ "type",
+ "href"
+ ],
+ "properties": {
+ "type": {
+ "const": "url"
+ },
+ "text": {
+ "$ref": "#/definitions/text_value"
+ },
+ "href": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "http://mysite.com"
+ ]
+ }
+ }
+ },
+ "code": {
+ "type": "object",
+ "description": "A codeblock",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "code"
+ },
+ "value": {
+ "type": "string"
+ },
+ "lang": {
+ "type": "string",
+ "description": "A programming language"
+ }
+ }
+ },
+ "value": {
+ "type": "object",
+ "description": "A field that can store a range of types of value",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "value"
+ },
+ "value": {
+ "type": [
+ "number",
+ "string",
+ "boolean"
+ ]
+ }
+ }
+ },
+ "diff": {
+ "type": "object",
+ "description": "A diff",
+ "required": [
+ "type",
+ "before",
+ "after"
+ ],
+ "properties": {
+ "type": {
+ "const": "diff"
+ },
+ "before": {
+ "type": "string"
+ },
+ "after": {
+ "type": "string"
+ }
+ }
+ },
+ "markdown": {
+ "type": "object",
+ "description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "markdown"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value",
+ "examples": [
+ "Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)"
+ ]
+ }
+ }
+ },
+ "commit": {
+ "type": "object",
+ "description": "A commit/tag/branch within the GitLab project",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "commit"
+ },
+ "value": {
+ "type": "string",
+ "description": "The commit SHA",
+ "minLength": 1
+ }
+ }
+ },
+ "file_location": {
+ "type": "object",
+ "description": "A location within a file in the project",
+ "required": [
+ "type",
+ "file_name",
+ "line_start"
+ ],
+ "properties": {
+ "type": {
+ "const": "file-location"
+ },
+ "file_name": {
+ "type": "string",
+ "minLength": 1
+ },
+ "line_start": {
+ "type": "integer"
+ },
+ "line_end": {
+ "type": "integer"
+ }
+ }
+ },
+ "module_location": {
+ "type": "object",
+ "description": "A location within a binary module of the form module+relative_offset",
+ "required": [
+ "type",
+ "module_name",
+ "offset"
+ ],
+ "properties": {
+ "type": {
+ "const": "module-location"
+ },
+ "module_name": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "compiled_binary"
+ ]
+ },
+ "offset": {
+ "type": "integer",
+ "examples": [
+ 100
+ ]
+ }
+ }
+ }
+ },
+ "self": {
+ "version": "15.0.0"
+ },
+ "required": [
+ "scan",
+ "version",
+ "vulnerabilities"
+ ],
+ "additionalProperties": true,
+ "properties": {
+ "scan": {
+ "type": "object",
+ "required": [
+ "analyzer",
+ "end_time",
+ "scanner",
+ "start_time",
+ "status",
+ "type"
+ ],
+ "properties": {
+ "end_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2020-01-28T03:26:02"
+ ]
+ },
+ "messages": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Communication intended for the initiator of a scan.",
+ "required": [
+ "level",
+ "value"
+ ],
+ "properties": {
+ "level": {
+ "type": "string",
+ "description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
+ "enum": [
+ "info",
+ "warn",
+ "fatal"
+ ],
+ "examples": [
+ "info"
+ ]
+ },
+ "value": {
+ "type": "string",
+ "description": "The message to communicate.",
+ "minLength": 1,
+ "examples": [
+ "Permission denied, scanning aborted"
+ ]
+ }
+ }
+ }
+ },
+ "analyzer": {
+ "type": "object",
+ "description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "gitlab-dast"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the analyzer, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "GitLab DAST"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "pattern": "^https?://.+",
+ "description": "A link to more information about the analyzer.",
+ "examples": [
+ "https://docs.gitlab.com/ee/user/application_security/dast"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the analyzer.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ }
+ }
+ },
+ "scanner": {
+ "type": "object",
+ "description": "Object defining the scanner used to perform the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the scanner.",
+ "minLength": 1,
+ "examples": [
+ "my-sast-scanner"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the scanner, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "My SAST Scanner"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "description": "A link to more information about the scanner.",
+ "examples": [
+ "https://scanner.url"
+ ]
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the scanner.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the scanner.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ }
+ }
+ },
+ "start_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2020-02-14T16:01:59"
+ ]
+ },
+ "status": {
+ "type": "string",
+ "description": "Result of the scan.",
+ "enum": [
+ "success",
+ "failure"
+ ]
+ },
+ "type": {
+ "type": "string",
+ "description": "Type of the scan.",
+ "enum": [
+ "cluster_image_scanning"
+ ]
+ }
+ }
+ },
+ "schema": {
+ "type": "string",
+ "description": "URI pointing to the validating security report schema.",
+ "pattern": "^https?://.+"
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the schema to which the JSON report conforms.",
+ "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
+ },
+ "vulnerabilities": {
+ "type": "array",
+ "description": "Array of vulnerability objects.",
+ "items": {
+ "type": "object",
+ "description": "Describes the vulnerability using GitLab Flavored Markdown",
+ "required": [
+ "id",
+ "identifiers",
+ "location"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 255,
+ "description": "The name of the vulnerability. This must not include the finding's specific information."
+ },
+ "description": {
+ "type": "string",
+ "maxLength": 1048576,
+ "description": "A long text section describing the vulnerability more fully."
+ },
+ "severity": {
+ "type": "string",
+ "description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
+ "enum": [
+ "Info",
+ "Unknown",
+ "Low",
+ "Medium",
+ "High",
+ "Critical"
+ ]
+ },
+ "solution": {
+ "type": "string",
+ "maxLength": 7000,
+ "description": "Explanation of how to fix the vulnerability."
+ },
+ "identifiers": {
+ "type": "array",
+ "minItems": 1,
+ "description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
+ "items": {
+ "type": "object",
+ "required": [
+ "type",
+ "name",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
+ "minLength": 1
+ },
+ "name": {
+ "type": "string",
+ "description": "Human-readable name of the identifier.",
+ "minLength": 1
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the identifier's documentation.",
+ "pattern": "^https?://.+"
+ },
+ "value": {
+ "type": "string",
+ "description": "Value of the identifier, for matching purpose.",
+ "minLength": 1
+ }
+ }
+ }
+ },
+ "links": {
+ "type": "array",
+ "description": "An array of references to external documentation or articles that describe the vulnerability.",
+ "items": {
+ "type": "object",
+ "required": [
+ "url"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the vulnerability details link."
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the vulnerability details document.",
+ "pattern": "^https?://.+"
+ }
+ }
+ }
+ },
+ "details": {
+ "$ref": "#/definitions/named_list/properties/items"
+ },
+ "tracking": {
+ "description": "Describes how this vulnerability should be tracked as the project changes.",
+ "oneOf": [
+ {
+ "description": "Declares that a series of items should be tracked using source-specific tracking methods.",
+ "required": [
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "source"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "description": "An item that should be tracked using source-specific tracking methods.",
+ "type": "object",
+ "required": [
+ "signatures"
+ ],
+ "properties": {
+ "file": {
+ "type": "string",
+ "description": "Path to the file where the vulnerability is located."
+ },
+ "start_line": {
+ "type": "number",
+ "description": "The first line of the file that includes the vulnerability."
+ },
+ "end_line": {
+ "type": "number",
+ "description": "The last line of the file that includes the vulnerability."
+ },
+ "signatures": {
+ "type": "array",
+ "description": "An array of calculated tracking signatures for this tracking item.",
+ "minItems": 1,
+ "items": {
+ "description": "A calculated tracking signature value and metadata.",
+ "required": [
+ "algorithm",
+ "value"
+ ],
+ "properties": {
+ "algorithm": {
+ "type": "string",
+ "description": "The algorithm used to generate the signature."
+ },
+ "value": {
+ "type": "string",
+ "description": "The result of this signature algorithm."
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "Each tracking type must declare its own type."
+ }
+ }
+ },
+ "flags": {
+ "description": "Flags that can be attached to vulnerabilities.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Informational flags identified and assigned to a vulnerability.",
+ "required": [
+ "type",
+ "origin",
+ "description"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Result of the scan.",
+ "enum": [
+ "flagged-as-likely-false-positive"
+ ]
+ },
+ "origin": {
+ "minLength": 1,
+ "description": "Tool that issued the flag.",
+ "type": "string"
+ },
+ "description": {
+ "minLength": 1,
+ "description": "What the flag is about.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "location": {
+ "type": "object",
+ "description": "Identifies the vulnerability's location.",
+ "required": [
+ "dependency",
+ "image",
+ "kubernetes_resource"
+ ],
+ "properties": {
+ "dependency": {
+ "type": "object",
+ "description": "Describes the dependency of a project where the vulnerability is located.",
+ "required": [
+ "package",
+ "version"
+ ],
+ "properties": {
+ "package": {
+ "type": "object",
+ "description": "Provides information on the package where the vulnerability is located.",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the package where the vulnerability is located."
+ }
+ }
+ },
+ "version": {
+ "type": "string",
+ "description": "Version of the vulnerable package."
+ },
+ "iid": {
+ "description": "ID that identifies the dependency in the scope of a dependency file.",
+ "type": "number"
+ },
+ "direct": {
+ "type": "boolean",
+ "description": "Tells whether this is a direct, top-level dependency of the scanned project."
+ },
+ "dependency_path": {
+ "type": "array",
+ "description": "Ancestors of the dependency, starting from a direct project dependency, and ending with an immediate parent of the dependency. The dependency itself is excluded from the path. Direct dependencies have no path.",
+ "items": {
+ "type": "object",
+ "required": [
+ "iid"
+ ],
+ "properties": {
+ "iid": {
+ "type": "number",
+ "description": "ID that is unique in the scope of a parent object, and specific to the resource type."
+ }
+ }
+ }
+ }
+ }
+ },
+ "operating_system": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 255,
+ "description": "The operating system that contains the vulnerable package."
+ },
+ "image": {
+ "type": "string",
+ "minLength": 1,
+ "description": "The analyzed Docker image.",
+ "examples": [
+ "index.docker.io/library/nginx:1.21"
+ ]
+ },
+ "kubernetes_resource": {
+ "type": "object",
+ "description": "The specific Kubernetes resource that was scanned.",
+ "required": [
+ "namespace",
+ "kind",
+ "name",
+ "container_name"
+ ],
+ "properties": {
+ "namespace": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 255,
+ "description": "The Kubernetes namespace the resource that had its image scanned.",
+ "examples": [
+ "default",
+ "staging",
+ "production"
+ ]
+ },
+ "kind": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 255,
+ "description": "The Kubernetes kind the resource that had its image scanned.",
+ "examples": [
+ "Deployment",
+ "DaemonSet"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 255,
+ "description": "The name of the resource that had its image scanned.",
+ "examples": [
+ "nginx-ingress"
+ ]
+ },
+ "container_name": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 255,
+ "description": "The name of the container that had its image scanned.",
+ "examples": [
+ "nginx"
+ ]
+ },
+ "agent_id": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 255,
+ "description": "The GitLab ID of the Kubernetes Agent which performed the scan.",
+ "examples": [
+ "1234"
+ ]
+ },
+ "cluster_id": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 255,
+ "description": "The GitLab ID of the Kubernetes cluster when using cluster integration.",
+ "examples": [
+ "1234"
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "remediations": {
+ "type": "array",
+ "description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
+ "items": {
+ "type": "object",
+ "required": [
+ "fixes",
+ "summary",
+ "diff"
+ ],
+ "properties": {
+ "fixes": {
+ "type": "array",
+ "description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
+ "items": {
+ "type": "object",
+ "required": [
+ "id"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ }
+ }
+ }
+ },
+ "summary": {
+ "type": "string",
+ "minLength": 1,
+ "description": "An overview of how the vulnerabilities were fixed."
+ },
+ "diff": {
+ "type": "string",
+ "minLength": 1,
+ "description": "A base64-encoded remediation code diff, compatible with git apply."
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/container-scanning-report-format.json b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/container-scanning-report-format.json
new file mode 100644
index 00000000000..2517832853e
--- /dev/null
+++ b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/container-scanning-report-format.json
@@ -0,0 +1,880 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/raw/master/dist/container-scanning-report-format.json",
+ "title": "Report format for GitLab Container Scanning",
+ "description": "This schema provides the the report format for Container Scanning (https://docs.gitlab.com/ee/user/application_security/container_scanning).",
+ "definitions": {
+ "detail_type": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/named_list"
+ },
+ {
+ "$ref": "#/definitions/list"
+ },
+ {
+ "$ref": "#/definitions/table"
+ },
+ {
+ "$ref": "#/definitions/text"
+ },
+ {
+ "$ref": "#/definitions/url"
+ },
+ {
+ "$ref": "#/definitions/code"
+ },
+ {
+ "$ref": "#/definitions/value"
+ },
+ {
+ "$ref": "#/definitions/diff"
+ },
+ {
+ "$ref": "#/definitions/markdown"
+ },
+ {
+ "$ref": "#/definitions/commit"
+ },
+ {
+ "$ref": "#/definitions/file_location"
+ },
+ {
+ "$ref": "#/definitions/module_location"
+ }
+ ]
+ },
+ "text_value": {
+ "type": "string"
+ },
+ "named_field": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/text_value",
+ "minLength": 1
+ },
+ "description": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "named_list": {
+ "type": "object",
+ "description": "An object with named and typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "named-list"
+ },
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "allOf": [
+ {
+ "$ref": "#/definitions/named_field"
+ },
+ {
+ "$ref": "#/definitions/detail_type"
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "list": {
+ "type": "object",
+ "description": "A list of typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "list"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ },
+ "table": {
+ "type": "object",
+ "description": "A table of typed fields",
+ "required": [
+ "type",
+ "rows"
+ ],
+ "properties": {
+ "type": {
+ "const": "table"
+ },
+ "header": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ },
+ "rows": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ }
+ },
+ "text": {
+ "type": "object",
+ "description": "Raw text",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "text"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "url": {
+ "type": "object",
+ "description": "A single URL",
+ "required": [
+ "type",
+ "href"
+ ],
+ "properties": {
+ "type": {
+ "const": "url"
+ },
+ "text": {
+ "$ref": "#/definitions/text_value"
+ },
+ "href": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "http://mysite.com"
+ ]
+ }
+ }
+ },
+ "code": {
+ "type": "object",
+ "description": "A codeblock",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "code"
+ },
+ "value": {
+ "type": "string"
+ },
+ "lang": {
+ "type": "string",
+ "description": "A programming language"
+ }
+ }
+ },
+ "value": {
+ "type": "object",
+ "description": "A field that can store a range of types of value",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "value"
+ },
+ "value": {
+ "type": [
+ "number",
+ "string",
+ "boolean"
+ ]
+ }
+ }
+ },
+ "diff": {
+ "type": "object",
+ "description": "A diff",
+ "required": [
+ "type",
+ "before",
+ "after"
+ ],
+ "properties": {
+ "type": {
+ "const": "diff"
+ },
+ "before": {
+ "type": "string"
+ },
+ "after": {
+ "type": "string"
+ }
+ }
+ },
+ "markdown": {
+ "type": "object",
+ "description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "markdown"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value",
+ "examples": [
+ "Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)"
+ ]
+ }
+ }
+ },
+ "commit": {
+ "type": "object",
+ "description": "A commit/tag/branch within the GitLab project",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "commit"
+ },
+ "value": {
+ "type": "string",
+ "description": "The commit SHA",
+ "minLength": 1
+ }
+ }
+ },
+ "file_location": {
+ "type": "object",
+ "description": "A location within a file in the project",
+ "required": [
+ "type",
+ "file_name",
+ "line_start"
+ ],
+ "properties": {
+ "type": {
+ "const": "file-location"
+ },
+ "file_name": {
+ "type": "string",
+ "minLength": 1
+ },
+ "line_start": {
+ "type": "integer"
+ },
+ "line_end": {
+ "type": "integer"
+ }
+ }
+ },
+ "module_location": {
+ "type": "object",
+ "description": "A location within a binary module of the form module+relative_offset",
+ "required": [
+ "type",
+ "module_name",
+ "offset"
+ ],
+ "properties": {
+ "type": {
+ "const": "module-location"
+ },
+ "module_name": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "compiled_binary"
+ ]
+ },
+ "offset": {
+ "type": "integer",
+ "examples": [
+ 100
+ ]
+ }
+ }
+ }
+ },
+ "self": {
+ "version": "15.0.0"
+ },
+ "required": [
+ "scan",
+ "version",
+ "vulnerabilities"
+ ],
+ "additionalProperties": true,
+ "properties": {
+ "scan": {
+ "type": "object",
+ "required": [
+ "analyzer",
+ "end_time",
+ "scanner",
+ "start_time",
+ "status",
+ "type"
+ ],
+ "properties": {
+ "end_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2020-01-28T03:26:02"
+ ]
+ },
+ "messages": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Communication intended for the initiator of a scan.",
+ "required": [
+ "level",
+ "value"
+ ],
+ "properties": {
+ "level": {
+ "type": "string",
+ "description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
+ "enum": [
+ "info",
+ "warn",
+ "fatal"
+ ],
+ "examples": [
+ "info"
+ ]
+ },
+ "value": {
+ "type": "string",
+ "description": "The message to communicate.",
+ "minLength": 1,
+ "examples": [
+ "Permission denied, scanning aborted"
+ ]
+ }
+ }
+ }
+ },
+ "analyzer": {
+ "type": "object",
+ "description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "gitlab-dast"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the analyzer, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "GitLab DAST"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "pattern": "^https?://.+",
+ "description": "A link to more information about the analyzer.",
+ "examples": [
+ "https://docs.gitlab.com/ee/user/application_security/dast"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the analyzer.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ }
+ }
+ },
+ "scanner": {
+ "type": "object",
+ "description": "Object defining the scanner used to perform the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the scanner.",
+ "minLength": 1,
+ "examples": [
+ "my-sast-scanner"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the scanner, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "My SAST Scanner"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "description": "A link to more information about the scanner.",
+ "examples": [
+ "https://scanner.url"
+ ]
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the scanner.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the scanner.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ }
+ }
+ },
+ "start_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2020-02-14T16:01:59"
+ ]
+ },
+ "status": {
+ "type": "string",
+ "description": "Result of the scan.",
+ "enum": [
+ "success",
+ "failure"
+ ]
+ },
+ "type": {
+ "type": "string",
+ "description": "Type of the scan.",
+ "enum": [
+ "container_scanning"
+ ]
+ }
+ }
+ },
+ "schema": {
+ "type": "string",
+ "description": "URI pointing to the validating security report schema.",
+ "pattern": "^https?://.+"
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the schema to which the JSON report conforms.",
+ "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
+ },
+ "vulnerabilities": {
+ "type": "array",
+ "description": "Array of vulnerability objects.",
+ "items": {
+ "type": "object",
+ "description": "Describes the vulnerability using GitLab Flavored Markdown",
+ "required": [
+ "id",
+ "identifiers",
+ "location"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 255,
+ "description": "The name of the vulnerability. This must not include the finding's specific information."
+ },
+ "description": {
+ "type": "string",
+ "maxLength": 1048576,
+ "description": "A long text section describing the vulnerability more fully."
+ },
+ "severity": {
+ "type": "string",
+ "description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
+ "enum": [
+ "Info",
+ "Unknown",
+ "Low",
+ "Medium",
+ "High",
+ "Critical"
+ ]
+ },
+ "solution": {
+ "type": "string",
+ "maxLength": 7000,
+ "description": "Explanation of how to fix the vulnerability."
+ },
+ "identifiers": {
+ "type": "array",
+ "minItems": 1,
+ "description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
+ "items": {
+ "type": "object",
+ "required": [
+ "type",
+ "name",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
+ "minLength": 1
+ },
+ "name": {
+ "type": "string",
+ "description": "Human-readable name of the identifier.",
+ "minLength": 1
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the identifier's documentation.",
+ "pattern": "^https?://.+"
+ },
+ "value": {
+ "type": "string",
+ "description": "Value of the identifier, for matching purpose.",
+ "minLength": 1
+ }
+ }
+ }
+ },
+ "links": {
+ "type": "array",
+ "description": "An array of references to external documentation or articles that describe the vulnerability.",
+ "items": {
+ "type": "object",
+ "required": [
+ "url"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the vulnerability details link."
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the vulnerability details document.",
+ "pattern": "^https?://.+"
+ }
+ }
+ }
+ },
+ "details": {
+ "$ref": "#/definitions/named_list/properties/items"
+ },
+ "tracking": {
+ "description": "Describes how this vulnerability should be tracked as the project changes.",
+ "oneOf": [
+ {
+ "description": "Declares that a series of items should be tracked using source-specific tracking methods.",
+ "required": [
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "source"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "description": "An item that should be tracked using source-specific tracking methods.",
+ "type": "object",
+ "required": [
+ "signatures"
+ ],
+ "properties": {
+ "file": {
+ "type": "string",
+ "description": "Path to the file where the vulnerability is located."
+ },
+ "start_line": {
+ "type": "number",
+ "description": "The first line of the file that includes the vulnerability."
+ },
+ "end_line": {
+ "type": "number",
+ "description": "The last line of the file that includes the vulnerability."
+ },
+ "signatures": {
+ "type": "array",
+ "description": "An array of calculated tracking signatures for this tracking item.",
+ "minItems": 1,
+ "items": {
+ "description": "A calculated tracking signature value and metadata.",
+ "required": [
+ "algorithm",
+ "value"
+ ],
+ "properties": {
+ "algorithm": {
+ "type": "string",
+ "description": "The algorithm used to generate the signature."
+ },
+ "value": {
+ "type": "string",
+ "description": "The result of this signature algorithm."
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "Each tracking type must declare its own type."
+ }
+ }
+ },
+ "flags": {
+ "description": "Flags that can be attached to vulnerabilities.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Informational flags identified and assigned to a vulnerability.",
+ "required": [
+ "type",
+ "origin",
+ "description"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Result of the scan.",
+ "enum": [
+ "flagged-as-likely-false-positive"
+ ]
+ },
+ "origin": {
+ "minLength": 1,
+ "description": "Tool that issued the flag.",
+ "type": "string"
+ },
+ "description": {
+ "minLength": 1,
+ "description": "What the flag is about.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "location": {
+ "type": "object",
+ "description": "Identifies the vulnerability's location.",
+ "required": [
+ "dependency",
+ "operating_system",
+ "image"
+ ],
+ "properties": {
+ "dependency": {
+ "type": "object",
+ "description": "Describes the dependency of a project where the vulnerability is located.",
+ "required": [
+ "package",
+ "version"
+ ],
+ "properties": {
+ "package": {
+ "type": "object",
+ "description": "Provides information on the package where the vulnerability is located.",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the package where the vulnerability is located."
+ }
+ }
+ },
+ "version": {
+ "type": "string",
+ "description": "Version of the vulnerable package."
+ },
+ "iid": {
+ "description": "ID that identifies the dependency in the scope of a dependency file.",
+ "type": "number"
+ },
+ "direct": {
+ "type": "boolean",
+ "description": "Tells whether this is a direct, top-level dependency of the scanned project."
+ },
+ "dependency_path": {
+ "type": "array",
+ "description": "Ancestors of the dependency, starting from a direct project dependency, and ending with an immediate parent of the dependency. The dependency itself is excluded from the path. Direct dependencies have no path.",
+ "items": {
+ "type": "object",
+ "required": [
+ "iid"
+ ],
+ "properties": {
+ "iid": {
+ "type": "number",
+ "description": "ID that is unique in the scope of a parent object, and specific to the resource type."
+ }
+ }
+ }
+ }
+ }
+ },
+ "operating_system": {
+ "type": "string",
+ "minLength": 1,
+ "description": "The operating system that contains the vulnerable package."
+ },
+ "image": {
+ "type": "string",
+ "minLength": 1,
+ "pattern": "^[^:]+(:\\d+[^:]*)?:[^:]+(:[^:]+)?$",
+ "description": "The analyzed Docker image."
+ },
+ "default_branch_image": {
+ "type": "string",
+ "maxLength": 255,
+ "pattern": "^[a-zA-Z0-9/_.-]+(:\\d+[a-zA-Z0-9/_.-]*)?:[a-zA-Z0-9_.-]+$",
+ "description": "The name of the image on the default branch."
+ }
+ }
+ }
+ }
+ }
+ },
+ "remediations": {
+ "type": "array",
+ "description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
+ "items": {
+ "type": "object",
+ "required": [
+ "fixes",
+ "summary",
+ "diff"
+ ],
+ "properties": {
+ "fixes": {
+ "type": "array",
+ "description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
+ "items": {
+ "type": "object",
+ "required": [
+ "id"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ }
+ }
+ }
+ },
+ "summary": {
+ "type": "string",
+ "minLength": 1,
+ "description": "An overview of how the vulnerabilities were fixed."
+ },
+ "diff": {
+ "type": "string",
+ "minLength": 1,
+ "description": "A base64-encoded remediation code diff, compatible with git apply."
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/coverage-fuzzing-report-format.json b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/coverage-fuzzing-report-format.json
new file mode 100644
index 00000000000..a2f9eb12992
--- /dev/null
+++ b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/coverage-fuzzing-report-format.json
@@ -0,0 +1,836 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/raw/master/dist/coverage-fuzzing-report-format.json",
+ "title": "Report format for GitLab Fuzz Testing",
+ "description": "This schema provides the report format for Coverage Guided Fuzz Testing (https://docs.gitlab.com/ee/user/application_security/coverage_fuzzing).",
+ "definitions": {
+ "detail_type": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/named_list"
+ },
+ {
+ "$ref": "#/definitions/list"
+ },
+ {
+ "$ref": "#/definitions/table"
+ },
+ {
+ "$ref": "#/definitions/text"
+ },
+ {
+ "$ref": "#/definitions/url"
+ },
+ {
+ "$ref": "#/definitions/code"
+ },
+ {
+ "$ref": "#/definitions/value"
+ },
+ {
+ "$ref": "#/definitions/diff"
+ },
+ {
+ "$ref": "#/definitions/markdown"
+ },
+ {
+ "$ref": "#/definitions/commit"
+ },
+ {
+ "$ref": "#/definitions/file_location"
+ },
+ {
+ "$ref": "#/definitions/module_location"
+ }
+ ]
+ },
+ "text_value": {
+ "type": "string"
+ },
+ "named_field": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/text_value",
+ "minLength": 1
+ },
+ "description": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "named_list": {
+ "type": "object",
+ "description": "An object with named and typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "named-list"
+ },
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "allOf": [
+ {
+ "$ref": "#/definitions/named_field"
+ },
+ {
+ "$ref": "#/definitions/detail_type"
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "list": {
+ "type": "object",
+ "description": "A list of typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "list"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ },
+ "table": {
+ "type": "object",
+ "description": "A table of typed fields",
+ "required": [
+ "type",
+ "rows"
+ ],
+ "properties": {
+ "type": {
+ "const": "table"
+ },
+ "header": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ },
+ "rows": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ }
+ },
+ "text": {
+ "type": "object",
+ "description": "Raw text",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "text"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "url": {
+ "type": "object",
+ "description": "A single URL",
+ "required": [
+ "type",
+ "href"
+ ],
+ "properties": {
+ "type": {
+ "const": "url"
+ },
+ "text": {
+ "$ref": "#/definitions/text_value"
+ },
+ "href": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "http://mysite.com"
+ ]
+ }
+ }
+ },
+ "code": {
+ "type": "object",
+ "description": "A codeblock",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "code"
+ },
+ "value": {
+ "type": "string"
+ },
+ "lang": {
+ "type": "string",
+ "description": "A programming language"
+ }
+ }
+ },
+ "value": {
+ "type": "object",
+ "description": "A field that can store a range of types of value",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "value"
+ },
+ "value": {
+ "type": [
+ "number",
+ "string",
+ "boolean"
+ ]
+ }
+ }
+ },
+ "diff": {
+ "type": "object",
+ "description": "A diff",
+ "required": [
+ "type",
+ "before",
+ "after"
+ ],
+ "properties": {
+ "type": {
+ "const": "diff"
+ },
+ "before": {
+ "type": "string"
+ },
+ "after": {
+ "type": "string"
+ }
+ }
+ },
+ "markdown": {
+ "type": "object",
+ "description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "markdown"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value",
+ "examples": [
+ "Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)"
+ ]
+ }
+ }
+ },
+ "commit": {
+ "type": "object",
+ "description": "A commit/tag/branch within the GitLab project",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "commit"
+ },
+ "value": {
+ "type": "string",
+ "description": "The commit SHA",
+ "minLength": 1
+ }
+ }
+ },
+ "file_location": {
+ "type": "object",
+ "description": "A location within a file in the project",
+ "required": [
+ "type",
+ "file_name",
+ "line_start"
+ ],
+ "properties": {
+ "type": {
+ "const": "file-location"
+ },
+ "file_name": {
+ "type": "string",
+ "minLength": 1
+ },
+ "line_start": {
+ "type": "integer"
+ },
+ "line_end": {
+ "type": "integer"
+ }
+ }
+ },
+ "module_location": {
+ "type": "object",
+ "description": "A location within a binary module of the form module+relative_offset",
+ "required": [
+ "type",
+ "module_name",
+ "offset"
+ ],
+ "properties": {
+ "type": {
+ "const": "module-location"
+ },
+ "module_name": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "compiled_binary"
+ ]
+ },
+ "offset": {
+ "type": "integer",
+ "examples": [
+ 100
+ ]
+ }
+ }
+ }
+ },
+ "self": {
+ "version": "15.0.0"
+ },
+ "required": [
+ "scan",
+ "version",
+ "vulnerabilities"
+ ],
+ "additionalProperties": true,
+ "properties": {
+ "scan": {
+ "type": "object",
+ "required": [
+ "analyzer",
+ "end_time",
+ "scanner",
+ "start_time",
+ "status",
+ "type"
+ ],
+ "properties": {
+ "end_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2020-01-28T03:26:02"
+ ]
+ },
+ "messages": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Communication intended for the initiator of a scan.",
+ "required": [
+ "level",
+ "value"
+ ],
+ "properties": {
+ "level": {
+ "type": "string",
+ "description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
+ "enum": [
+ "info",
+ "warn",
+ "fatal"
+ ],
+ "examples": [
+ "info"
+ ]
+ },
+ "value": {
+ "type": "string",
+ "description": "The message to communicate.",
+ "minLength": 1,
+ "examples": [
+ "Permission denied, scanning aborted"
+ ]
+ }
+ }
+ }
+ },
+ "analyzer": {
+ "type": "object",
+ "description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "gitlab-dast"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the analyzer, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "GitLab DAST"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "pattern": "^https?://.+",
+ "description": "A link to more information about the analyzer.",
+ "examples": [
+ "https://docs.gitlab.com/ee/user/application_security/dast"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the analyzer.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ }
+ }
+ },
+ "scanner": {
+ "type": "object",
+ "description": "Object defining the scanner used to perform the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the scanner.",
+ "minLength": 1,
+ "examples": [
+ "my-sast-scanner"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the scanner, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "My SAST Scanner"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "description": "A link to more information about the scanner.",
+ "examples": [
+ "https://scanner.url"
+ ]
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the scanner.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the scanner.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ }
+ }
+ },
+ "start_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2020-02-14T16:01:59"
+ ]
+ },
+ "status": {
+ "type": "string",
+ "description": "Result of the scan.",
+ "enum": [
+ "success",
+ "failure"
+ ]
+ },
+ "type": {
+ "type": "string",
+ "description": "Type of the scan.",
+ "enum": [
+ "coverage_fuzzing"
+ ]
+ }
+ }
+ },
+ "schema": {
+ "type": "string",
+ "description": "URI pointing to the validating security report schema.",
+ "pattern": "^https?://.+"
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the schema to which the JSON report conforms.",
+ "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
+ },
+ "vulnerabilities": {
+ "type": "array",
+ "description": "Array of vulnerability objects.",
+ "items": {
+ "type": "object",
+ "description": "Describes the vulnerability using GitLab Flavored Markdown",
+ "required": [
+ "id",
+ "identifiers",
+ "location"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 255,
+ "description": "The name of the vulnerability. This must not include the finding's specific information."
+ },
+ "description": {
+ "type": "string",
+ "maxLength": 1048576,
+ "description": "A long text section describing the vulnerability more fully."
+ },
+ "severity": {
+ "type": "string",
+ "description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
+ "enum": [
+ "Info",
+ "Unknown",
+ "Low",
+ "Medium",
+ "High",
+ "Critical"
+ ]
+ },
+ "solution": {
+ "type": "string",
+ "maxLength": 7000,
+ "description": "Explanation of how to fix the vulnerability."
+ },
+ "identifiers": {
+ "type": "array",
+ "minItems": 1,
+ "description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
+ "items": {
+ "type": "object",
+ "required": [
+ "type",
+ "name",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
+ "minLength": 1
+ },
+ "name": {
+ "type": "string",
+ "description": "Human-readable name of the identifier.",
+ "minLength": 1
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the identifier's documentation.",
+ "pattern": "^https?://.+"
+ },
+ "value": {
+ "type": "string",
+ "description": "Value of the identifier, for matching purpose.",
+ "minLength": 1
+ }
+ }
+ }
+ },
+ "links": {
+ "type": "array",
+ "description": "An array of references to external documentation or articles that describe the vulnerability.",
+ "items": {
+ "type": "object",
+ "required": [
+ "url"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the vulnerability details link."
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the vulnerability details document.",
+ "pattern": "^https?://.+"
+ }
+ }
+ }
+ },
+ "details": {
+ "$ref": "#/definitions/named_list/properties/items"
+ },
+ "tracking": {
+ "description": "Describes how this vulnerability should be tracked as the project changes.",
+ "oneOf": [
+ {
+ "description": "Declares that a series of items should be tracked using source-specific tracking methods.",
+ "required": [
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "source"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "description": "An item that should be tracked using source-specific tracking methods.",
+ "type": "object",
+ "required": [
+ "signatures"
+ ],
+ "properties": {
+ "file": {
+ "type": "string",
+ "description": "Path to the file where the vulnerability is located."
+ },
+ "start_line": {
+ "type": "number",
+ "description": "The first line of the file that includes the vulnerability."
+ },
+ "end_line": {
+ "type": "number",
+ "description": "The last line of the file that includes the vulnerability."
+ },
+ "signatures": {
+ "type": "array",
+ "description": "An array of calculated tracking signatures for this tracking item.",
+ "minItems": 1,
+ "items": {
+ "description": "A calculated tracking signature value and metadata.",
+ "required": [
+ "algorithm",
+ "value"
+ ],
+ "properties": {
+ "algorithm": {
+ "type": "string",
+ "description": "The algorithm used to generate the signature."
+ },
+ "value": {
+ "type": "string",
+ "description": "The result of this signature algorithm."
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "Each tracking type must declare its own type."
+ }
+ }
+ },
+ "flags": {
+ "description": "Flags that can be attached to vulnerabilities.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Informational flags identified and assigned to a vulnerability.",
+ "required": [
+ "type",
+ "origin",
+ "description"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Result of the scan.",
+ "enum": [
+ "flagged-as-likely-false-positive"
+ ]
+ },
+ "origin": {
+ "minLength": 1,
+ "description": "Tool that issued the flag.",
+ "type": "string"
+ },
+ "description": {
+ "minLength": 1,
+ "description": "What the flag is about.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "location": {
+ "description": "The location of the error",
+ "type": "object",
+ "properties": {
+ "crash_address": {
+ "type": "string",
+ "description": "The relative address in memory were the crash occurred.",
+ "examples": [
+ "0xabababab"
+ ]
+ },
+ "stacktrace_snippet": {
+ "type": "string",
+ "description": "The stack trace recorded during fuzzing resulting the crash.",
+ "examples": [
+ "func_a+0xabcd\nfunc_b+0xabcc"
+ ]
+ },
+ "crash_state": {
+ "type": "string",
+ "description": "Minimised and normalized crash stack-trace (called crash_state).",
+ "examples": [
+ "func_a+0xa\nfunc_b+0xb\nfunc_c+0xc"
+ ]
+ },
+ "crash_type": {
+ "type": "string",
+ "description": "Type of the crash.",
+ "examples": [
+ "Heap-Buffer-overflow",
+ "Division-by-zero"
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "remediations": {
+ "type": "array",
+ "description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
+ "items": {
+ "type": "object",
+ "required": [
+ "fixes",
+ "summary",
+ "diff"
+ ],
+ "properties": {
+ "fixes": {
+ "type": "array",
+ "description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
+ "items": {
+ "type": "object",
+ "required": [
+ "id"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ }
+ }
+ }
+ },
+ "summary": {
+ "type": "string",
+ "minLength": 1,
+ "description": "An overview of how the vulnerabilities were fixed."
+ },
+ "diff": {
+ "type": "string",
+ "minLength": 1,
+ "description": "A base64-encoded remediation code diff, compatible with git apply."
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/dast-report-format.json b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/dast-report-format.json
new file mode 100644
index 00000000000..10fafaf8975
--- /dev/null
+++ b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/dast-report-format.json
@@ -0,0 +1,1241 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/raw/master/dist/dast-report-format.json",
+ "title": "Report format for GitLab DAST",
+ "description": "This schema provides the the report format for Dynamic Application Security Testing (https://docs.gitlab.com/ee/user/application_security/dast).",
+ "definitions": {
+ "detail_type": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/named_list"
+ },
+ {
+ "$ref": "#/definitions/list"
+ },
+ {
+ "$ref": "#/definitions/table"
+ },
+ {
+ "$ref": "#/definitions/text"
+ },
+ {
+ "$ref": "#/definitions/url"
+ },
+ {
+ "$ref": "#/definitions/code"
+ },
+ {
+ "$ref": "#/definitions/value"
+ },
+ {
+ "$ref": "#/definitions/diff"
+ },
+ {
+ "$ref": "#/definitions/markdown"
+ },
+ {
+ "$ref": "#/definitions/commit"
+ },
+ {
+ "$ref": "#/definitions/file_location"
+ },
+ {
+ "$ref": "#/definitions/module_location"
+ }
+ ]
+ },
+ "text_value": {
+ "type": "string"
+ },
+ "named_field": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/text_value",
+ "minLength": 1
+ },
+ "description": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "named_list": {
+ "type": "object",
+ "description": "An object with named and typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "named-list"
+ },
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "allOf": [
+ {
+ "$ref": "#/definitions/named_field"
+ },
+ {
+ "$ref": "#/definitions/detail_type"
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "list": {
+ "type": "object",
+ "description": "A list of typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "list"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ },
+ "table": {
+ "type": "object",
+ "description": "A table of typed fields",
+ "required": [
+ "type",
+ "rows"
+ ],
+ "properties": {
+ "type": {
+ "const": "table"
+ },
+ "header": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ },
+ "rows": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ }
+ },
+ "text": {
+ "type": "object",
+ "description": "Raw text",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "text"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "url": {
+ "type": "object",
+ "description": "A single URL",
+ "required": [
+ "type",
+ "href"
+ ],
+ "properties": {
+ "type": {
+ "const": "url"
+ },
+ "text": {
+ "$ref": "#/definitions/text_value"
+ },
+ "href": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "http://mysite.com"
+ ]
+ }
+ }
+ },
+ "code": {
+ "type": "object",
+ "description": "A codeblock",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "code"
+ },
+ "value": {
+ "type": "string"
+ },
+ "lang": {
+ "type": "string",
+ "description": "A programming language"
+ }
+ }
+ },
+ "value": {
+ "type": "object",
+ "description": "A field that can store a range of types of value",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "value"
+ },
+ "value": {
+ "type": [
+ "number",
+ "string",
+ "boolean"
+ ]
+ }
+ }
+ },
+ "diff": {
+ "type": "object",
+ "description": "A diff",
+ "required": [
+ "type",
+ "before",
+ "after"
+ ],
+ "properties": {
+ "type": {
+ "const": "diff"
+ },
+ "before": {
+ "type": "string"
+ },
+ "after": {
+ "type": "string"
+ }
+ }
+ },
+ "markdown": {
+ "type": "object",
+ "description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "markdown"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value",
+ "examples": [
+ "Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)"
+ ]
+ }
+ }
+ },
+ "commit": {
+ "type": "object",
+ "description": "A commit/tag/branch within the GitLab project",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "commit"
+ },
+ "value": {
+ "type": "string",
+ "description": "The commit SHA",
+ "minLength": 1
+ }
+ }
+ },
+ "file_location": {
+ "type": "object",
+ "description": "A location within a file in the project",
+ "required": [
+ "type",
+ "file_name",
+ "line_start"
+ ],
+ "properties": {
+ "type": {
+ "const": "file-location"
+ },
+ "file_name": {
+ "type": "string",
+ "minLength": 1
+ },
+ "line_start": {
+ "type": "integer"
+ },
+ "line_end": {
+ "type": "integer"
+ }
+ }
+ },
+ "module_location": {
+ "type": "object",
+ "description": "A location within a binary module of the form module+relative_offset",
+ "required": [
+ "type",
+ "module_name",
+ "offset"
+ ],
+ "properties": {
+ "type": {
+ "const": "module-location"
+ },
+ "module_name": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "compiled_binary"
+ ]
+ },
+ "offset": {
+ "type": "integer",
+ "examples": [
+ 100
+ ]
+ }
+ }
+ }
+ },
+ "self": {
+ "version": "15.0.0"
+ },
+ "required": [
+ "scan",
+ "version",
+ "vulnerabilities"
+ ],
+ "additionalProperties": true,
+ "properties": {
+ "scan": {
+ "type": "object",
+ "required": [
+ "analyzer",
+ "end_time",
+ "scanned_resources",
+ "scanner",
+ "start_time",
+ "status",
+ "type"
+ ],
+ "properties": {
+ "end_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2020-01-28T03:26:02"
+ ]
+ },
+ "messages": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Communication intended for the initiator of a scan.",
+ "required": [
+ "level",
+ "value"
+ ],
+ "properties": {
+ "level": {
+ "type": "string",
+ "description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
+ "enum": [
+ "info",
+ "warn",
+ "fatal"
+ ],
+ "examples": [
+ "info"
+ ]
+ },
+ "value": {
+ "type": "string",
+ "description": "The message to communicate.",
+ "minLength": 1,
+ "examples": [
+ "Permission denied, scanning aborted"
+ ]
+ }
+ }
+ }
+ },
+ "analyzer": {
+ "type": "object",
+ "description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "gitlab-dast"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the analyzer, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "GitLab DAST"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "pattern": "^https?://.+",
+ "description": "A link to more information about the analyzer.",
+ "examples": [
+ "https://docs.gitlab.com/ee/user/application_security/dast"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the analyzer.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ }
+ }
+ },
+ "scanner": {
+ "type": "object",
+ "description": "Object defining the scanner used to perform the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the scanner.",
+ "minLength": 1,
+ "examples": [
+ "my-sast-scanner"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the scanner, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "My SAST Scanner"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "description": "A link to more information about the scanner.",
+ "examples": [
+ "https://scanner.url"
+ ]
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the scanner.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the scanner.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ }
+ }
+ },
+ "start_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2020-02-14T16:01:59"
+ ]
+ },
+ "status": {
+ "type": "string",
+ "description": "Result of the scan.",
+ "enum": [
+ "success",
+ "failure"
+ ]
+ },
+ "type": {
+ "type": "string",
+ "description": "Type of the scan.",
+ "enum": [
+ "dast",
+ "api_fuzzing"
+ ]
+ },
+ "scanned_resources": {
+ "type": "array",
+ "description": "The attack surface scanned by DAST.",
+ "items": {
+ "type": "object",
+ "required": [
+ "method",
+ "url",
+ "type"
+ ],
+ "properties": {
+ "method": {
+ "type": "string",
+ "minLength": 1,
+ "description": "HTTP method of the scanned resource.",
+ "examples": [
+ "GET",
+ "POST",
+ "HEAD"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "minLength": 1,
+ "description": "URL of the scanned resource.",
+ "examples": [
+ "http://my.site.com/a-page"
+ ]
+ },
+ "type": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Type of the scanned resource, for DAST, this must be 'url'.",
+ "examples": [
+ "url"
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "schema": {
+ "type": "string",
+ "description": "URI pointing to the validating security report schema.",
+ "pattern": "^https?://.+"
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the schema to which the JSON report conforms.",
+ "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
+ },
+ "vulnerabilities": {
+ "type": "array",
+ "description": "Array of vulnerability objects.",
+ "items": {
+ "type": "object",
+ "description": "Describes the vulnerability using GitLab Flavored Markdown",
+ "required": [
+ "id",
+ "identifiers",
+ "location"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 255,
+ "description": "The name of the vulnerability. This must not include the finding's specific information."
+ },
+ "description": {
+ "type": "string",
+ "maxLength": 1048576,
+ "description": "A long text section describing the vulnerability more fully."
+ },
+ "severity": {
+ "type": "string",
+ "description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
+ "enum": [
+ "Info",
+ "Unknown",
+ "Low",
+ "Medium",
+ "High",
+ "Critical"
+ ]
+ },
+ "solution": {
+ "type": "string",
+ "maxLength": 7000,
+ "description": "Explanation of how to fix the vulnerability."
+ },
+ "identifiers": {
+ "type": "array",
+ "minItems": 1,
+ "description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
+ "items": {
+ "type": "object",
+ "required": [
+ "type",
+ "name",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
+ "minLength": 1
+ },
+ "name": {
+ "type": "string",
+ "description": "Human-readable name of the identifier.",
+ "minLength": 1
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the identifier's documentation.",
+ "pattern": "^https?://.+"
+ },
+ "value": {
+ "type": "string",
+ "description": "Value of the identifier, for matching purpose.",
+ "minLength": 1
+ }
+ }
+ }
+ },
+ "links": {
+ "type": "array",
+ "description": "An array of references to external documentation or articles that describe the vulnerability.",
+ "items": {
+ "type": "object",
+ "required": [
+ "url"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the vulnerability details link."
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the vulnerability details document.",
+ "pattern": "^https?://.+"
+ }
+ }
+ }
+ },
+ "details": {
+ "$ref": "#/definitions/named_list/properties/items"
+ },
+ "tracking": {
+ "description": "Describes how this vulnerability should be tracked as the project changes.",
+ "oneOf": [
+ {
+ "description": "Declares that a series of items should be tracked using source-specific tracking methods.",
+ "required": [
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "source"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "description": "An item that should be tracked using source-specific tracking methods.",
+ "type": "object",
+ "required": [
+ "signatures"
+ ],
+ "properties": {
+ "file": {
+ "type": "string",
+ "description": "Path to the file where the vulnerability is located."
+ },
+ "start_line": {
+ "type": "number",
+ "description": "The first line of the file that includes the vulnerability."
+ },
+ "end_line": {
+ "type": "number",
+ "description": "The last line of the file that includes the vulnerability."
+ },
+ "signatures": {
+ "type": "array",
+ "description": "An array of calculated tracking signatures for this tracking item.",
+ "minItems": 1,
+ "items": {
+ "description": "A calculated tracking signature value and metadata.",
+ "required": [
+ "algorithm",
+ "value"
+ ],
+ "properties": {
+ "algorithm": {
+ "type": "string",
+ "description": "The algorithm used to generate the signature."
+ },
+ "value": {
+ "type": "string",
+ "description": "The result of this signature algorithm."
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "Each tracking type must declare its own type."
+ }
+ }
+ },
+ "flags": {
+ "description": "Flags that can be attached to vulnerabilities.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Informational flags identified and assigned to a vulnerability.",
+ "required": [
+ "type",
+ "origin",
+ "description"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Result of the scan.",
+ "enum": [
+ "flagged-as-likely-false-positive"
+ ]
+ },
+ "origin": {
+ "minLength": 1,
+ "description": "Tool that issued the flag.",
+ "type": "string"
+ },
+ "description": {
+ "minLength": 1,
+ "description": "What the flag is about.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "evidence": {
+ "type": "object",
+ "properties": {
+ "source": {
+ "type": "object",
+ "description": "Source of evidence",
+ "required": [
+ "id",
+ "name"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Unique source identifier",
+ "examples": [
+ "assert:LogAnalysis",
+ "assert:StatusCode"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Source display name",
+ "examples": [
+ "Log Analysis",
+ "Status Code"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "description": "Link to additional information",
+ "examples": [
+ "https://docs.gitlab.com/ee/development/integrations/secure.html"
+ ]
+ }
+ }
+ },
+ "summary": {
+ "type": "string",
+ "description": "Human readable string containing evidence of the vulnerability.",
+ "examples": [
+ "Credit card 4111111111111111 found",
+ "Server leaked information nginx/1.17.6"
+ ]
+ },
+ "request": {
+ "type": "object",
+ "description": "An HTTP request.",
+ "required": [
+ "headers",
+ "method",
+ "url"
+ ],
+ "properties": {
+ "headers": {
+ "type": "array",
+ "description": "HTTP headers present on the request.",
+ "items": {
+ "type": "object",
+ "required": [
+ "name",
+ "value"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Name of the HTTP header.",
+ "examples": [
+ "Accept",
+ "Content-Length",
+ "Content-Type"
+ ]
+ },
+ "value": {
+ "type": "string",
+ "description": "Value of the HTTP header.",
+ "examples": [
+ "*/*",
+ "560",
+ "application/json; charset=utf-8"
+ ]
+ }
+ }
+ }
+ },
+ "method": {
+ "type": "string",
+ "minLength": 1,
+ "description": "HTTP method used in the request.",
+ "examples": [
+ "GET",
+ "POST"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "minLength": 1,
+ "description": "URL of the request.",
+ "examples": [
+ "http://my.site.com/vulnerable-endpoint?show-credit-card"
+ ]
+ },
+ "body": {
+ "type": "string",
+ "description": "Body of the request for display purposes. Body must be suitable for display (not binary), and truncated to a reasonable size.",
+ "examples": [
+ "user=jsmith&first=%27&last=smith"
+ ]
+ }
+ }
+ },
+ "response": {
+ "type": "object",
+ "description": "An HTTP response.",
+ "required": [
+ "headers",
+ "reason_phrase",
+ "status_code"
+ ],
+ "properties": {
+ "headers": {
+ "type": "array",
+ "description": "HTTP headers present on the request.",
+ "items": {
+ "type": "object",
+ "required": [
+ "name",
+ "value"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Name of the HTTP header.",
+ "examples": [
+ "Accept",
+ "Content-Length",
+ "Content-Type"
+ ]
+ },
+ "value": {
+ "type": "string",
+ "description": "Value of the HTTP header.",
+ "examples": [
+ "*/*",
+ "560",
+ "application/json; charset=utf-8"
+ ]
+ }
+ }
+ }
+ },
+ "reason_phrase": {
+ "type": "string",
+ "description": "HTTP reason phrase of the response.",
+ "examples": [
+ "OK",
+ "Internal Server Error"
+ ]
+ },
+ "status_code": {
+ "type": "integer",
+ "description": "HTTP status code of the response.",
+ "examples": [
+ 200,
+ 500
+ ]
+ },
+ "body": {
+ "type": "string",
+ "description": "Body of the response for display purposes. Body must be suitable for display (not binary), and truncated to a reasonable size.",
+ "examples": [
+ "{\"user_id\": 2}"
+ ]
+ }
+ }
+ },
+ "supporting_messages": {
+ "type": "array",
+ "description": "Array of supporting http messages.",
+ "items": {
+ "type": "object",
+ "description": "A supporting http message.",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Message display name.",
+ "examples": [
+ "Unmodified",
+ "Recorded"
+ ]
+ },
+ "request": {
+ "type": "object",
+ "description": "An HTTP request.",
+ "required": [
+ "headers",
+ "method",
+ "url"
+ ],
+ "properties": {
+ "headers": {
+ "type": "array",
+ "description": "HTTP headers present on the request.",
+ "items": {
+ "type": "object",
+ "required": [
+ "name",
+ "value"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Name of the HTTP header.",
+ "examples": [
+ "Accept",
+ "Content-Length",
+ "Content-Type"
+ ]
+ },
+ "value": {
+ "type": "string",
+ "description": "Value of the HTTP header.",
+ "examples": [
+ "*/*",
+ "560",
+ "application/json; charset=utf-8"
+ ]
+ }
+ }
+ }
+ },
+ "method": {
+ "type": "string",
+ "minLength": 1,
+ "description": "HTTP method used in the request.",
+ "examples": [
+ "GET",
+ "POST"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "minLength": 1,
+ "description": "URL of the request.",
+ "examples": [
+ "http://my.site.com/vulnerable-endpoint?show-credit-card"
+ ]
+ },
+ "body": {
+ "type": "string",
+ "description": "Body of the request for display purposes. Body must be suitable for display (not binary), and truncated to a reasonable size.",
+ "examples": [
+ "user=jsmith&first=%27&last=smith"
+ ]
+ }
+ }
+ },
+ "response": {
+ "type": "object",
+ "description": "An HTTP response.",
+ "required": [
+ "headers",
+ "reason_phrase",
+ "status_code"
+ ],
+ "properties": {
+ "headers": {
+ "type": "array",
+ "description": "HTTP headers present on the request.",
+ "items": {
+ "type": "object",
+ "required": [
+ "name",
+ "value"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Name of the HTTP header.",
+ "examples": [
+ "Accept",
+ "Content-Length",
+ "Content-Type"
+ ]
+ },
+ "value": {
+ "type": "string",
+ "description": "Value of the HTTP header.",
+ "examples": [
+ "*/*",
+ "560",
+ "application/json; charset=utf-8"
+ ]
+ }
+ }
+ }
+ },
+ "reason_phrase": {
+ "type": "string",
+ "description": "HTTP reason phrase of the response.",
+ "examples": [
+ "OK",
+ "Internal Server Error"
+ ]
+ },
+ "status_code": {
+ "type": "integer",
+ "description": "HTTP status code of the response.",
+ "examples": [
+ 200,
+ 500
+ ]
+ },
+ "body": {
+ "type": "string",
+ "description": "Body of the response for display purposes. Body must be suitable for display (not binary), and truncated to a reasonable size.",
+ "examples": [
+ "{\"user_id\": 2}"
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "location": {
+ "type": "object",
+ "description": "Identifies the vulnerability's location.",
+ "properties": {
+ "hostname": {
+ "type": "string",
+ "description": "The protocol, domain, and port of the application where the vulnerability was found."
+ },
+ "method": {
+ "type": "string",
+ "description": "The HTTP method that was used to request the URL where the vulnerability was found."
+ },
+ "param": {
+ "type": "string",
+ "description": "A value provided by a vulnerability rule related to the found vulnerability. Examples include a header value, or a parameter used in a HTTP POST."
+ },
+ "path": {
+ "type": "string",
+ "description": "The path of the URL where the vulnerability was found. Typically, this would start with a forward slash."
+ }
+ }
+ },
+ "assets": {
+ "type": "array",
+ "description": "Array of build assets associated with vulnerability.",
+ "items": {
+ "type": "object",
+ "description": "Describes an asset associated with vulnerability.",
+ "required": [
+ "type",
+ "name",
+ "url"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "The type of asset",
+ "enum": [
+ "http_session",
+ "postman"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Display name for asset",
+ "examples": [
+ "HTTP Messages",
+ "Postman Collection"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Link to asset in build artifacts",
+ "examples": [
+ "https://gitlab.com/gitlab-org/security-products/dast/-/jobs/626397001/artifacts/file//output/zap_session.data"
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "remediations": {
+ "type": "array",
+ "description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
+ "items": {
+ "type": "object",
+ "required": [
+ "fixes",
+ "summary",
+ "diff"
+ ],
+ "properties": {
+ "fixes": {
+ "type": "array",
+ "description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
+ "items": {
+ "type": "object",
+ "required": [
+ "id"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ }
+ }
+ }
+ },
+ "summary": {
+ "type": "string",
+ "minLength": 1,
+ "description": "An overview of how the vulnerabilities were fixed."
+ },
+ "diff": {
+ "type": "string",
+ "minLength": 1,
+ "description": "A base64-encoded remediation code diff, compatible with git apply."
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/dependency-scanning-report-format.json b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/dependency-scanning-report-format.json
new file mode 100644
index 00000000000..ade1ce9ea8f
--- /dev/null
+++ b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/dependency-scanning-report-format.json
@@ -0,0 +1,944 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/raw/master/dist/dependency-scanning-report-format.json",
+ "title": "Report format for GitLab Dependency Scanning",
+ "description": "This schema provides the the report format for Dependency Scanning analyzers (https://docs.gitlab.com/ee/user/application_security/dependency_scanning).",
+ "definitions": {
+ "detail_type": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/named_list"
+ },
+ {
+ "$ref": "#/definitions/list"
+ },
+ {
+ "$ref": "#/definitions/table"
+ },
+ {
+ "$ref": "#/definitions/text"
+ },
+ {
+ "$ref": "#/definitions/url"
+ },
+ {
+ "$ref": "#/definitions/code"
+ },
+ {
+ "$ref": "#/definitions/value"
+ },
+ {
+ "$ref": "#/definitions/diff"
+ },
+ {
+ "$ref": "#/definitions/markdown"
+ },
+ {
+ "$ref": "#/definitions/commit"
+ },
+ {
+ "$ref": "#/definitions/file_location"
+ },
+ {
+ "$ref": "#/definitions/module_location"
+ }
+ ]
+ },
+ "text_value": {
+ "type": "string"
+ },
+ "named_field": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/text_value",
+ "minLength": 1
+ },
+ "description": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "named_list": {
+ "type": "object",
+ "description": "An object with named and typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "named-list"
+ },
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "allOf": [
+ {
+ "$ref": "#/definitions/named_field"
+ },
+ {
+ "$ref": "#/definitions/detail_type"
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "list": {
+ "type": "object",
+ "description": "A list of typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "list"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ },
+ "table": {
+ "type": "object",
+ "description": "A table of typed fields",
+ "required": [
+ "type",
+ "rows"
+ ],
+ "properties": {
+ "type": {
+ "const": "table"
+ },
+ "header": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ },
+ "rows": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ }
+ },
+ "text": {
+ "type": "object",
+ "description": "Raw text",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "text"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "url": {
+ "type": "object",
+ "description": "A single URL",
+ "required": [
+ "type",
+ "href"
+ ],
+ "properties": {
+ "type": {
+ "const": "url"
+ },
+ "text": {
+ "$ref": "#/definitions/text_value"
+ },
+ "href": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "http://mysite.com"
+ ]
+ }
+ }
+ },
+ "code": {
+ "type": "object",
+ "description": "A codeblock",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "code"
+ },
+ "value": {
+ "type": "string"
+ },
+ "lang": {
+ "type": "string",
+ "description": "A programming language"
+ }
+ }
+ },
+ "value": {
+ "type": "object",
+ "description": "A field that can store a range of types of value",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "value"
+ },
+ "value": {
+ "type": [
+ "number",
+ "string",
+ "boolean"
+ ]
+ }
+ }
+ },
+ "diff": {
+ "type": "object",
+ "description": "A diff",
+ "required": [
+ "type",
+ "before",
+ "after"
+ ],
+ "properties": {
+ "type": {
+ "const": "diff"
+ },
+ "before": {
+ "type": "string"
+ },
+ "after": {
+ "type": "string"
+ }
+ }
+ },
+ "markdown": {
+ "type": "object",
+ "description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "markdown"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value",
+ "examples": [
+ "Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)"
+ ]
+ }
+ }
+ },
+ "commit": {
+ "type": "object",
+ "description": "A commit/tag/branch within the GitLab project",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "commit"
+ },
+ "value": {
+ "type": "string",
+ "description": "The commit SHA",
+ "minLength": 1
+ }
+ }
+ },
+ "file_location": {
+ "type": "object",
+ "description": "A location within a file in the project",
+ "required": [
+ "type",
+ "file_name",
+ "line_start"
+ ],
+ "properties": {
+ "type": {
+ "const": "file-location"
+ },
+ "file_name": {
+ "type": "string",
+ "minLength": 1
+ },
+ "line_start": {
+ "type": "integer"
+ },
+ "line_end": {
+ "type": "integer"
+ }
+ }
+ },
+ "module_location": {
+ "type": "object",
+ "description": "A location within a binary module of the form module+relative_offset",
+ "required": [
+ "type",
+ "module_name",
+ "offset"
+ ],
+ "properties": {
+ "type": {
+ "const": "module-location"
+ },
+ "module_name": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "compiled_binary"
+ ]
+ },
+ "offset": {
+ "type": "integer",
+ "examples": [
+ 100
+ ]
+ }
+ }
+ }
+ },
+ "self": {
+ "version": "15.0.0"
+ },
+ "required": [
+ "dependency_files",
+ "scan",
+ "version",
+ "vulnerabilities"
+ ],
+ "additionalProperties": true,
+ "properties": {
+ "scan": {
+ "type": "object",
+ "required": [
+ "analyzer",
+ "end_time",
+ "scanner",
+ "start_time",
+ "status",
+ "type"
+ ],
+ "properties": {
+ "end_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2020-01-28T03:26:02"
+ ]
+ },
+ "messages": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Communication intended for the initiator of a scan.",
+ "required": [
+ "level",
+ "value"
+ ],
+ "properties": {
+ "level": {
+ "type": "string",
+ "description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
+ "enum": [
+ "info",
+ "warn",
+ "fatal"
+ ],
+ "examples": [
+ "info"
+ ]
+ },
+ "value": {
+ "type": "string",
+ "description": "The message to communicate.",
+ "minLength": 1,
+ "examples": [
+ "Permission denied, scanning aborted"
+ ]
+ }
+ }
+ }
+ },
+ "analyzer": {
+ "type": "object",
+ "description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "gitlab-dast"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the analyzer, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "GitLab DAST"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "pattern": "^https?://.+",
+ "description": "A link to more information about the analyzer.",
+ "examples": [
+ "https://docs.gitlab.com/ee/user/application_security/dast"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the analyzer.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ }
+ }
+ },
+ "scanner": {
+ "type": "object",
+ "description": "Object defining the scanner used to perform the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the scanner.",
+ "minLength": 1,
+ "examples": [
+ "my-sast-scanner"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the scanner, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "My SAST Scanner"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "description": "A link to more information about the scanner.",
+ "examples": [
+ "https://scanner.url"
+ ]
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the scanner.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the scanner.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ }
+ }
+ },
+ "start_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2020-02-14T16:01:59"
+ ]
+ },
+ "status": {
+ "type": "string",
+ "description": "Result of the scan.",
+ "enum": [
+ "success",
+ "failure"
+ ]
+ },
+ "type": {
+ "type": "string",
+ "description": "Type of the scan.",
+ "enum": [
+ "dependency_scanning"
+ ]
+ }
+ }
+ },
+ "schema": {
+ "type": "string",
+ "description": "URI pointing to the validating security report schema.",
+ "pattern": "^https?://.+"
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the schema to which the JSON report conforms.",
+ "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
+ },
+ "vulnerabilities": {
+ "type": "array",
+ "description": "Array of vulnerability objects.",
+ "items": {
+ "type": "object",
+ "description": "Describes the vulnerability using GitLab Flavored Markdown",
+ "required": [
+ "id",
+ "identifiers",
+ "location"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 255,
+ "description": "The name of the vulnerability. This must not include the finding's specific information."
+ },
+ "description": {
+ "type": "string",
+ "maxLength": 1048576,
+ "description": "A long text section describing the vulnerability more fully."
+ },
+ "severity": {
+ "type": "string",
+ "description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
+ "enum": [
+ "Info",
+ "Unknown",
+ "Low",
+ "Medium",
+ "High",
+ "Critical"
+ ]
+ },
+ "solution": {
+ "type": "string",
+ "maxLength": 7000,
+ "description": "Explanation of how to fix the vulnerability."
+ },
+ "identifiers": {
+ "type": "array",
+ "minItems": 1,
+ "description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
+ "items": {
+ "type": "object",
+ "required": [
+ "type",
+ "name",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
+ "minLength": 1
+ },
+ "name": {
+ "type": "string",
+ "description": "Human-readable name of the identifier.",
+ "minLength": 1
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the identifier's documentation.",
+ "pattern": "^https?://.+"
+ },
+ "value": {
+ "type": "string",
+ "description": "Value of the identifier, for matching purpose.",
+ "minLength": 1
+ }
+ }
+ }
+ },
+ "links": {
+ "type": "array",
+ "description": "An array of references to external documentation or articles that describe the vulnerability.",
+ "items": {
+ "type": "object",
+ "required": [
+ "url"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the vulnerability details link."
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the vulnerability details document.",
+ "pattern": "^https?://.+"
+ }
+ }
+ }
+ },
+ "details": {
+ "$ref": "#/definitions/named_list/properties/items"
+ },
+ "tracking": {
+ "description": "Describes how this vulnerability should be tracked as the project changes.",
+ "oneOf": [
+ {
+ "description": "Declares that a series of items should be tracked using source-specific tracking methods.",
+ "required": [
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "source"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "description": "An item that should be tracked using source-specific tracking methods.",
+ "type": "object",
+ "required": [
+ "signatures"
+ ],
+ "properties": {
+ "file": {
+ "type": "string",
+ "description": "Path to the file where the vulnerability is located."
+ },
+ "start_line": {
+ "type": "number",
+ "description": "The first line of the file that includes the vulnerability."
+ },
+ "end_line": {
+ "type": "number",
+ "description": "The last line of the file that includes the vulnerability."
+ },
+ "signatures": {
+ "type": "array",
+ "description": "An array of calculated tracking signatures for this tracking item.",
+ "minItems": 1,
+ "items": {
+ "description": "A calculated tracking signature value and metadata.",
+ "required": [
+ "algorithm",
+ "value"
+ ],
+ "properties": {
+ "algorithm": {
+ "type": "string",
+ "description": "The algorithm used to generate the signature."
+ },
+ "value": {
+ "type": "string",
+ "description": "The result of this signature algorithm."
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "Each tracking type must declare its own type."
+ }
+ }
+ },
+ "flags": {
+ "description": "Flags that can be attached to vulnerabilities.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Informational flags identified and assigned to a vulnerability.",
+ "required": [
+ "type",
+ "origin",
+ "description"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Result of the scan.",
+ "enum": [
+ "flagged-as-likely-false-positive"
+ ]
+ },
+ "origin": {
+ "minLength": 1,
+ "description": "Tool that issued the flag.",
+ "type": "string"
+ },
+ "description": {
+ "minLength": 1,
+ "description": "What the flag is about.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "location": {
+ "type": "object",
+ "description": "Identifies the vulnerability's location.",
+ "required": [
+ "file",
+ "dependency"
+ ],
+ "properties": {
+ "file": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Path to the manifest or lock file where the dependency is declared (such as yarn.lock)."
+ },
+ "dependency": {
+ "type": "object",
+ "description": "Describes the dependency of a project where the vulnerability is located.",
+ "required": [
+ "package",
+ "version"
+ ],
+ "properties": {
+ "package": {
+ "type": "object",
+ "description": "Provides information on the package where the vulnerability is located.",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the package where the vulnerability is located."
+ }
+ }
+ },
+ "version": {
+ "type": "string",
+ "description": "Version of the vulnerable package."
+ },
+ "iid": {
+ "description": "ID that identifies the dependency in the scope of a dependency file.",
+ "type": "number"
+ },
+ "direct": {
+ "type": "boolean",
+ "description": "Tells whether this is a direct, top-level dependency of the scanned project."
+ },
+ "dependency_path": {
+ "type": "array",
+ "description": "Ancestors of the dependency, starting from a direct project dependency, and ending with an immediate parent of the dependency. The dependency itself is excluded from the path. Direct dependencies have no path.",
+ "items": {
+ "type": "object",
+ "required": [
+ "iid"
+ ],
+ "properties": {
+ "iid": {
+ "type": "number",
+ "description": "ID that is unique in the scope of a parent object, and specific to the resource type."
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "remediations": {
+ "type": "array",
+ "description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
+ "items": {
+ "type": "object",
+ "required": [
+ "fixes",
+ "summary",
+ "diff"
+ ],
+ "properties": {
+ "fixes": {
+ "type": "array",
+ "description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
+ "items": {
+ "type": "object",
+ "required": [
+ "id"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ }
+ }
+ }
+ },
+ "summary": {
+ "type": "string",
+ "minLength": 1,
+ "description": "An overview of how the vulnerabilities were fixed."
+ },
+ "diff": {
+ "type": "string",
+ "minLength": 1,
+ "description": "A base64-encoded remediation code diff, compatible with git apply."
+ }
+ }
+ }
+ },
+ "dependency_files": {
+ "type": "array",
+ "description": "List of dependency files identified in the project.",
+ "items": {
+ "type": "object",
+ "required": [
+ "path",
+ "package_manager",
+ "dependencies"
+ ],
+ "properties": {
+ "path": {
+ "type": "string",
+ "minLength": 1
+ },
+ "package_manager": {
+ "type": "string",
+ "minLength": 1
+ },
+ "dependencies": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Describes the dependency of a project where the vulnerability is located.",
+ "required": [
+ "package",
+ "version"
+ ],
+ "properties": {
+ "package": {
+ "type": "object",
+ "description": "Provides information on the package where the vulnerability is located.",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the package where the vulnerability is located."
+ }
+ }
+ },
+ "version": {
+ "type": "string",
+ "description": "Version of the vulnerable package."
+ },
+ "iid": {
+ "description": "ID that identifies the dependency in the scope of a dependency file.",
+ "type": "number"
+ },
+ "direct": {
+ "type": "boolean",
+ "description": "Tells whether this is a direct, top-level dependency of the scanned project."
+ },
+ "dependency_path": {
+ "type": "array",
+ "description": "Ancestors of the dependency, starting from a direct project dependency, and ending with an immediate parent of the dependency. The dependency itself is excluded from the path. Direct dependencies have no path.",
+ "items": {
+ "type": "object",
+ "required": [
+ "iid"
+ ],
+ "properties": {
+ "iid": {
+ "type": "number",
+ "description": "ID that is unique in the scope of a parent object, and specific to the resource type."
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/sast-report-format.json b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/sast-report-format.json
new file mode 100644
index 00000000000..9fae45d728e
--- /dev/null
+++ b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/sast-report-format.json
@@ -0,0 +1,831 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/raw/master/dist/sast-report-format.json",
+ "title": "Report format for GitLab SAST",
+ "description": "This schema provides the report format for Static Application Security Testing analyzers (https://docs.gitlab.com/ee/user/application_security/sast).",
+ "definitions": {
+ "detail_type": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/named_list"
+ },
+ {
+ "$ref": "#/definitions/list"
+ },
+ {
+ "$ref": "#/definitions/table"
+ },
+ {
+ "$ref": "#/definitions/text"
+ },
+ {
+ "$ref": "#/definitions/url"
+ },
+ {
+ "$ref": "#/definitions/code"
+ },
+ {
+ "$ref": "#/definitions/value"
+ },
+ {
+ "$ref": "#/definitions/diff"
+ },
+ {
+ "$ref": "#/definitions/markdown"
+ },
+ {
+ "$ref": "#/definitions/commit"
+ },
+ {
+ "$ref": "#/definitions/file_location"
+ },
+ {
+ "$ref": "#/definitions/module_location"
+ }
+ ]
+ },
+ "text_value": {
+ "type": "string"
+ },
+ "named_field": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/text_value",
+ "minLength": 1
+ },
+ "description": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "named_list": {
+ "type": "object",
+ "description": "An object with named and typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "named-list"
+ },
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "allOf": [
+ {
+ "$ref": "#/definitions/named_field"
+ },
+ {
+ "$ref": "#/definitions/detail_type"
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "list": {
+ "type": "object",
+ "description": "A list of typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "list"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ },
+ "table": {
+ "type": "object",
+ "description": "A table of typed fields",
+ "required": [
+ "type",
+ "rows"
+ ],
+ "properties": {
+ "type": {
+ "const": "table"
+ },
+ "header": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ },
+ "rows": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ }
+ },
+ "text": {
+ "type": "object",
+ "description": "Raw text",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "text"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "url": {
+ "type": "object",
+ "description": "A single URL",
+ "required": [
+ "type",
+ "href"
+ ],
+ "properties": {
+ "type": {
+ "const": "url"
+ },
+ "text": {
+ "$ref": "#/definitions/text_value"
+ },
+ "href": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "http://mysite.com"
+ ]
+ }
+ }
+ },
+ "code": {
+ "type": "object",
+ "description": "A codeblock",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "code"
+ },
+ "value": {
+ "type": "string"
+ },
+ "lang": {
+ "type": "string",
+ "description": "A programming language"
+ }
+ }
+ },
+ "value": {
+ "type": "object",
+ "description": "A field that can store a range of types of value",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "value"
+ },
+ "value": {
+ "type": [
+ "number",
+ "string",
+ "boolean"
+ ]
+ }
+ }
+ },
+ "diff": {
+ "type": "object",
+ "description": "A diff",
+ "required": [
+ "type",
+ "before",
+ "after"
+ ],
+ "properties": {
+ "type": {
+ "const": "diff"
+ },
+ "before": {
+ "type": "string"
+ },
+ "after": {
+ "type": "string"
+ }
+ }
+ },
+ "markdown": {
+ "type": "object",
+ "description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "markdown"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value",
+ "examples": [
+ "Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)"
+ ]
+ }
+ }
+ },
+ "commit": {
+ "type": "object",
+ "description": "A commit/tag/branch within the GitLab project",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "commit"
+ },
+ "value": {
+ "type": "string",
+ "description": "The commit SHA",
+ "minLength": 1
+ }
+ }
+ },
+ "file_location": {
+ "type": "object",
+ "description": "A location within a file in the project",
+ "required": [
+ "type",
+ "file_name",
+ "line_start"
+ ],
+ "properties": {
+ "type": {
+ "const": "file-location"
+ },
+ "file_name": {
+ "type": "string",
+ "minLength": 1
+ },
+ "line_start": {
+ "type": "integer"
+ },
+ "line_end": {
+ "type": "integer"
+ }
+ }
+ },
+ "module_location": {
+ "type": "object",
+ "description": "A location within a binary module of the form module+relative_offset",
+ "required": [
+ "type",
+ "module_name",
+ "offset"
+ ],
+ "properties": {
+ "type": {
+ "const": "module-location"
+ },
+ "module_name": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "compiled_binary"
+ ]
+ },
+ "offset": {
+ "type": "integer",
+ "examples": [
+ 100
+ ]
+ }
+ }
+ }
+ },
+ "self": {
+ "version": "15.0.0"
+ },
+ "required": [
+ "scan",
+ "version",
+ "vulnerabilities"
+ ],
+ "additionalProperties": true,
+ "properties": {
+ "scan": {
+ "type": "object",
+ "required": [
+ "analyzer",
+ "end_time",
+ "scanner",
+ "start_time",
+ "status",
+ "type"
+ ],
+ "properties": {
+ "end_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2020-01-28T03:26:02"
+ ]
+ },
+ "messages": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Communication intended for the initiator of a scan.",
+ "required": [
+ "level",
+ "value"
+ ],
+ "properties": {
+ "level": {
+ "type": "string",
+ "description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
+ "enum": [
+ "info",
+ "warn",
+ "fatal"
+ ],
+ "examples": [
+ "info"
+ ]
+ },
+ "value": {
+ "type": "string",
+ "description": "The message to communicate.",
+ "minLength": 1,
+ "examples": [
+ "Permission denied, scanning aborted"
+ ]
+ }
+ }
+ }
+ },
+ "analyzer": {
+ "type": "object",
+ "description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "gitlab-dast"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the analyzer, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "GitLab DAST"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "pattern": "^https?://.+",
+ "description": "A link to more information about the analyzer.",
+ "examples": [
+ "https://docs.gitlab.com/ee/user/application_security/dast"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the analyzer.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ }
+ }
+ },
+ "scanner": {
+ "type": "object",
+ "description": "Object defining the scanner used to perform the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the scanner.",
+ "minLength": 1,
+ "examples": [
+ "my-sast-scanner"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the scanner, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "My SAST Scanner"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "description": "A link to more information about the scanner.",
+ "examples": [
+ "https://scanner.url"
+ ]
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the scanner.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the scanner.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ }
+ }
+ },
+ "start_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2020-02-14T16:01:59"
+ ]
+ },
+ "status": {
+ "type": "string",
+ "description": "Result of the scan.",
+ "enum": [
+ "success",
+ "failure"
+ ]
+ },
+ "type": {
+ "type": "string",
+ "description": "Type of the scan.",
+ "enum": [
+ "sast"
+ ]
+ }
+ }
+ },
+ "schema": {
+ "type": "string",
+ "description": "URI pointing to the validating security report schema.",
+ "pattern": "^https?://.+"
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the schema to which the JSON report conforms.",
+ "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
+ },
+ "vulnerabilities": {
+ "type": "array",
+ "description": "Array of vulnerability objects.",
+ "items": {
+ "type": "object",
+ "description": "Describes the vulnerability using GitLab Flavored Markdown",
+ "required": [
+ "id",
+ "identifiers",
+ "location"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 255,
+ "description": "The name of the vulnerability. This must not include the finding's specific information."
+ },
+ "description": {
+ "type": "string",
+ "maxLength": 1048576,
+ "description": "A long text section describing the vulnerability more fully."
+ },
+ "severity": {
+ "type": "string",
+ "description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
+ "enum": [
+ "Info",
+ "Unknown",
+ "Low",
+ "Medium",
+ "High",
+ "Critical"
+ ]
+ },
+ "solution": {
+ "type": "string",
+ "maxLength": 7000,
+ "description": "Explanation of how to fix the vulnerability."
+ },
+ "identifiers": {
+ "type": "array",
+ "minItems": 1,
+ "description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
+ "items": {
+ "type": "object",
+ "required": [
+ "type",
+ "name",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
+ "minLength": 1
+ },
+ "name": {
+ "type": "string",
+ "description": "Human-readable name of the identifier.",
+ "minLength": 1
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the identifier's documentation.",
+ "pattern": "^https?://.+"
+ },
+ "value": {
+ "type": "string",
+ "description": "Value of the identifier, for matching purpose.",
+ "minLength": 1
+ }
+ }
+ }
+ },
+ "links": {
+ "type": "array",
+ "description": "An array of references to external documentation or articles that describe the vulnerability.",
+ "items": {
+ "type": "object",
+ "required": [
+ "url"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the vulnerability details link."
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the vulnerability details document.",
+ "pattern": "^https?://.+"
+ }
+ }
+ }
+ },
+ "details": {
+ "$ref": "#/definitions/named_list/properties/items"
+ },
+ "tracking": {
+ "description": "Describes how this vulnerability should be tracked as the project changes.",
+ "oneOf": [
+ {
+ "description": "Declares that a series of items should be tracked using source-specific tracking methods.",
+ "required": [
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "source"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "description": "An item that should be tracked using source-specific tracking methods.",
+ "type": "object",
+ "required": [
+ "signatures"
+ ],
+ "properties": {
+ "file": {
+ "type": "string",
+ "description": "Path to the file where the vulnerability is located."
+ },
+ "start_line": {
+ "type": "number",
+ "description": "The first line of the file that includes the vulnerability."
+ },
+ "end_line": {
+ "type": "number",
+ "description": "The last line of the file that includes the vulnerability."
+ },
+ "signatures": {
+ "type": "array",
+ "description": "An array of calculated tracking signatures for this tracking item.",
+ "minItems": 1,
+ "items": {
+ "description": "A calculated tracking signature value and metadata.",
+ "required": [
+ "algorithm",
+ "value"
+ ],
+ "properties": {
+ "algorithm": {
+ "type": "string",
+ "description": "The algorithm used to generate the signature."
+ },
+ "value": {
+ "type": "string",
+ "description": "The result of this signature algorithm."
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "Each tracking type must declare its own type."
+ }
+ }
+ },
+ "flags": {
+ "description": "Flags that can be attached to vulnerabilities.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Informational flags identified and assigned to a vulnerability.",
+ "required": [
+ "type",
+ "origin",
+ "description"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Result of the scan.",
+ "enum": [
+ "flagged-as-likely-false-positive"
+ ]
+ },
+ "origin": {
+ "minLength": 1,
+ "description": "Tool that issued the flag.",
+ "type": "string"
+ },
+ "description": {
+ "minLength": 1,
+ "description": "What the flag is about.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "location": {
+ "type": "object",
+ "description": "Identifies the vulnerability's location.",
+ "properties": {
+ "file": {
+ "type": "string",
+ "description": "Path to the file where the vulnerability is located."
+ },
+ "start_line": {
+ "type": "number",
+ "description": "The first line of the code affected by the vulnerability."
+ },
+ "end_line": {
+ "type": "number",
+ "description": "The last line of the code affected by the vulnerability."
+ },
+ "class": {
+ "type": "string",
+ "description": "Provides the name of the class where the vulnerability is located."
+ },
+ "method": {
+ "type": "string",
+ "description": "Provides the name of the method where the vulnerability is located."
+ }
+ }
+ },
+ "raw_source_code_extract": {
+ "type": "string",
+ "description": "Provides an unsanitized excerpt of the affected source code."
+ }
+ }
+ }
+ },
+ "remediations": {
+ "type": "array",
+ "description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
+ "items": {
+ "type": "object",
+ "required": [
+ "fixes",
+ "summary",
+ "diff"
+ ],
+ "properties": {
+ "fixes": {
+ "type": "array",
+ "description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
+ "items": {
+ "type": "object",
+ "required": [
+ "id"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ }
+ }
+ }
+ },
+ "summary": {
+ "type": "string",
+ "minLength": 1,
+ "description": "An overview of how the vulnerabilities were fixed."
+ },
+ "diff": {
+ "type": "string",
+ "minLength": 1,
+ "description": "A base64-encoded remediation code diff, compatible with git apply."
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/secret-detection-report-format.json b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/secret-detection-report-format.json
new file mode 100644
index 00000000000..fca00e17f26
--- /dev/null
+++ b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/secret-detection-report-format.json
@@ -0,0 +1,854 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/raw/master/dist/secret-detection-report-format.json",
+ "title": "Report format for GitLab Secret Detection",
+ "description": "This schema provides the the report format for the Secret Detection analyzer (https://docs.gitlab.com/ee/user/application_security/secret_detection)",
+ "definitions": {
+ "detail_type": {
+ "oneOf": [
+ {
+ "$ref": "#/definitions/named_list"
+ },
+ {
+ "$ref": "#/definitions/list"
+ },
+ {
+ "$ref": "#/definitions/table"
+ },
+ {
+ "$ref": "#/definitions/text"
+ },
+ {
+ "$ref": "#/definitions/url"
+ },
+ {
+ "$ref": "#/definitions/code"
+ },
+ {
+ "$ref": "#/definitions/value"
+ },
+ {
+ "$ref": "#/definitions/diff"
+ },
+ {
+ "$ref": "#/definitions/markdown"
+ },
+ {
+ "$ref": "#/definitions/commit"
+ },
+ {
+ "$ref": "#/definitions/file_location"
+ },
+ {
+ "$ref": "#/definitions/module_location"
+ }
+ ]
+ },
+ "text_value": {
+ "type": "string"
+ },
+ "named_field": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/text_value",
+ "minLength": 1
+ },
+ "description": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "named_list": {
+ "type": "object",
+ "description": "An object with named and typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "named-list"
+ },
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "allOf": [
+ {
+ "$ref": "#/definitions/named_field"
+ },
+ {
+ "$ref": "#/definitions/detail_type"
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "list": {
+ "type": "object",
+ "description": "A list of typed fields",
+ "required": [
+ "type",
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "list"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ },
+ "table": {
+ "type": "object",
+ "description": "A table of typed fields",
+ "required": [
+ "type",
+ "rows"
+ ],
+ "properties": {
+ "type": {
+ "const": "table"
+ },
+ "header": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ },
+ "rows": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/detail_type"
+ }
+ }
+ }
+ }
+ },
+ "text": {
+ "type": "object",
+ "description": "Raw text",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "text"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value"
+ }
+ }
+ },
+ "url": {
+ "type": "object",
+ "description": "A single URL",
+ "required": [
+ "type",
+ "href"
+ ],
+ "properties": {
+ "type": {
+ "const": "url"
+ },
+ "text": {
+ "$ref": "#/definitions/text_value"
+ },
+ "href": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "http://mysite.com"
+ ]
+ }
+ }
+ },
+ "code": {
+ "type": "object",
+ "description": "A codeblock",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "code"
+ },
+ "value": {
+ "type": "string"
+ },
+ "lang": {
+ "type": "string",
+ "description": "A programming language"
+ }
+ }
+ },
+ "value": {
+ "type": "object",
+ "description": "A field that can store a range of types of value",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "value"
+ },
+ "value": {
+ "type": [
+ "number",
+ "string",
+ "boolean"
+ ]
+ }
+ }
+ },
+ "diff": {
+ "type": "object",
+ "description": "A diff",
+ "required": [
+ "type",
+ "before",
+ "after"
+ ],
+ "properties": {
+ "type": {
+ "const": "diff"
+ },
+ "before": {
+ "type": "string"
+ },
+ "after": {
+ "type": "string"
+ }
+ }
+ },
+ "markdown": {
+ "type": "object",
+ "description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "markdown"
+ },
+ "value": {
+ "$ref": "#/definitions/text_value",
+ "examples": [
+ "Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)"
+ ]
+ }
+ }
+ },
+ "commit": {
+ "type": "object",
+ "description": "A commit/tag/branch within the GitLab project",
+ "required": [
+ "type",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "const": "commit"
+ },
+ "value": {
+ "type": "string",
+ "description": "The commit SHA",
+ "minLength": 1
+ }
+ }
+ },
+ "file_location": {
+ "type": "object",
+ "description": "A location within a file in the project",
+ "required": [
+ "type",
+ "file_name",
+ "line_start"
+ ],
+ "properties": {
+ "type": {
+ "const": "file-location"
+ },
+ "file_name": {
+ "type": "string",
+ "minLength": 1
+ },
+ "line_start": {
+ "type": "integer"
+ },
+ "line_end": {
+ "type": "integer"
+ }
+ }
+ },
+ "module_location": {
+ "type": "object",
+ "description": "A location within a binary module of the form module+relative_offset",
+ "required": [
+ "type",
+ "module_name",
+ "offset"
+ ],
+ "properties": {
+ "type": {
+ "const": "module-location"
+ },
+ "module_name": {
+ "type": "string",
+ "minLength": 1,
+ "examples": [
+ "compiled_binary"
+ ]
+ },
+ "offset": {
+ "type": "integer",
+ "examples": [
+ 100
+ ]
+ }
+ }
+ }
+ },
+ "self": {
+ "version": "15.0.0"
+ },
+ "required": [
+ "scan",
+ "version",
+ "vulnerabilities"
+ ],
+ "additionalProperties": true,
+ "properties": {
+ "scan": {
+ "type": "object",
+ "required": [
+ "analyzer",
+ "end_time",
+ "scanner",
+ "start_time",
+ "status",
+ "type"
+ ],
+ "properties": {
+ "end_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2020-01-28T03:26:02"
+ ]
+ },
+ "messages": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Communication intended for the initiator of a scan.",
+ "required": [
+ "level",
+ "value"
+ ],
+ "properties": {
+ "level": {
+ "type": "string",
+ "description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
+ "enum": [
+ "info",
+ "warn",
+ "fatal"
+ ],
+ "examples": [
+ "info"
+ ]
+ },
+ "value": {
+ "type": "string",
+ "description": "The message to communicate.",
+ "minLength": 1,
+ "examples": [
+ "Permission denied, scanning aborted"
+ ]
+ }
+ }
+ }
+ },
+ "analyzer": {
+ "type": "object",
+ "description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "gitlab-dast"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the analyzer, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "GitLab DAST"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "pattern": "^https?://.+",
+ "description": "A link to more information about the analyzer.",
+ "examples": [
+ "https://docs.gitlab.com/ee/user/application_security/dast"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the analyzer.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the analyzer.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ }
+ }
+ },
+ "scanner": {
+ "type": "object",
+ "description": "Object defining the scanner used to perform the scan.",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "vendor"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique id that identifies the scanner.",
+ "minLength": 1,
+ "examples": [
+ "my-sast-scanner"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "description": "A human readable value that identifies the scanner, not required to be unique.",
+ "minLength": 1,
+ "examples": [
+ "My SAST Scanner"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "description": "A link to more information about the scanner.",
+ "examples": [
+ "https://scanner.url"
+ ]
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the scanner.",
+ "minLength": 1,
+ "examples": [
+ "1.0.2"
+ ]
+ },
+ "vendor": {
+ "description": "The vendor/maintainer of the scanner.",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the vendor.",
+ "minLength": 1,
+ "examples": [
+ "GitLab"
+ ]
+ }
+ }
+ }
+ }
+ },
+ "start_time": {
+ "type": "string",
+ "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2020-02-14T16:01:59"
+ ]
+ },
+ "status": {
+ "type": "string",
+ "description": "Result of the scan.",
+ "enum": [
+ "success",
+ "failure"
+ ]
+ },
+ "type": {
+ "type": "string",
+ "description": "Type of the scan.",
+ "enum": [
+ "secret_detection"
+ ]
+ }
+ }
+ },
+ "schema": {
+ "type": "string",
+ "description": "URI pointing to the validating security report schema.",
+ "pattern": "^https?://.+"
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of the schema to which the JSON report conforms.",
+ "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
+ },
+ "vulnerabilities": {
+ "type": "array",
+ "description": "Array of vulnerability objects.",
+ "items": {
+ "type": "object",
+ "description": "Describes the vulnerability using GitLab Flavored Markdown",
+ "required": [
+ "id",
+ "identifiers",
+ "location"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 255,
+ "description": "The name of the vulnerability. This must not include the finding's specific information."
+ },
+ "description": {
+ "type": "string",
+ "maxLength": 1048576,
+ "description": "A long text section describing the vulnerability more fully."
+ },
+ "severity": {
+ "type": "string",
+ "description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
+ "enum": [
+ "Info",
+ "Unknown",
+ "Low",
+ "Medium",
+ "High",
+ "Critical"
+ ]
+ },
+ "solution": {
+ "type": "string",
+ "maxLength": 7000,
+ "description": "Explanation of how to fix the vulnerability."
+ },
+ "identifiers": {
+ "type": "array",
+ "minItems": 1,
+ "description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
+ "items": {
+ "type": "object",
+ "required": [
+ "type",
+ "name",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
+ "minLength": 1
+ },
+ "name": {
+ "type": "string",
+ "description": "Human-readable name of the identifier.",
+ "minLength": 1
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the identifier's documentation.",
+ "pattern": "^https?://.+"
+ },
+ "value": {
+ "type": "string",
+ "description": "Value of the identifier, for matching purpose.",
+ "minLength": 1
+ }
+ }
+ }
+ },
+ "links": {
+ "type": "array",
+ "description": "An array of references to external documentation or articles that describe the vulnerability.",
+ "items": {
+ "type": "object",
+ "required": [
+ "url"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the vulnerability details link."
+ },
+ "url": {
+ "type": "string",
+ "description": "URL of the vulnerability details document.",
+ "pattern": "^https?://.+"
+ }
+ }
+ }
+ },
+ "details": {
+ "$ref": "#/definitions/named_list/properties/items"
+ },
+ "tracking": {
+ "description": "Describes how this vulnerability should be tracked as the project changes.",
+ "oneOf": [
+ {
+ "description": "Declares that a series of items should be tracked using source-specific tracking methods.",
+ "required": [
+ "items"
+ ],
+ "properties": {
+ "type": {
+ "const": "source"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "description": "An item that should be tracked using source-specific tracking methods.",
+ "type": "object",
+ "required": [
+ "signatures"
+ ],
+ "properties": {
+ "file": {
+ "type": "string",
+ "description": "Path to the file where the vulnerability is located."
+ },
+ "start_line": {
+ "type": "number",
+ "description": "The first line of the file that includes the vulnerability."
+ },
+ "end_line": {
+ "type": "number",
+ "description": "The last line of the file that includes the vulnerability."
+ },
+ "signatures": {
+ "type": "array",
+ "description": "An array of calculated tracking signatures for this tracking item.",
+ "minItems": 1,
+ "items": {
+ "description": "A calculated tracking signature value and metadata.",
+ "required": [
+ "algorithm",
+ "value"
+ ],
+ "properties": {
+ "algorithm": {
+ "type": "string",
+ "description": "The algorithm used to generate the signature."
+ },
+ "value": {
+ "type": "string",
+ "description": "The result of this signature algorithm."
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "Each tracking type must declare its own type."
+ }
+ }
+ },
+ "flags": {
+ "description": "Flags that can be attached to vulnerabilities.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Informational flags identified and assigned to a vulnerability.",
+ "required": [
+ "type",
+ "origin",
+ "description"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Result of the scan.",
+ "enum": [
+ "flagged-as-likely-false-positive"
+ ]
+ },
+ "origin": {
+ "minLength": 1,
+ "description": "Tool that issued the flag.",
+ "type": "string"
+ },
+ "description": {
+ "minLength": 1,
+ "description": "What the flag is about.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "location": {
+ "required": [
+ "commit"
+ ],
+ "properties": {
+ "file": {
+ "type": "string",
+ "description": "Path to the file where the vulnerability is located"
+ },
+ "commit": {
+ "type": "object",
+ "description": "Represents the commit in which the vulnerability was detected",
+ "required": [
+ "sha"
+ ],
+ "properties": {
+ "author": {
+ "type": "string"
+ },
+ "date": {
+ "type": "string"
+ },
+ "message": {
+ "type": "string"
+ },
+ "sha": {
+ "type": "string",
+ "minLength": 1
+ }
+ }
+ },
+ "start_line": {
+ "type": "number",
+ "description": "The first line of the code affected by the vulnerability"
+ },
+ "end_line": {
+ "type": "number",
+ "description": "The last line of the code affected by the vulnerability"
+ },
+ "class": {
+ "type": "string",
+ "description": "Provides the name of the class where the vulnerability is located"
+ },
+ "method": {
+ "type": "string",
+ "description": "Provides the name of the method where the vulnerability is located"
+ }
+ }
+ },
+ "raw_source_code_extract": {
+ "type": "string",
+ "description": "Provides an unsanitized excerpt of the affected source code."
+ }
+ }
+ }
+ },
+ "remediations": {
+ "type": "array",
+ "description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
+ "items": {
+ "type": "object",
+ "required": [
+ "fixes",
+ "summary",
+ "diff"
+ ],
+ "properties": {
+ "fixes": {
+ "type": "array",
+ "description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
+ "items": {
+ "type": "object",
+ "required": [
+ "id"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
+ "examples": [
+ "642735a5-1425-428d-8d4e-3c854885a3c9"
+ ]
+ }
+ }
+ }
+ },
+ "summary": {
+ "type": "string",
+ "minLength": 1,
+ "description": "An overview of how the vulnerabilities were fixed."
+ },
+ "diff": {
+ "type": "string",
+ "minLength": 1,
+ "description": "A base64-encoded remediation code diff, compatible with git apply."
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/lib/gitlab/ci/pipeline/chain/command.rb b/lib/gitlab/ci/pipeline/chain/command.rb
index 0a6f6fd740c..2419b039f24 100644
--- a/lib/gitlab/ci/pipeline/chain/command.rb
+++ b/lib/gitlab/ci/pipeline/chain/command.rb
@@ -117,8 +117,14 @@ module Gitlab
end
def observe_jobs_count_in_alive_pipelines
+ jobs_count = if Feature.enabled?(:ci_limit_active_jobs_early, project)
+ project.all_pipelines.jobs_count_in_alive_pipelines
+ else
+ project.all_pipelines.builds_count_in_alive_pipelines
+ end
+
metrics.active_jobs_histogram
- .observe({ plan: project.actual_plan_name }, project.all_pipelines.jobs_count_in_alive_pipelines)
+ .observe({ plan: project.actual_plan_name }, jobs_count)
end
def increment_pipeline_failure_reason_counter(reason)
diff --git a/lib/gitlab/ci/pipeline/chain/validate/external.rb b/lib/gitlab/ci/pipeline/chain/validate/external.rb
index f4fa9e5fe2a..915e48828d2 100644
--- a/lib/gitlab/ci/pipeline/chain/validate/external.rb
+++ b/lib/gitlab/ci/pipeline/chain/validate/external.rb
@@ -107,7 +107,7 @@ module Gitlab
type: pipeline.source
},
builds: builds_validation_payload,
- total_builds_count: current_user.pipelines.jobs_count_in_alive_pipelines
+ total_builds_count: current_user.pipelines.builds_count_in_alive_pipelines
}
end
diff --git a/lib/gitlab/request_forgery_protection.rb b/lib/gitlab/request_forgery_protection.rb
index a84a6ac2d14..258c904290d 100644
--- a/lib/gitlab/request_forgery_protection.rb
+++ b/lib/gitlab/request_forgery_protection.rb
@@ -6,6 +6,7 @@
module Gitlab
module RequestForgeryProtection
+ # rubocop:disable Rails/ApplicationController
class Controller < ActionController::Base
protect_from_forgery with: :exception, prepend: true
@@ -31,5 +32,6 @@ module Gitlab
rescue ActionController::InvalidAuthenticityToken
false
end
+ # rubocop:enable Rails/ApplicationController
end
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 89948816374..dbeb1447940 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -27054,12 +27054,18 @@ msgstr ""
msgid "Notify|%{paragraph_start}Hi %{name}!%{paragraph_end} %{paragraph_start}A new public key was added to your account:%{paragraph_end} %{paragraph_start}title: %{key_title}%{paragraph_end} %{paragraph_start}If this key was added in error, you can remove it under %{removal_link}%{paragraph_end}"
msgstr ""
+msgid "Notify|%{update_at_start} Last update at %{update_at_mid} %{last_update_at} %{update_at_end}"
+msgstr ""
+
msgid "Notify|%{updated_by_user_name} pushed new commits to merge request %{mr_link}"
msgstr ""
msgid "Notify|A new GPG key was added to your account:"
msgstr ""
+msgid "Notify|A remote mirror update has failed."
+msgstr ""
+
msgid "Notify|All discussions on merge request %{mr_link} were resolved by %{name}"
msgstr ""
@@ -27111,6 +27117,9 @@ msgstr ""
msgid "Notify|Learn more about Auto DevOps"
msgstr ""
+msgid "Notify|Logs may contain sensitive data. Please consider before forwarding this email."
+msgstr ""
+
msgid "Notify|Merge request %{merge_request} can no longer be merged due to conflict."
msgstr ""
@@ -27147,6 +27156,9 @@ msgstr ""
msgid "Notify|Pipeline %{pipeline_link} triggered by"
msgstr ""
+msgid "Notify|Remote mirror"
+msgstr ""
+
msgid "Notify|The Auto DevOps pipeline failed for pipeline %{pipeline_link} and has been disabled for %{project_link}. In order to use the Auto DevOps pipeline with your project, please review the %{supported_langs_link}, adjust your project accordingly, and turn on the Auto DevOps pipeline within your %{settings_link}."
msgstr ""
@@ -44092,6 +44104,9 @@ msgstr ""
msgid "Vulnerability|Project"
msgstr ""
+msgid "Vulnerability|Project:"
+msgstr ""
+
msgid "Vulnerability|Remove identifier row"
msgstr ""
@@ -44119,6 +44134,9 @@ msgstr ""
msgid "Vulnerability|Severity"
msgstr ""
+msgid "Vulnerability|Severity:"
+msgstr ""
+
msgid "Vulnerability|Status"
msgstr ""
diff --git a/rubocop/code_reuse_helpers.rb b/rubocop/code_reuse_helpers.rb
index 87b907f8778..245bbc31cbd 100644
--- a/rubocop/code_reuse_helpers.rb
+++ b/rubocop/code_reuse_helpers.rb
@@ -163,7 +163,7 @@ module RuboCop
each_send_node(node) do |send_node|
next unless send_receiver_name_ends_with?(send_node, suffix)
- add_offense(send_node, location: :expression, message: message)
+ add_offense(send_node, message: message)
end
end
diff --git a/rubocop/cop/active_model_errors_direct_manipulation.rb b/rubocop/cop/active_model_errors_direct_manipulation.rb
index e1e2840f37c..0a3af067743 100644
--- a/rubocop/cop/active_model_errors_direct_manipulation.rb
+++ b/rubocop/cop/active_model_errors_direct_manipulation.rb
@@ -6,7 +6,7 @@ module RuboCop
# in preparation to upgrade to Rails 6.1
#
# See https://gitlab.com/gitlab-org/gitlab/-/issues/225874
- class ActiveModelErrorsDirectManipulation < RuboCop::Cop::Cop
+ class ActiveModelErrorsDirectManipulation < RuboCop::Cop::Base
MSG = 'Avoid manipulating errors hash directly. For more details check https://gitlab.com/gitlab-org/gitlab/-/issues/225874'
MANIPULATIVE_METHODS = ":<< :append :clear :collect! :compact! :concat :delete :delete_at :delete_if :drop :drop_while :fill :filter! :keep_if :flatten! :insert :map! :pop :prepend :push :reject! :replace :reverse! :rotate! :select! :shift :shuffle! :slice! :sort! :sort_by! :uniq! :unshift"
@@ -50,10 +50,10 @@ module RuboCop
PATTERN
def on_send(node)
- add_offense(node, location: :expression) if active_model_errors_root_assignment?(node)
- add_offense(node, location: :expression) if active_model_errors_root_manipulation?(node)
- add_offense(node, location: :expression) if active_model_errors_manipulation?(node)
- add_offense(node, location: :expression) if active_model_errors_assignment?(node)
+ add_offense(node) if active_model_errors_root_assignment?(node)
+ add_offense(node) if active_model_errors_root_manipulation?(node)
+ add_offense(node) if active_model_errors_manipulation?(node)
+ add_offense(node) if active_model_errors_assignment?(node)
end
end
end
diff --git a/rubocop/cop/active_record_association_reload.rb b/rubocop/cop/active_record_association_reload.rb
index eb9fc8a0246..9a1e9674904 100644
--- a/rubocop/cop/active_record_association_reload.rb
+++ b/rubocop/cop/active_record_association_reload.rb
@@ -3,7 +3,7 @@
module RuboCop
module Cop
# Cop that blacklists the use of `reload`.
- class ActiveRecordAssociationReload < RuboCop::Cop::Cop
+ class ActiveRecordAssociationReload < RuboCop::Cop::Base
MSG = 'Use reset instead of reload. ' \
'For more details check the https://gitlab.com/gitlab-org/gitlab-foss/issues/60218.'
@@ -14,7 +14,7 @@ module RuboCop
def on_send(node)
return unless reload?(node)
- add_offense(node, location: :selector)
+ add_offense(node.loc.selector)
end
end
end
diff --git a/rubocop/cop/api/base.rb b/rubocop/cop/api/base.rb
index 85b19e9a833..c10115c8265 100644
--- a/rubocop/cop/api/base.rb
+++ b/rubocop/cop/api/base.rb
@@ -3,7 +3,9 @@
module RuboCop
module Cop
module API
- class Base < RuboCop::Cop::Cop
+ class Base < RuboCop::Cop::Base
+ extend RuboCop::Cop::AutoCorrector
+
# This cop checks that APIs subclass API::Base.
#
# @example
@@ -38,13 +40,9 @@ module RuboCop
def on_class(node)
grape_api_definition(node) do
- add_offense(node.children[1])
- end
- end
-
- def autocorrect(node)
- lambda do |corrector|
- corrector.replace(node, '::API::Base')
+ add_offense(node.children[1]) do |corrector|
+ corrector.replace(node.children[1], '::API::Base')
+ end
end
end
end
diff --git a/rubocop/cop/api/grape_array_missing_coerce.rb b/rubocop/cop/api/grape_array_missing_coerce.rb
index 3d7a6a72d81..5cb80e113a4 100644
--- a/rubocop/cop/api/grape_array_missing_coerce.rb
+++ b/rubocop/cop/api/grape_array_missing_coerce.rb
@@ -3,7 +3,7 @@
module RuboCop
module Cop
module API
- class GrapeArrayMissingCoerce < RuboCop::Cop::Cop
+ class GrapeArrayMissingCoerce < RuboCop::Cop::Base
# This cop checks that Grape API parameters using an Array type
# implement a coerce_with method:
#
diff --git a/rubocop/cop/avoid_becomes.rb b/rubocop/cop/avoid_becomes.rb
index cfd6b3d2164..20df394c32c 100644
--- a/rubocop/cop/avoid_becomes.rb
+++ b/rubocop/cop/avoid_becomes.rb
@@ -9,7 +9,7 @@ module RuboCop
# problems, even when a developer eager loaded all necessary associations.
#
# See https://gitlab.com/gitlab-org/gitlab/-/issues/23182 for more information.
- class AvoidBecomes < RuboCop::Cop::Cop
+ class AvoidBecomes < RuboCop::Cop::Base
MSG = 'Avoid the use of becomes(SomeConstant), as this creates a ' \
'new object and throws away any eager loaded associations. ' \
'When creating URLs in views, just use the path helpers directly. ' \
@@ -23,7 +23,7 @@ module RuboCop
PATTERN
def on_send(node)
- add_offense(node, location: :expression) if becomes?(node)
+ add_offense(node) if becomes?(node)
end
end
end
diff --git a/rubocop/cop/avoid_break_from_strong_memoize.rb b/rubocop/cop/avoid_break_from_strong_memoize.rb
index a3a8d0c3990..1a657a99966 100644
--- a/rubocop/cop/avoid_break_from_strong_memoize.rb
+++ b/rubocop/cop/avoid_break_from_strong_memoize.rb
@@ -20,7 +20,7 @@ module RuboCop
# do_an_heavy_calculation
# end
#
- class AvoidBreakFromStrongMemoize < RuboCop::Cop::Cop
+ class AvoidBreakFromStrongMemoize < RuboCop::Cop::Base
MSG = 'Do not use break inside strong_memoize, use next instead.'
def on_block(node)
diff --git a/rubocop/cop/avoid_keyword_arguments_in_sidekiq_workers.rb b/rubocop/cop/avoid_keyword_arguments_in_sidekiq_workers.rb
index da3cac073ad..ea7cdd5bf9d 100644
--- a/rubocop/cop/avoid_keyword_arguments_in_sidekiq_workers.rb
+++ b/rubocop/cop/avoid_keyword_arguments_in_sidekiq_workers.rb
@@ -3,7 +3,7 @@
module RuboCop
module Cop
# Cop that blacklists keyword arguments usage in Sidekiq workers
- class AvoidKeywordArgumentsInSidekiqWorkers < RuboCop::Cop::Cop
+ class AvoidKeywordArgumentsInSidekiqWorkers < RuboCop::Cop::Base
MSG = "Do not use keyword arguments in Sidekiq workers. " \
"For details, check https://github.com/mperham/sidekiq/issues/2372"
OBSERVED_METHOD = :perform
@@ -13,7 +13,7 @@ module RuboCop
node.arguments.each do |argument|
if argument.type == :kwarg || argument.type == :kwoptarg
- add_offense(node, location: :expression)
+ add_offense(node)
end
end
end
diff --git a/rubocop/cop/avoid_return_from_blocks.rb b/rubocop/cop/avoid_return_from_blocks.rb
index cc1868f10a4..61edfd0a789 100644
--- a/rubocop/cop/avoid_return_from_blocks.rb
+++ b/rubocop/cop/avoid_return_from_blocks.rb
@@ -20,7 +20,7 @@ module RuboCop
# do_something_else
# end
#
- class AvoidReturnFromBlocks < RuboCop::Cop::Cop
+ class AvoidReturnFromBlocks < RuboCop::Cop::Base
MSG = 'Do not return from a block, use next or break instead.'
DEF_METHODS = %i[define_method lambda].freeze
WHITELISTED_METHODS = %i[each each_filename times loop].freeze
diff --git a/rubocop/cop/avoid_route_redirect_leading_slash.rb b/rubocop/cop/avoid_route_redirect_leading_slash.rb
index 0b0dc7d3d33..0535ae16a33 100644
--- a/rubocop/cop/avoid_route_redirect_leading_slash.rb
+++ b/rubocop/cop/avoid_route_redirect_leading_slash.rb
@@ -13,7 +13,9 @@ module RuboCop
# root to: redirect('-/autocomplete/users')
#
- class AvoidRouteRedirectLeadingSlash < RuboCop::Cop::Cop
+ class AvoidRouteRedirectLeadingSlash < RuboCop::Cop::Base
+ extend RuboCop::Cop::AutoCorrector
+
MSG = 'Do not use a leading "/" in route redirects'
def_node_matcher :leading_slash_in_redirect?, <<~PATTERN
@@ -24,7 +26,9 @@ module RuboCop
return unless in_routes?(node)
return unless leading_slash_in_redirect?(node)
- add_offense(node)
+ add_offense(node) do |corrector|
+ corrector.replace(node.loc.expression, remove_leading_slash(node))
+ end
end
def has_leading_slash?(str)
@@ -38,12 +42,6 @@ module RuboCop
dirname.end_with?('config/routes') || filename.end_with?('routes.rb')
end
- def autocorrect(node)
- lambda do |corrector|
- corrector.replace(node.loc.expression, remove_leading_slash(node))
- end
- end
-
def remove_leading_slash(node)
node.source.sub('/', '')
end
diff --git a/rubocop/cop/ban_catch_throw.rb b/rubocop/cop/ban_catch_throw.rb
index 42301d5512f..3f215eb3140 100644
--- a/rubocop/cop/ban_catch_throw.rb
+++ b/rubocop/cop/ban_catch_throw.rb
@@ -19,7 +19,7 @@ module RuboCop
# # ...
# end
#
- class BanCatchThrow < RuboCop::Cop::Cop
+ class BanCatchThrow < RuboCop::Cop::Base
MSG = "Do not use catch or throw unless a gem's API demands it."
def on_send(node)
@@ -27,7 +27,7 @@ module RuboCop
return unless receiver.nil? && %i[catch throw].include?(method_name)
- add_offense(node, location: :expression)
+ add_offense(node)
end
end
end
diff --git a/rubocop/cop/code_reuse/finder.rb b/rubocop/cop/code_reuse/finder.rb
index 1d70befe79b..ed008f613a4 100644
--- a/rubocop/cop/code_reuse/finder.rb
+++ b/rubocop/cop/code_reuse/finder.rb
@@ -6,7 +6,7 @@ module RuboCop
module Cop
module CodeReuse
# Cop that enforces various code reuse rules for Finders.
- class Finder < RuboCop::Cop::Cop
+ class Finder < RuboCop::Cop::Base
include CodeReuseHelpers
IN_FINDER = 'Finders can not be used inside a Finder.'
diff --git a/rubocop/cop/code_reuse/presenter.rb b/rubocop/cop/code_reuse/presenter.rb
index 6eef5e5a4b0..9ceb7bde54e 100644
--- a/rubocop/cop/code_reuse/presenter.rb
+++ b/rubocop/cop/code_reuse/presenter.rb
@@ -6,7 +6,7 @@ module RuboCop
module Cop
module CodeReuse
# Cop that enforces various code reuse rules for Presenter classes.
- class Presenter < RuboCop::Cop::Cop
+ class Presenter < RuboCop::Cop::Base
include CodeReuseHelpers
IN_SERVICE = 'Presenters can not be used in a Service class.'
diff --git a/rubocop/cop/code_reuse/serializer.rb b/rubocop/cop/code_reuse/serializer.rb
index 17a84ec31f7..493432c69da 100644
--- a/rubocop/cop/code_reuse/serializer.rb
+++ b/rubocop/cop/code_reuse/serializer.rb
@@ -6,7 +6,7 @@ module RuboCop
module Cop
module CodeReuse
# Cop that enforces various code reuse rules for Serializer classes.
- class Serializer < RuboCop::Cop::Cop
+ class Serializer < RuboCop::Cop::Base
include CodeReuseHelpers
IN_SERVICE = 'Serializers can not be used in a Service class.'
diff --git a/rubocop/cop/code_reuse/service_class.rb b/rubocop/cop/code_reuse/service_class.rb
index e403a87093c..e9002f232a2 100644
--- a/rubocop/cop/code_reuse/service_class.rb
+++ b/rubocop/cop/code_reuse/service_class.rb
@@ -6,7 +6,7 @@ module RuboCop
module Cop
module CodeReuse
# Cop that enforces various code reuse rules for Service classes.
- class ServiceClass < RuboCop::Cop::Cop
+ class ServiceClass < RuboCop::Cop::Base
include CodeReuseHelpers
IN_FINDER = 'Service classes can not be used in a Finder.'
diff --git a/rubocop/cop/code_reuse/worker.rb b/rubocop/cop/code_reuse/worker.rb
index 3a1120ac2a1..f39ffbe9c6f 100644
--- a/rubocop/cop/code_reuse/worker.rb
+++ b/rubocop/cop/code_reuse/worker.rb
@@ -6,7 +6,7 @@ module RuboCop
module Cop
module CodeReuse
# Cop that enforces various code reuse rules for workers.
- class Worker < RuboCop::Cop::Cop
+ class Worker < RuboCop::Cop::Base
include CodeReuseHelpers
IN_CONTROLLER = 'Workers can not be used in a controller.'
diff --git a/rubocop/cop/database/disable_referential_integrity.rb b/rubocop/cop/database/disable_referential_integrity.rb
index 80d52678011..9e201e2d143 100644
--- a/rubocop/cop/database/disable_referential_integrity.rb
+++ b/rubocop/cop/database/disable_referential_integrity.rb
@@ -4,7 +4,7 @@ module RuboCop
module Cop
module Database
# Cop that checks if 'disable_referential_integrity' method is called.
- class DisableReferentialIntegrity < RuboCop::Cop::Cop
+ class DisableReferentialIntegrity < RuboCop::Cop::Base
MSG = <<~TEXT
Do not use `disable_referential_integrity`, disable triggers in a safe
transaction instead. Follow the format:
diff --git a/rubocop/cop/database/establish_connection.rb b/rubocop/cop/database/establish_connection.rb
index 20454887ce2..3681974640b 100644
--- a/rubocop/cop/database/establish_connection.rb
+++ b/rubocop/cop/database/establish_connection.rb
@@ -3,7 +3,7 @@
module RuboCop
module Cop
module Database
- class EstablishConnection < RuboCop::Cop::Cop
+ class EstablishConnection < RuboCop::Cop::Base
MSG = "Don't establish new database connections, as this slows down " \
'tests and may result in new connections using an incorrect configuration'
@@ -12,7 +12,7 @@ module RuboCop
PATTERN
def on_send(node)
- add_offense(node, location: :expression) if establish_connection?(node)
+ add_offense(node) if establish_connection?(node)
end
end
end
diff --git a/rubocop/cop/database/multiple_databases.rb b/rubocop/cop/database/multiple_databases.rb
index 1ac9bb4473b..33ff8acd4d8 100644
--- a/rubocop/cop/database/multiple_databases.rb
+++ b/rubocop/cop/database/multiple_databases.rb
@@ -10,7 +10,7 @@ module RuboCop
# # good
# ApplicationRecord.connection
#
- class MultipleDatabases < RuboCop::Cop::Cop
+ class MultipleDatabases < RuboCop::Cop::Base
AR_BASE_MESSAGE = <<~EOF
Do not use methods from ActiveRecord::Base, use the ApplicationRecord class instead
For fixing offenses related to the ActiveRecord::Base.transaction method, see our guidelines:
@@ -32,7 +32,7 @@ module RuboCop
active_record_base_method = node.children[1]
return if method_is_allowed?(active_record_base_method)
- add_offense(node, location: :expression, message: AR_BASE_MESSAGE)
+ add_offense(node, message: AR_BASE_MESSAGE)
end
private
diff --git a/rubocop/cop/database/rescue_query_canceled.rb b/rubocop/cop/database/rescue_query_canceled.rb
index 1238f9ed911..01f3ba272c2 100644
--- a/rubocop/cop/database/rescue_query_canceled.rb
+++ b/rubocop/cop/database/rescue_query_canceled.rb
@@ -20,7 +20,7 @@ module RuboCop
# # good
#
# run_cheap_queries_with_each_batch
- class RescueQueryCanceled < RuboCop::Cop::Cop
+ class RescueQueryCanceled < RuboCop::Cop::Base
MSG = <<~EOF
Avoid rescuing the `ActiveRecord::QueryCanceled` class.
diff --git a/rubocop/cop/database/rescue_statement_timeout.rb b/rubocop/cop/database/rescue_statement_timeout.rb
index 0b75a441e29..a0e9396e8f4 100644
--- a/rubocop/cop/database/rescue_statement_timeout.rb
+++ b/rubocop/cop/database/rescue_statement_timeout.rb
@@ -20,7 +20,7 @@ module RuboCop
# # good
#
# run_cheap_queries_with_each_batch
- class RescueStatementTimeout < RuboCop::Cop::Cop
+ class RescueStatementTimeout < RuboCop::Cop::Base
MSG = <<~EOF
Avoid rescuing the `ActiveRecord::StatementTimeout` class.
diff --git a/rubocop/cop/default_scope.rb b/rubocop/cop/default_scope.rb
index 39f8c8e9ed0..930a69be881 100644
--- a/rubocop/cop/default_scope.rb
+++ b/rubocop/cop/default_scope.rb
@@ -3,7 +3,7 @@
module RuboCop
module Cop
# Cop that blacklists the use of `default_scope`.
- class DefaultScope < RuboCop::Cop::Cop
+ class DefaultScope < RuboCop::Cop::Base
MSG = <<~EOF
Do not use `default_scope`, as it does not follow the principle of
least surprise. See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33847
@@ -17,7 +17,7 @@ module RuboCop
def on_send(node)
return unless default_scope?(node)
- add_offense(node, location: :expression)
+ add_offense(node)
end
end
end
diff --git a/rubocop/cop/destroy_all.rb b/rubocop/cop/destroy_all.rb
index 38b6cb40f91..78e5d0f25f3 100644
--- a/rubocop/cop/destroy_all.rb
+++ b/rubocop/cop/destroy_all.rb
@@ -3,7 +3,7 @@
module RuboCop
module Cop
# Cop that blacklists the use of `destroy_all`.
- class DestroyAll < RuboCop::Cop::Cop
+ class DestroyAll < RuboCop::Cop::Base
MSG = 'Use `delete_all` instead of `destroy_all`. ' \
'`destroy_all` will load the rows into memory, then execute a ' \
'`DELETE` for every individual row.'
@@ -15,7 +15,7 @@ module RuboCop
def on_send(node)
return unless destroy_all?(node)
- add_offense(node, location: :expression)
+ add_offense(node)
end
end
end
diff --git a/rubocop/cop/file_decompression.rb b/rubocop/cop/file_decompression.rb
index 44813244028..e1e645e6d62 100644
--- a/rubocop/cop/file_decompression.rb
+++ b/rubocop/cop/file_decompression.rb
@@ -3,7 +3,7 @@
module RuboCop
module Cop
# Check for symlinks when extracting files to avoid arbitrary file reading.
- class FileDecompression < RuboCop::Cop::Cop
+ class FileDecompression < RuboCop::Cop::Base
MSG = <<~EOF
While extracting files check for symlink to avoid arbitrary file reading.
https://gitlab.com/gitlab-com/gl-infra/production/-/issues/6132
@@ -29,7 +29,7 @@ module RuboCop
def on_send(node)
system?(node) do |match|
- add_offense(node, location: :expression, message: MSG) if forbidden_command?(match)
+ add_offense(node, message: MSG) if forbidden_command?(match)
end
end
diff --git a/rubocop/cop/filename_length.rb b/rubocop/cop/filename_length.rb
index 815db7de3f5..948f69cc88c 100644
--- a/rubocop/cop/filename_length.rb
+++ b/rubocop/cop/filename_length.rb
@@ -2,7 +2,7 @@
module RuboCop
module Cop
- class FilenameLength < Cop
+ class FilenameLength < RuboCop::Cop::Base
include RangeHelp
FILEPATH_MAX_BYTES = 256
@@ -10,14 +10,14 @@ module RuboCop
MSG_FILEPATH_LEN = "This file path is too long. It should be #{FILEPATH_MAX_BYTES} or less"
MSG_FILENAME_LEN = "This file name is too long. It should be #{FILENAME_MAX_BYTES} or less"
- def investigate(processed_source)
+ def on_new_investigation
file_path = processed_source.file_path
return if config.file_to_exclude?(file_path)
if file_path.bytesize > FILEPATH_MAX_BYTES
- add_offense(nil, location: source_range(processed_source.buffer, 1, 0, 1), message: MSG_FILEPATH_LEN)
+ add_offense(source_range(processed_source.buffer, 1, 0), message: MSG_FILEPATH_LEN)
elsif File.basename(file_path).bytesize > FILENAME_MAX_BYTES
- add_offense(nil, location: source_range(processed_source.buffer, 1, 0, 1), message: MSG_FILENAME_LEN)
+ add_offense(source_range(processed_source.buffer, 1, 0), message: MSG_FILENAME_LEN)
end
end
end
diff --git a/rubocop/cop/gitlab/avoid_feature_category_not_owned.rb b/rubocop/cop/gitlab/avoid_feature_category_not_owned.rb
index fb790f44a96..05d7824f92e 100644
--- a/rubocop/cop/gitlab/avoid_feature_category_not_owned.rb
+++ b/rubocop/cop/gitlab/avoid_feature_category_not_owned.rb
@@ -5,7 +5,7 @@ require_relative '../../code_reuse_helpers'
module RuboCop
module Cop
module Gitlab
- class AvoidFeatureCategoryNotOwned < RuboCop::Cop::Cop
+ class AvoidFeatureCategoryNotOwned < RuboCop::Cop::Base
include ::RuboCop::CodeReuseHelpers
MSG = 'Avoid adding new endpoints with `feature_category :not_owned`. See https://docs.gitlab.com/ee/development/feature_categorization'
@@ -25,7 +25,7 @@ module RuboCop
return unless file_needs_feature_category?(node)
return unless setting_not_owned?(node)
- add_offense(node, location: :expression)
+ add_offense(node)
end
private
diff --git a/rubocop/cop/gitlab/avoid_feature_get.rb b/rubocop/cop/gitlab/avoid_feature_get.rb
index 7664f66521a..68aaff8aeff 100644
--- a/rubocop/cop/gitlab/avoid_feature_get.rb
+++ b/rubocop/cop/gitlab/avoid_feature_get.rb
@@ -20,7 +20,7 @@ module RuboCop
# Feature.enable_percentage_of_time(:x, 100)
# Feature.remove(:x)
#
- class AvoidFeatureGet < RuboCop::Cop::Cop
+ class AvoidFeatureGet < RuboCop::Cop::Base
MSG = 'Use `stub_feature_flags` method instead of `Feature.get`. ' \
'See doc/development/feature_flags/index.md#feature-flags-in-tests for more information.'
@@ -31,7 +31,7 @@ module RuboCop
def on_send(node)
return unless feature_get?(node)
- add_offense(node, location: :selector)
+ add_offense(node.loc.selector)
end
end
end
diff --git a/rubocop/cop/gitlab/avoid_uploaded_file_from_params.rb b/rubocop/cop/gitlab/avoid_uploaded_file_from_params.rb
index 0795f96732d..cb3382c1b75 100644
--- a/rubocop/cop/gitlab/avoid_uploaded_file_from_params.rb
+++ b/rubocop/cop/gitlab/avoid_uploaded_file_from_params.rb
@@ -33,7 +33,7 @@ module RuboCop
# uploaded_file = declared_params[:file]
# end
# end
- class AvoidUploadedFileFromParams < RuboCop::Cop::Cop
+ class AvoidUploadedFileFromParams < RuboCop::Cop::Base
MSG = 'Use the `UploadedFile` set by `multipart.rb` instead of calling `UploadedFile.from_params` directly. See https://docs.gitlab.com/ee/development/uploads/working_with_uploads.html'
def_node_matcher :calling_uploaded_file_from_params?, <<~PATTERN
@@ -43,7 +43,7 @@ module RuboCop
def on_send(node)
return unless calling_uploaded_file_from_params?(node)
- add_offense(node, location: :expression)
+ add_offense(node)
end
end
end
diff --git a/rubocop/cop/gitlab/bulk_insert.rb b/rubocop/cop/gitlab/bulk_insert.rb
index baaefc2533c..f88dcde2dc2 100644
--- a/rubocop/cop/gitlab/bulk_insert.rb
+++ b/rubocop/cop/gitlab/bulk_insert.rb
@@ -5,7 +5,7 @@ module RuboCop
module Gitlab
# Cop that disallows the use of `legacy_bulk_insert`, in favour of using
# the `BulkInsertSafe` module.
- class BulkInsert < RuboCop::Cop::Cop
+ class BulkInsert < RuboCop::Cop::Base
MSG = 'Use the `BulkInsertSafe` concern, instead of using `LegacyBulkInsert.bulk_insert`. See https://docs.gitlab.com/ee/development/insert_into_tables_in_batches.html'
def_node_matcher :raw_union?, <<~PATTERN
@@ -15,7 +15,7 @@ module RuboCop
def on_send(node)
return unless raw_union?(node)
- add_offense(node, location: :expression)
+ add_offense(node)
end
end
end
diff --git a/rubocop/cop/gitlab/change_timezone.rb b/rubocop/cop/gitlab/change_timezone.rb
index c30a057d51c..a5d9393b6c3 100644
--- a/rubocop/cop/gitlab/change_timezone.rb
+++ b/rubocop/cop/gitlab/change_timezone.rb
@@ -3,7 +3,7 @@
module RuboCop
module Cop
module Gitlab
- class ChangeTimezone < RuboCop::Cop::Cop
+ class ChangeTimezone < RuboCop::Cop::Base
MSG = "Do not change timezone in the runtime (application or rspec), " \
"it could result in silently modifying other behavior."
diff --git a/rubocop/cop/gitlab/const_get_inherit_false.rb b/rubocop/cop/gitlab/const_get_inherit_false.rb
index 3d3bbc4c8d3..e44097a8d9e 100644
--- a/rubocop/cop/gitlab/const_get_inherit_false.rb
+++ b/rubocop/cop/gitlab/const_get_inherit_false.rb
@@ -6,7 +6,9 @@ module RuboCop
# Cop that encourages usage of inherit=false for 2nd argument when using const_get.
#
# See https://gitlab.com/gitlab-org/gitlab/issues/27678
- class ConstGetInheritFalse < RuboCop::Cop::Cop
+ class ConstGetInheritFalse < RuboCop::Cop::Base
+ extend RuboCop::Cop::AutoCorrector
+
MSG = 'Use inherit=false when using const_get.'
def_node_matcher :const_get?, <<~PATTERN
@@ -17,11 +19,7 @@ module RuboCop
return unless const_get?(node)
return if second_argument(node)&.false_type?
- add_offense(node, location: :selector)
- end
-
- def autocorrect(node)
- lambda do |corrector|
+ add_offense(node.loc.selector) do |corrector|
if arg = second_argument(node)
corrector.replace(arg.source_range, 'false')
else
diff --git a/rubocop/cop/gitlab/delegate_predicate_methods.rb b/rubocop/cop/gitlab/delegate_predicate_methods.rb
index 43b5184faab..9e6a2823719 100644
--- a/rubocop/cop/gitlab/delegate_predicate_methods.rb
+++ b/rubocop/cop/gitlab/delegate_predicate_methods.rb
@@ -21,7 +21,7 @@ module RuboCop
# def is_foo?
# !!bar&.is_foo?
# end
- class DelegatePredicateMethods < RuboCop::Cop::Cop
+ class DelegatePredicateMethods < RuboCop::Cop::Base
MSG = "Using `delegate` with `allow_nil` on the following predicate methods is discouraged: %s."
RESTRICT_ON_SEND = %i[delegate].freeze
def_node_matcher :predicate_allow_nil_option, <<~PATTERN
diff --git a/rubocop/cop/gitlab/deprecate_track_redis_hll_event.rb b/rubocop/cop/gitlab/deprecate_track_redis_hll_event.rb
index 3e30f3aa4d0..58411357eeb 100644
--- a/rubocop/cop/gitlab/deprecate_track_redis_hll_event.rb
+++ b/rubocop/cop/gitlab/deprecate_track_redis_hll_event.rb
@@ -14,7 +14,7 @@ module RuboCop
#
# # good
# track_event :show, name: 'g_analytics_valuestream', destinations: [:redis_hll]
- class DeprecateTrackRedisHLLEvent < RuboCop::Cop::Cop
+ class DeprecateTrackRedisHLLEvent < RuboCop::Cop::Base
MSG = '`track_redis_hll_event` is deprecated. Use `track_event` helper instead. ' \
'See https://docs.gitlab.com/ee/development/service_ping/implement.html#add-new-events'
@@ -25,7 +25,7 @@ module RuboCop
def on_send(node)
return unless track_redis_hll_event_used?(node)
- add_offense(node, location: :selector)
+ add_offense(node.loc.selector)
end
end
end
diff --git a/rubocop/cop/gitlab/event_store_subscriber.rb b/rubocop/cop/gitlab/event_store_subscriber.rb
index 0b2dd94bc42..7e4cc3e66cc 100644
--- a/rubocop/cop/gitlab/event_store_subscriber.rb
+++ b/rubocop/cop/gitlab/event_store_subscriber.rb
@@ -30,7 +30,7 @@ module RuboCop
# end
# end
#
- class EventStoreSubscriber < RuboCop::Cop::Cop
+ class EventStoreSubscriber < RuboCop::Cop::Base
SUBSCRIBER_MODULE_NAME = 'Gitlab::EventStore::Subscriber'
FORBID_PERFORM_OVERRIDE = "Do not override `perform` in a `#{SUBSCRIBER_MODULE_NAME}`."
REQUIRE_HANDLE_EVENT = "A `#{SUBSCRIBER_MODULE_NAME}` must implement `#handle_event(event)`."
diff --git a/rubocop/cop/gitlab/except.rb b/rubocop/cop/gitlab/except.rb
index 24da6962457..d20cf47b473 100644
--- a/rubocop/cop/gitlab/except.rb
+++ b/rubocop/cop/gitlab/except.rb
@@ -5,7 +5,7 @@ module RuboCop
module Gitlab
# Cop that disallows the use of `Gitlab::SQL::Except`, in favour of using
# the `FromExcept` module.
- class Except < RuboCop::Cop::Cop
+ class Except < RuboCop::Cop::Base
MSG = 'Use the `FromExcept` concern, instead of using `Gitlab::SQL::Except` directly'
def_node_matcher :raw_except?, <<~PATTERN
@@ -15,7 +15,7 @@ module RuboCop
def on_send(node)
return unless raw_except?(node)
- add_offense(node, location: :expression)
+ add_offense(node)
end
end
end
diff --git a/rubocop/cop/gitlab/feature_available_usage.rb b/rubocop/cop/gitlab/feature_available_usage.rb
index f748b7d9111..3e0385c4018 100644
--- a/rubocop/cop/gitlab/feature_available_usage.rb
+++ b/rubocop/cop/gitlab/feature_available_usage.rb
@@ -4,7 +4,7 @@ module RuboCop
module Cop
module Gitlab
# Cop that checks for correct calling of #feature_available?
- class FeatureAvailableUsage < RuboCop::Cop::Cop
+ class FeatureAvailableUsage < RuboCop::Cop::Base
OBSERVED_METHOD = :feature_available?
LICENSED_FEATURE_LITERAL_ARG_MSG = '`feature_available?` should not be called for features that can be licensed (`%s` given), use `licensed_feature_available?(feature)` instead.'
LICENSED_FEATURE_DYNAMIC_ARG_MSG = "`feature_available?` should not be called for features that can be licensed (`%s` isn't a literal so we cannot say if it's legit or not), using `licensed_feature_available?(feature)` may be more appropriate."
@@ -38,9 +38,9 @@ module RuboCop
return if ALL_FEATURES.include?(feature_name(node)) && args_count(node) == 2
if !ALL_FEATURES.include?(feature_name(node))
- add_offense(node, location: :expression, message: licensed_feature_message(node))
+ add_offense(node, message: licensed_feature_message(node))
elsif args_count(node) < 2
- add_offense(node, location: :expression, message: NOT_ENOUGH_ARGS_MSG)
+ add_offense(node, message: NOT_ENOUGH_ARGS_MSG)
end
end
diff --git a/rubocop/cop/gitlab/finder_with_find_by.rb b/rubocop/cop/gitlab/finder_with_find_by.rb
index 8fa9fe4a2f9..ac454398f9c 100644
--- a/rubocop/cop/gitlab/finder_with_find_by.rb
+++ b/rubocop/cop/gitlab/finder_with_find_by.rb
@@ -3,8 +3,10 @@
module RuboCop
module Cop
module Gitlab
- class FinderWithFindBy < RuboCop::Cop::Cop
- FIND_PATTERN = /\Afind(_by\!?)?\z/.freeze
+ class FinderWithFindBy < RuboCop::Cop::Base
+ extend RuboCop::Cop::AutoCorrector
+
+ FIND_PATTERN = /\Afind(_by!?)?\z/.freeze
ALLOWED_MODULES = ['FinderMethods'].freeze
def message(used_method)
@@ -18,13 +20,9 @@ module RuboCop
end
def on_send(node)
- if find_on_execute?(node) && !allowed_module?(node)
- add_offense(node, location: :selector, message: message(node.method_name))
- end
- end
+ return unless find_on_execute?(node) && !allowed_module?(node)
- def autocorrect(node)
- lambda do |corrector|
+ add_offense(node.loc.selector, message: message(node.method_name)) do |corrector|
upto_including_execute = node.descendants.first.source_range
before_execute = node.descendants[1].source_range
range_to_remove = node.source_range
diff --git a/rubocop/cop/gitlab/httparty.rb b/rubocop/cop/gitlab/httparty.rb
index 20f0c381e11..f57c605ce91 100644
--- a/rubocop/cop/gitlab/httparty.rb
+++ b/rubocop/cop/gitlab/httparty.rb
@@ -3,7 +3,9 @@
module RuboCop
module Cop
module Gitlab
- class HTTParty < RuboCop::Cop::Cop
+ class HTTParty < RuboCop::Cop::Base
+ extend RuboCop::Cop::AutoCorrector
+
MSG_SEND = <<~EOL
Avoid calling `HTTParty` directly. Instead, use the Gitlab::HTTP
wrapper. To allow request to localhost or the private network set
@@ -25,31 +27,18 @@ module RuboCop
PATTERN
def on_send(node)
- add_offense(node, location: :expression, message: MSG_SEND) if httparty_node?(node)
- add_offense(node, location: :expression, message: MSG_INCLUDE) if includes_httparty?(node)
- end
-
- def autocorrect(node)
- if includes_httparty?(node)
- autocorrect_includes_httparty(node)
- else
- autocorrect_httparty_node(node)
- end
- end
-
- def autocorrect_includes_httparty(node)
- lambda do |corrector|
- corrector.remove(node.source_range)
- end
- end
-
- def autocorrect_httparty_node(node)
- _, method_name, *arg_nodes = *node
-
- replacement = "Gitlab::HTTP.#{method_name}(#{arg_nodes.map(&:source).join(', ')})"
-
- lambda do |corrector|
- corrector.replace(node.source_range, replacement)
+ if httparty_node?(node)
+ add_offense(node, message: MSG_SEND) do |corrector|
+ _, method_name, *arg_nodes = *node
+
+ replacement = "Gitlab::HTTP.#{method_name}(#{arg_nodes.map(&:source).join(', ')})"
+
+ corrector.replace(node.source_range, replacement)
+ end
+ elsif includes_httparty?(node)
+ add_offense(node, message: MSG_INCLUDE) do |corrector|
+ corrector.remove(node.source_range)
+ end
end
end
end
diff --git a/rubocop/cop/gitlab/intersect.rb b/rubocop/cop/gitlab/intersect.rb
index 4b61073b804..e608b25cbe1 100644
--- a/rubocop/cop/gitlab/intersect.rb
+++ b/rubocop/cop/gitlab/intersect.rb
@@ -5,7 +5,7 @@ module RuboCop
module Gitlab
# Cop that disallows the use of `Gitlab::SQL::Intersect`, in favour of using
# the `FromIntersect` module.
- class Intersect < RuboCop::Cop::Cop
+ class Intersect < RuboCop::Cop::Base
MSG = 'Use the `FromIntersect` concern, instead of using `Gitlab::SQL::Intersect` directly'
def_node_matcher :raw_intersect?, <<~PATTERN
@@ -15,7 +15,7 @@ module RuboCop
def on_send(node)
return unless raw_intersect?(node)
- add_offense(node, location: :expression)
+ add_offense(node)
end
end
end
diff --git a/rubocop/cop/gitlab/json.rb b/rubocop/cop/gitlab/json.rb
index d2ba0012ca0..56846e3c276 100644
--- a/rubocop/cop/gitlab/json.rb
+++ b/rubocop/cop/gitlab/json.rb
@@ -3,7 +3,9 @@
module RuboCop
module Cop
module Gitlab
- class Json < RuboCop::Cop::Cop
+ class Json < RuboCop::Cop::Base
+ extend RuboCop::Cop::AutoCorrector
+
MSG = <<~EOL
Avoid calling `JSON` directly. Instead, use the `Gitlab::Json`
wrapper. This allows us to alter the JSON parser being used.
@@ -14,19 +16,13 @@ module RuboCop
PATTERN
def on_send(node)
- add_offense(node) if json_node?(node)
- end
-
- def autocorrect(node)
- autocorrect_json_node(node)
- end
+ return unless json_node?(node)
- def autocorrect_json_node(node)
- _, method_name, *arg_nodes = *node
+ add_offense(node) do |corrector|
+ _, method_name, *arg_nodes = *node
- replacement = "Gitlab::Json.#{method_name}(#{arg_nodes.map(&:source).join(', ')})"
+ replacement = "Gitlab::Json.#{method_name}(#{arg_nodes.map(&:source).join(', ')})"
- lambda do |corrector|
corrector.replace(node.source_range, replacement)
end
end
diff --git a/rubocop/cop/gitlab/mark_used_feature_flags.rb b/rubocop/cop/gitlab/mark_used_feature_flags.rb
index 8fbcc56b906..8d8c84e78f5 100644
--- a/rubocop/cop/gitlab/mark_used_feature_flags.rb
+++ b/rubocop/cop/gitlab/mark_used_feature_flags.rb
@@ -9,7 +9,7 @@ module RuboCop
#
# The files set in `tmp/feature_flags/*.used` can then be used for verification purpose.
#
- class MarkUsedFeatureFlags < RuboCop::Cop::Cop
+ class MarkUsedFeatureFlags < RuboCop::Cop::Base
include RuboCop::CodeReuseHelpers
FEATURE_METHODS = %i[enabled? disabled?].freeze
diff --git a/rubocop/cop/gitlab/module_with_instance_variables.rb b/rubocop/cop/gitlab/module_with_instance_variables.rb
index 40cdc0d3a57..e43ede61b7e 100644
--- a/rubocop/cop/gitlab/module_with_instance_variables.rb
+++ b/rubocop/cop/gitlab/module_with_instance_variables.rb
@@ -3,7 +3,7 @@
module RuboCop
module Cop
module Gitlab
- class ModuleWithInstanceVariables < RuboCop::Cop::Cop
+ class ModuleWithInstanceVariables < RuboCop::Cop::Base
MSG = <<~EOL
Do not use instance variables in a module. Please read this
for the rationale behind it:
@@ -32,12 +32,12 @@ module RuboCop
if only_ivar_or_assignment?(definition)
# We don't allow if any other ivar is used
definition.each_descendant(:ivar) do |offense|
- add_offense(offense, location: :expression)
+ add_offense(offense)
end
# We allow initialize method and single ivar
elsif !initialize_method?(definition) && !single_ivar?(definition)
definition.each_descendant(:ivar, :ivasgn) do |offense|
- add_offense(offense, location: :expression)
+ add_offense(offense)
end
end
end
diff --git a/rubocop/cop/gitlab/policy_rule_boolean.rb b/rubocop/cop/gitlab/policy_rule_boolean.rb
index ca69eebab6e..ddf100fc8a1 100644
--- a/rubocop/cop/gitlab/policy_rule_boolean.rb
+++ b/rubocop/cop/gitlab/policy_rule_boolean.rb
@@ -22,7 +22,7 @@ module RuboCop
# # good
# rule { conducts_electricity & can?(:magnetize) }.enable :motor
# rule { ~conducts_electricity & batteries }.enable :motor
- class PolicyRuleBoolean < RuboCop::Cop::Cop
+ class PolicyRuleBoolean < RuboCop::Cop::Base
def_node_search :has_and_operator?, <<~PATTERN
(and ...)
PATTERN
diff --git a/rubocop/cop/gitlab/predicate_memoization.rb b/rubocop/cop/gitlab/predicate_memoization.rb
index 4c851f90238..3fbd004655f 100644
--- a/rubocop/cop/gitlab/predicate_memoization.rb
+++ b/rubocop/cop/gitlab/predicate_memoization.rb
@@ -3,7 +3,7 @@
module RuboCop
module Cop
module Gitlab
- class PredicateMemoization < RuboCop::Cop::Cop
+ class PredicateMemoization < RuboCop::Cop::Base
MSG = <<~EOL
Avoid using `@value ||= query` inside predicate methods in order to
properly memoize `false` or `nil` values.
diff --git a/rubocop/cop/gitlab/rails_logger.rb b/rubocop/cop/gitlab/rails_logger.rb
index 5a1695ce56e..ae05491ca7d 100644
--- a/rubocop/cop/gitlab/rails_logger.rb
+++ b/rubocop/cop/gitlab/rails_logger.rb
@@ -38,7 +38,7 @@ module RuboCop
def on_send(node)
return unless rails_logger_log?(node)
- add_offense(node, location: :expression)
+ add_offense(node)
end
end
end
diff --git a/rubocop/cop/gitlab/union.rb b/rubocop/cop/gitlab/union.rb
index c44c847657b..36ec6bb9b7f 100644
--- a/rubocop/cop/gitlab/union.rb
+++ b/rubocop/cop/gitlab/union.rb
@@ -5,7 +5,7 @@ module RuboCop
module Gitlab
# Cop that disallows the use of `Gitlab::SQL::Union`, in favour of using
# the `FromUnion` module.
- class Union < RuboCop::Cop::Cop
+ class Union < RuboCop::Cop::Base
MSG = 'Use the `FromUnion` concern, instead of using `Gitlab::SQL::Union` directly'
def_node_matcher :raw_union?, <<~PATTERN
@@ -15,7 +15,7 @@ module RuboCop
def on_send(node)
return unless raw_union?(node)
- add_offense(node, location: :expression)
+ add_offense(node)
end
end
end
diff --git a/rubocop/cop/graphql/authorize_types.rb b/rubocop/cop/graphql/authorize_types.rb
index c96919343d6..7bd2cd9f7ef 100644
--- a/rubocop/cop/graphql/authorize_types.rb
+++ b/rubocop/cop/graphql/authorize_types.rb
@@ -3,7 +3,7 @@
module RuboCop
module Cop
module Graphql
- class AuthorizeTypes < RuboCop::Cop::Cop
+ class AuthorizeTypes < RuboCop::Cop::Base
MSG = 'Add an `authorize :ability` call to the type: '\
'https://docs.gitlab.com/ee/development/graphql_guide/authorization.html#type-authorization'
@@ -19,7 +19,7 @@ module RuboCop
return if allowed?(class_constant(node))
return if allowed?(superclass_constant(node))
- add_offense(node, location: :expression) unless authorize?(node)
+ add_offense(node) unless authorize?(node)
end
private
diff --git a/rubocop/cop/graphql/descriptions.rb b/rubocop/cop/graphql/descriptions.rb
index 0d69fd55931..3c945507699 100644
--- a/rubocop/cop/graphql/descriptions.rb
+++ b/rubocop/cop/graphql/descriptions.rb
@@ -42,7 +42,9 @@
module RuboCop
module Cop
module Graphql
- class Descriptions < RuboCop::Cop::Cop
+ class Descriptions < RuboCop::Cop::Base
+ extend RuboCop::Cop::AutoCorrector
+
MSG_STYLE_GUIDE_LINK = 'See the description style guide: https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#description-style-guide'
MSG_NO_DESCRIPTION = "Please add a `description` property. #{MSG_STYLE_GUIDE_LINK}"
MSG_NO_PERIOD = "`description` strings must end with a `.`. #{MSG_STYLE_GUIDE_LINK}"
@@ -74,15 +76,17 @@ module RuboCop
description = locate_description(node)
- return add_offense(node, location: :expression, message: MSG_NO_DESCRIPTION) unless description
+ message = if description.nil?
+ MSG_NO_DESCRIPTION
+ elsif no_period?(description)
+ MSG_NO_PERIOD
+ elsif bad_start?(description)
+ MSG_BAD_START
+ end
- add_offense(node, location: :expression, message: MSG_NO_PERIOD) if no_period?(description)
- add_offense(node, location: :expression, message: MSG_BAD_START) if bad_start?(description)
- end
+ return unless message
- # Autocorrect missing periods at end of description.
- def autocorrect(node)
- lambda do |corrector|
+ add_offense(node, message: message) do |corrector|
description = locate_description(node)
next unless description
diff --git a/rubocop/cop/graphql/gid_expected_type.rb b/rubocop/cop/graphql/gid_expected_type.rb
index 354c5516752..7e802e6d2db 100644
--- a/rubocop/cop/graphql/gid_expected_type.rb
+++ b/rubocop/cop/graphql/gid_expected_type.rb
@@ -3,7 +3,7 @@
module RuboCop
module Cop
module Graphql
- class GIDExpectedType < RuboCop::Cop::Cop
+ class GIDExpectedType < RuboCop::Cop::Base
MSG = 'Add an expected_type parameter to #object_from_id calls if possible.'
def_node_search :id_from_object?, <<~PATTERN
diff --git a/rubocop/cop/graphql/graphql_name_position.rb b/rubocop/cop/graphql/graphql_name_position.rb
index f18d65588cc..b876fb5b088 100644
--- a/rubocop/cop/graphql/graphql_name_position.rb
+++ b/rubocop/cop/graphql/graphql_name_position.rb
@@ -20,7 +20,7 @@
module RuboCop
module Cop
module Graphql
- class GraphqlNamePosition < RuboCop::Cop::Cop
+ class GraphqlNamePosition < RuboCop::Cop::Base
MSG = '`graphql_name` should be the first line of the class: '\
'https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#naming-conventions'
@@ -32,7 +32,7 @@ module RuboCop
return unless graphql_name?(node)
return if node.body.single_line?
- add_offense(node, location: :expression) unless graphql_name?(node.body.children.first)
+ add_offense(node) unless graphql_name?(node.body.children.first)
end
end
end
diff --git a/rubocop/cop/graphql/id_type.rb b/rubocop/cop/graphql/id_type.rb
index ba973242efa..eb677aa4507 100644
--- a/rubocop/cop/graphql/id_type.rb
+++ b/rubocop/cop/graphql/id_type.rb
@@ -3,7 +3,7 @@
module RuboCop
module Cop
module Graphql
- class IDType < RuboCop::Cop::Cop
+ class IDType < RuboCop::Cop::Base
MSG = 'Do not use GraphQL::Types::ID, use a specific GlobalIDType instead'
WHITELISTED_ARGUMENTS = %i[iid full_path project_path group_path target_project_path namespace_path].freeze
diff --git a/rubocop/cop/graphql/json_type.rb b/rubocop/cop/graphql/json_type.rb
index 8518a771cbd..2525dc427b8 100644
--- a/rubocop/cop/graphql/json_type.rb
+++ b/rubocop/cop/graphql/json_type.rb
@@ -18,7 +18,7 @@
module RuboCop
module Cop
module Graphql
- class JSONType < RuboCop::Cop::Cop
+ class JSONType < RuboCop::Cop::Base
MSG = 'Avoid using GraphQL::Types::JSON. See: ' \
'https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#json'
@@ -32,7 +32,7 @@ module RuboCop
PATTERN
def on_send(node)
- add_offense(node, location: :expression) if has_json_type?(node)
+ add_offense(node) if has_json_type?(node)
end
end
end
diff --git a/rubocop/cop/graphql/old_types.rb b/rubocop/cop/graphql/old_types.rb
index 61e8ac92dc7..9bbda4732dd 100644
--- a/rubocop/cop/graphql/old_types.rb
+++ b/rubocop/cop/graphql/old_types.rb
@@ -19,7 +19,7 @@
module RuboCop
module Cop
module Graphql
- class OldTypes < RuboCop::Cop::Cop
+ class OldTypes < RuboCop::Cop::Base
MSG_ID = 'Avoid using GraphQL::ID_TYPE. Use GraphQL::Types::ID instead'
MSG_INT = 'Avoid using GraphQL::INT_TYPE. Use GraphQL::Types::Int instead'
MSG_STRING = 'Avoid using GraphQL::STRING_TYPE. Use GraphQL::Types::String instead'
@@ -37,7 +37,7 @@ module RuboCop
old_constant = has_old_type?(node)
return unless old_constant
- add_offense(node, location: :expression, message: "#{self.class}::MSG_#{old_constant[0..-6]}".constantize)
+ add_offense(node, message: "#{self.class}::MSG_#{old_constant[0..-6]}".constantize)
end
end
end
diff --git a/rubocop/cop/graphql/resolver_type.rb b/rubocop/cop/graphql/resolver_type.rb
index e9fa768fd3e..34f1d43fc2a 100644
--- a/rubocop/cop/graphql/resolver_type.rb
+++ b/rubocop/cop/graphql/resolver_type.rb
@@ -23,7 +23,7 @@
module RuboCop
module Cop
module Graphql
- class ResolverType < RuboCop::Cop::Cop
+ class ResolverType < RuboCop::Cop::Base
MSG = 'Missing type annotation: Please add `type` DSL method call. ' \
'e.g: type UserType.connection_type, null: true'
@@ -32,7 +32,7 @@ module RuboCop
PATTERN
def on_class(node)
- add_offense(node, location: :expression) if resolver?(node) && !typed?(node)
+ add_offense(node) if resolver?(node) && !typed?(node)
end
private
diff --git a/rubocop/cop/group_public_or_visible_to_user.rb b/rubocop/cop/group_public_or_visible_to_user.rb
index beda0b7f8ba..d3aa230680b 100644
--- a/rubocop/cop/group_public_or_visible_to_user.rb
+++ b/rubocop/cop/group_public_or_visible_to_user.rb
@@ -3,7 +3,7 @@
module RuboCop
module Cop
# Cop that blacklists the usage of Group.public_or_visible_to_user
- class GroupPublicOrVisibleToUser < RuboCop::Cop::Cop
+ class GroupPublicOrVisibleToUser < RuboCop::Cop::Base
MSG = '`Group.public_or_visible_to_user` should be used with extreme care. ' \
'Please ensure that you are not using it on its own and that the amount ' \
'of rows being filtered is reasonable.'
@@ -15,7 +15,7 @@ module RuboCop
def on_send(node)
return unless public_or_visible_to_user?(node)
- add_offense(node, location: :expression)
+ add_offense(node)
end
end
end
diff --git a/rubocop/cop/ignored_columns.rb b/rubocop/cop/ignored_columns.rb
index 4a6f1e4f2d9..542d78c59e9 100644
--- a/rubocop/cop/ignored_columns.rb
+++ b/rubocop/cop/ignored_columns.rb
@@ -3,7 +3,7 @@
module RuboCop
module Cop
# Cop that blacklists the usage of `ActiveRecord::Base.ignored_columns=` directly
- class IgnoredColumns < RuboCop::Cop::Cop
+ class IgnoredColumns < RuboCop::Cop::Base
USE_CONCERN_MSG = 'Use `IgnoredColumns` concern instead of adding to `self.ignored_columns`.'
WRONG_MODEL_MSG = 'If the model exists in CE and EE, the column has to be ignored ' \
'in the CE model. If the model only exists in EE, then it has to be added there.'
@@ -22,11 +22,11 @@ module RuboCop
def on_send(node)
if ignored_columns?(node)
- add_offense(node, location: :expression, message: USE_CONCERN_MSG)
+ add_offense(node, message: USE_CONCERN_MSG)
end
if using_ignore?(node) && used_in_wrong_model?
- add_offense(node, location: :expression, message: WRONG_MODEL_MSG)
+ add_offense(node, message: WRONG_MODEL_MSG)
end
end
diff --git a/rubocop/cop/include_sidekiq_worker.rb b/rubocop/cop/include_sidekiq_worker.rb
index e39b8bf92c2..1a42de64aa9 100644
--- a/rubocop/cop/include_sidekiq_worker.rb
+++ b/rubocop/cop/include_sidekiq_worker.rb
@@ -3,7 +3,9 @@
module RuboCop
module Cop
# Cop that makes sure workers include `ApplicationWorker`, not `Sidekiq::Worker`.
- class IncludeSidekiqWorker < RuboCop::Cop::Cop
+ class IncludeSidekiqWorker < RuboCop::Cop::Base
+ extend RuboCop::Cop::AutoCorrector
+
MSG = 'Include `ApplicationWorker`, not `Sidekiq::Worker`.'
def_node_matcher :includes_sidekiq_worker?, <<~PATTERN
@@ -13,12 +15,8 @@ module RuboCop
def on_send(node)
return unless includes_sidekiq_worker?(node)
- add_offense(node.arguments.first, location: :expression)
- end
-
- def autocorrect(node)
- lambda do |corrector|
- corrector.replace(node.source_range, 'ApplicationWorker')
+ add_offense(node.arguments.first) do |corrector|
+ corrector.replace(node.arguments.first, 'ApplicationWorker')
end
end
end
diff --git a/rubocop/cop/inject_enterprise_edition_module.rb b/rubocop/cop/inject_enterprise_edition_module.rb
index 785f1494354..7e3c44cc5fd 100644
--- a/rubocop/cop/inject_enterprise_edition_module.rb
+++ b/rubocop/cop/inject_enterprise_edition_module.rb
@@ -4,7 +4,9 @@ module RuboCop
module Cop
# Cop that blacklists the injecting of extension specific modules before any lines which are not already injecting another module.
# It allows multiple module injections as long as they're all at the end.
- class InjectEnterpriseEditionModule < RuboCop::Cop::Cop
+ class InjectEnterpriseEditionModule < RuboCop::Cop::Base
+ extend RuboCop::Cop::AutoCorrector
+
INVALID_LINE = 'Injecting extension modules must be done on the last line of this file' \
', outside of any class or module definitions'
@@ -34,7 +36,7 @@ module RuboCop
return unless check_method?(node)
if DISALLOW_METHODS.include?(node.children[1])
- add_offense(node, message: DISALLOWED_METHOD)
+ add_offense(node, message: DISALLOWED_METHOD, &corrector(node))
else
verify_line_number(node)
verify_argument_type(node)
@@ -52,7 +54,7 @@ module RuboCop
if allowed_line
ignore_node(node)
elsif line < last_line
- add_offense(node, message: INVALID_LINE)
+ add_offense(node, message: INVALID_LINE, &corrector(node))
end
end
@@ -61,7 +63,7 @@ module RuboCop
return if argument.str_type?
- add_offense(argument, message: INVALID_ARGUMENT)
+ add_offense(argument, message: INVALID_ARGUMENT, &corrector(argument))
end
def check_method?(node)
@@ -74,10 +76,12 @@ module RuboCop
end
end
+ private
+
# Automatically correcting these offenses is not always possible, as
# sometimes code needs to be refactored to make this work. As such, we
# only allow developers to easily blacklist existing offenses.
- def autocorrect(node)
+ def corrector(node)
lambda do |corrector|
corrector.insert_after(
node.source_range,
diff --git a/rubocop/cop/lint/last_keyword_argument.rb b/rubocop/cop/lint/last_keyword_argument.rb
index 80f4660eeb8..3f5ad7e20d7 100644
--- a/rubocop/cop/lint/last_keyword_argument.rb
+++ b/rubocop/cop/lint/last_keyword_argument.rb
@@ -9,7 +9,9 @@ module RuboCop
# 1. Running specs with RECORD_DEPRECATIONS=1
# 1. Downloading the complete set of deprecations/ files from a CI
# pipeline (see https://gitlab.com/gitlab-org/gitlab/-/merge_requests/47720)
- class LastKeywordArgument < Cop
+ class LastKeywordArgument < RuboCop::Cop::Base
+ extend RuboCop::Cop::AutoCorrector
+
MSG = 'Using the last argument as keyword parameters is deprecated'
DEPRECATIONS_GLOB = File.expand_path('../../../deprecations/**/*.yml', __dir__)
@@ -26,11 +28,7 @@ module RuboCop
# parser thinks `a: :b, c: :d` is hash type, it's actually kwargs
return if arg.hash_type? && !arg.source.match(/\A{/)
- add_offense(arg)
- end
-
- def autocorrect(arg)
- lambda do |corrector|
+ add_offense(arg) do |corrector|
if arg.hash_type?
kwarg = arg.source.sub(/\A{\s*/, '').sub(/\s*}\z/, '')
corrector.replace(arg, kwarg)
diff --git a/rubocop/cop/migration/add_column_with_default.rb b/rubocop/cop/migration/add_column_with_default.rb
index afd7d93cd47..36603e09263 100644
--- a/rubocop/cop/migration/add_column_with_default.rb
+++ b/rubocop/cop/migration/add_column_with_default.rb
@@ -5,7 +5,7 @@ require_relative '../../migration_helpers'
module RuboCop
module Cop
module Migration
- class AddColumnWithDefault < RuboCop::Cop::Cop
+ class AddColumnWithDefault < RuboCop::Cop::Base
include MigrationHelpers
MSG = '`add_column_with_default` is deprecated, use `add_column` instead'
@@ -15,7 +15,7 @@ module RuboCop
name = node.children[1]
- add_offense(node, location: :selector) if name == :add_column_with_default
+ add_offense(node.loc.selector) if name == :add_column_with_default
end
end
end
diff --git a/rubocop/cop/migration/add_columns_to_wide_tables.rb b/rubocop/cop/migration/add_columns_to_wide_tables.rb
index 41056379515..98dd605faef 100644
--- a/rubocop/cop/migration/add_columns_to_wide_tables.rb
+++ b/rubocop/cop/migration/add_columns_to_wide_tables.rb
@@ -6,7 +6,7 @@ module RuboCop
module Cop
module Migration
# Cop that prevents adding columns to wide tables.
- class AddColumnsToWideTables < RuboCop::Cop::Cop
+ class AddColumnsToWideTables < RuboCop::Cop::Base
include MigrationHelpers
MSG = '`%s` is a wide table with several columns, adding more should be avoided unless absolutely necessary.' \
@@ -26,7 +26,7 @@ module RuboCop
return unless offense?(method_name, table_name)
- add_offense(node, location: :selector, message: format(MSG, table_name.value))
+ add_offense(node.loc.selector, message: format(MSG, table_name.value))
end
private
diff --git a/rubocop/cop/migration/add_concurrent_foreign_key.rb b/rubocop/cop/migration/add_concurrent_foreign_key.rb
index ebab6aa653e..f538207d336 100644
--- a/rubocop/cop/migration/add_concurrent_foreign_key.rb
+++ b/rubocop/cop/migration/add_concurrent_foreign_key.rb
@@ -7,7 +7,7 @@ module RuboCop
module Migration
# Cop that checks if `add_concurrent_foreign_key` is used instead of
# `add_foreign_key`.
- class AddConcurrentForeignKey < RuboCop::Cop::Cop
+ class AddConcurrentForeignKey < RuboCop::Cop::Base
include MigrationHelpers
MSG = '`add_foreign_key` requires downtime, use `add_concurrent_foreign_key` instead'
@@ -29,7 +29,7 @@ module RuboCop
return if in_with_lock_retries?(node)
return if not_valid_fk?(node)
- add_offense(node, location: :selector)
+ add_offense(node.loc.selector)
end
def method_name(node)
diff --git a/rubocop/cop/migration/add_concurrent_index.rb b/rubocop/cop/migration/add_concurrent_index.rb
index bfe7c15bfdf..77b8ced4778 100644
--- a/rubocop/cop/migration/add_concurrent_index.rb
+++ b/rubocop/cop/migration/add_concurrent_index.rb
@@ -7,7 +7,7 @@ module RuboCop
module Migration
# Cop that checks if `add_concurrent_index` is used with `up`/`down` methods
# and not `change`.
- class AddConcurrentIndex < RuboCop::Cop::Cop
+ class AddConcurrentIndex < RuboCop::Cop::Base
include MigrationHelpers
MSG = '`add_concurrent_index` is not reversible so you must manually define ' \
@@ -21,15 +21,11 @@ module RuboCop
return unless name == :add_concurrent_index
node.each_ancestor(:def) do |def_node|
- next unless method_name(def_node) == :change
+ next unless def_node.method_name == :change
- add_offense(def_node, location: :name)
+ add_offense(def_node.loc.name)
end
end
-
- def method_name(node)
- node.children.first
- end
end
end
end
diff --git a/rubocop/cop/migration/add_index.rb b/rubocop/cop/migration/add_index.rb
index 327e89fb040..3920fd19c98 100644
--- a/rubocop/cop/migration/add_index.rb
+++ b/rubocop/cop/migration/add_index.rb
@@ -6,7 +6,7 @@ module RuboCop
module Cop
module Migration
# Cop that checks if indexes are added in a concurrent manner.
- class AddIndex < RuboCop::Cop::Cop
+ class AddIndex < RuboCop::Cop::Base
include MigrationHelpers
MSG = '`add_index` requires downtime, use `add_concurrent_index` instead'
@@ -29,7 +29,7 @@ module RuboCop
# data in these tables yet.
next if new_tables.include?(first_arg)
- add_offense(send_node, location: :selector)
+ add_offense(send_node.loc.selector)
end
end
diff --git a/rubocop/cop/migration/add_limit_to_text_columns.rb b/rubocop/cop/migration/add_limit_to_text_columns.rb
index a47fbe0bf16..5c71fbbfaa2 100644
--- a/rubocop/cop/migration/add_limit_to_text_columns.rb
+++ b/rubocop/cop/migration/add_limit_to_text_columns.rb
@@ -10,7 +10,7 @@ module RuboCop
# Text columns starting with `encrypted_` are very likely used
# by `attr_encrypted` which controls the text length. Those columns
# should not add a text limit.
- class AddLimitToTextColumns < RuboCop::Cop::Cop
+ class AddLimitToTextColumns < RuboCop::Cop::Base
include MigrationHelpers
TEXT_LIMIT_ATTRIBUTE_ALLOWED_SINCE = 2021_09_10_00_00_00
@@ -43,11 +43,11 @@ module RuboCop
next unless text_operation?(send_node)
if text_operation_with_limit?(send_node)
- add_offense(send_node, location: :selector, message: TEXT_LIMIT_ATTRIBUTE_NOT_ALLOWED) if version(node) < TEXT_LIMIT_ATTRIBUTE_ALLOWED_SINCE
+ add_offense(send_node.loc.selector, message: TEXT_LIMIT_ATTRIBUTE_NOT_ALLOWED) if version(node) < TEXT_LIMIT_ATTRIBUTE_ALLOWED_SINCE
else
# We require a limit for the same table and attribute name
if text_limit_missing?(node, *table_and_attribute_name(send_node))
- add_offense(send_node, location: :selector)
+ add_offense(send_node.loc.selector)
end
end
end
diff --git a/rubocop/cop/migration/add_reference.rb b/rubocop/cop/migration/add_reference.rb
index 33840fc7caf..02a0ef899b4 100644
--- a/rubocop/cop/migration/add_reference.rb
+++ b/rubocop/cop/migration/add_reference.rb
@@ -6,7 +6,7 @@ module RuboCop
module Migration
# add_reference can only be used with newly created tables.
# Additionally, the cop here checks that we create an index for the foreign key, too.
- class AddReference < RuboCop::Cop::Cop
+ class AddReference < RuboCop::Cop::Base
include MigrationHelpers
MSG = '`add_reference` requires downtime for existing tables, use `add_concurrent_foreign_key` instead. When used for new tables, `index: true` or `index: { options... } is required.`'
@@ -28,12 +28,12 @@ module RuboCop
# Using "add_reference" is fine for newly created tables as there's no
# data in these tables yet.
if existing_table?(new_tables, first_arg)
- add_offense(send_node, location: :selector)
+ add_offense(send_node.loc.selector)
end
# We require an index on the foreign key column.
if index_missing?(node)
- add_offense(send_node, location: :selector)
+ add_offense(send_node.loc.selector)
end
end
end
diff --git a/rubocop/cop/migration/add_timestamps.rb b/rubocop/cop/migration/add_timestamps.rb
index 01d3f01ef4f..8b09d730cbc 100644
--- a/rubocop/cop/migration/add_timestamps.rb
+++ b/rubocop/cop/migration/add_timestamps.rb
@@ -6,7 +6,7 @@ module RuboCop
module Cop
module Migration
# Cop that checks if 'add_timestamps' method is called with timezone information.
- class AddTimestamps < RuboCop::Cop::Cop
+ class AddTimestamps < RuboCop::Cop::Base
include MigrationHelpers
MSG = 'Do not use `add_timestamps`, use `add_timestamps_with_timezone` instead'
@@ -15,7 +15,7 @@ module RuboCop
def on_send(node)
return unless in_migration?(node)
- add_offense(node, location: :selector) if method_name(node) == :add_timestamps
+ add_offense(node.loc.selector) if method_name(node) == :add_timestamps
end
def method_name(node)
diff --git a/rubocop/cop/migration/background_migration_base_class.rb b/rubocop/cop/migration/background_migration_base_class.rb
index 50cbe3a69c3..9ec8403a607 100644
--- a/rubocop/cop/migration/background_migration_base_class.rb
+++ b/rubocop/cop/migration/background_migration_base_class.rb
@@ -3,7 +3,7 @@
module RuboCop
module Cop
module Migration
- class BackgroundMigrationBaseClass < RuboCop::Cop::Cop
+ class BackgroundMigrationBaseClass < RuboCop::Cop::Base
MSG = 'Batched background migration jobs should inherit from Gitlab::BackgroundMigration::BatchedMigrationJob'
def_node_search :top_level_module?, <<~PATTERN
@@ -25,7 +25,7 @@ module RuboCop
return if top_level_class_node.nil? || inherits_batched_migration_job?(top_level_class_node)
- add_offense(top_level_class_node, location: :expression)
+ add_offense(top_level_class_node)
end
end
end
diff --git a/rubocop/cop/migration/background_migration_record.rb b/rubocop/cop/migration/background_migration_record.rb
index 2ee6b9f7b42..ee6f3fd140b 100644
--- a/rubocop/cop/migration/background_migration_record.rb
+++ b/rubocop/cop/migration/background_migration_record.rb
@@ -5,7 +5,7 @@ require_relative '../../migration_helpers'
module RuboCop
module Cop
module Migration
- class BackgroundMigrationRecord < RuboCop::Cop::Cop
+ class BackgroundMigrationRecord < RuboCop::Cop::Base
include MigrationHelpers
MSG = <<~MSG
@@ -26,14 +26,14 @@ module RuboCop
return unless in_background_migration?(node)
return unless inherits_from_active_record_base?(node)
- add_offense(node, location: :expression)
+ add_offense(node)
end
def on_send(node)
return unless in_background_migration?(node)
return unless class_new_active_record_base?(node)
- add_offense(node, location: :expression)
+ add_offense(node)
end
end
end
diff --git a/rubocop/cop/migration/background_migrations.rb b/rubocop/cop/migration/background_migrations.rb
index 39c5496e4d3..7dcc2101fb1 100644
--- a/rubocop/cop/migration/background_migrations.rb
+++ b/rubocop/cop/migration/background_migrations.rb
@@ -5,7 +5,7 @@ require_relative '../../migration_helpers'
module RuboCop
module Cop
module Migration
- class BackgroundMigrations < RuboCop::Cop::Cop
+ class BackgroundMigrations < RuboCop::Cop::Base
include MigrationHelpers
MSG = 'Background migrations are deprecated. Please use a Batched Background Migration instead.'\
@@ -20,7 +20,7 @@ module RuboCop
migrate_in
)
- add_offense(node, location: :selector) if disabled_methods.include? name
+ add_offense(node.loc.selector) if disabled_methods.include? name
end
end
end
diff --git a/rubocop/cop/migration/complex_indexes_require_name.rb b/rubocop/cop/migration/complex_indexes_require_name.rb
index 82deb36716d..771537f2576 100644
--- a/rubocop/cop/migration/complex_indexes_require_name.rb
+++ b/rubocop/cop/migration/complex_indexes_require_name.rb
@@ -5,7 +5,7 @@ require_relative '../../migration_helpers'
module RuboCop
module Cop
module Migration
- class ComplexIndexesRequireName < RuboCop::Cop::Cop
+ class ComplexIndexesRequireName < RuboCop::Cop::Base
include MigrationHelpers
MSG = 'indexes added with custom options must be explicitly named'
@@ -32,7 +32,7 @@ module RuboCop
node.each_descendant(:send) do |send_node|
next unless create_table_with_index_offense?(send_node) || add_index_offense?(send_node)
- add_offense(send_node, location: :selector)
+ add_offense(send_node.loc.selector)
end
end
diff --git a/rubocop/cop/migration/create_table_with_foreign_keys.rb b/rubocop/cop/migration/create_table_with_foreign_keys.rb
index 382a2d6f65b..e3039ac76a9 100644
--- a/rubocop/cop/migration/create_table_with_foreign_keys.rb
+++ b/rubocop/cop/migration/create_table_with_foreign_keys.rb
@@ -5,7 +5,7 @@ require_relative '../../migration_helpers'
module RuboCop
module Cop
module Migration
- class CreateTableWithForeignKeys < RuboCop::Cop::Cop
+ class CreateTableWithForeignKeys < RuboCop::Cop::Base
include MigrationHelpers
MSG = 'Creating a table with more than one foreign key at once violates our migration style guide. ' \
diff --git a/rubocop/cop/migration/datetime.rb b/rubocop/cop/migration/datetime.rb
index c605c8e1b6e..9cdb2d83ab5 100644
--- a/rubocop/cop/migration/datetime.rb
+++ b/rubocop/cop/migration/datetime.rb
@@ -6,7 +6,7 @@ module RuboCop
module Cop
module Migration
# Cop that checks if datetime data type is added with timezone information.
- class Datetime < RuboCop::Cop::Cop
+ class Datetime < RuboCop::Cop::Base
include MigrationHelpers
MSG = 'Do not use the `%s` data type, use `datetime_with_timezone` instead'
@@ -19,7 +19,7 @@ module RuboCop
method_name = send_node.children[1]
if method_name == :datetime || method_name == :timestamp
- add_offense(send_node, location: :selector, message: format(MSG, method_name))
+ add_offense(send_node.loc.selector, message: format(MSG, method_name))
end
end
end
@@ -34,7 +34,7 @@ module RuboCop
last_argument = descendant.children.last
if last_argument == :datetime || last_argument == :timestamp
- add_offense(node, location: :expression, message: format(MSG, last_argument))
+ add_offense(node, message: format(MSG, last_argument))
end
end
end
diff --git a/rubocop/cop/migration/drop_table.rb b/rubocop/cop/migration/drop_table.rb
index 531cbb14021..62dea79cbe6 100644
--- a/rubocop/cop/migration/drop_table.rb
+++ b/rubocop/cop/migration/drop_table.rb
@@ -7,7 +7,7 @@ module RuboCop
module Migration
# Cop that checks if `drop_table` is called in deployment migrations.
# Calling it in deployment migrations can cause downtimes as there still may be code using the target tables.
- class DropTable < RuboCop::Cop::Cop
+ class DropTable < RuboCop::Cop::Base
include MigrationHelpers
MSG = <<-MESSAGE.delete("\n").squeeze
@@ -22,7 +22,7 @@ module RuboCop
node.each_descendant(:send) do |send_node|
next unless offensible?(send_node)
- add_offense(send_node, location: :selector)
+ add_offense(send_node.loc.selector)
end
end
diff --git a/rubocop/cop/migration/migration_record.rb b/rubocop/cop/migration/migration_record.rb
index 291644f10e3..1543d2fff08 100644
--- a/rubocop/cop/migration/migration_record.rb
+++ b/rubocop/cop/migration/migration_record.rb
@@ -5,7 +5,7 @@ require_relative '../../migration_helpers'
module RuboCop
module Cop
module Migration
- class MigrationRecord < RuboCop::Cop::Cop
+ class MigrationRecord < RuboCop::Cop::Base
include MigrationHelpers
ENFORCED_SINCE = 2022_04_26_00_00_00
@@ -27,7 +27,7 @@ module RuboCop
return unless relevant_migration?(node)
return unless inherits_from_active_record_base?(node) || inherits_from_application_record?(node)
- add_offense(node, location: :expression)
+ add_offense(node)
end
private
diff --git a/rubocop/cop/migration/prevent_global_enable_lock_retries_with_disable_ddl_transaction.rb b/rubocop/cop/migration/prevent_global_enable_lock_retries_with_disable_ddl_transaction.rb
index f5343f973e1..9556a16dc01 100644
--- a/rubocop/cop/migration/prevent_global_enable_lock_retries_with_disable_ddl_transaction.rb
+++ b/rubocop/cop/migration/prevent_global_enable_lock_retries_with_disable_ddl_transaction.rb
@@ -6,7 +6,7 @@ module RuboCop
module Cop
module Migration
# Cop that prevents usage of `enable_lock_retries!` within the `disable_ddl_transaction!` method.
- class PreventGlobalEnableLockRetriesWithDisableDdlTransaction < RuboCop::Cop::Cop
+ class PreventGlobalEnableLockRetriesWithDisableDdlTransaction < RuboCop::Cop::Base
include MigrationHelpers
MSG = '`enable_lock_retries!` cannot be used with `disable_ddl_transaction!`. Use the `with_lock_retries` helper method to define retriable code blocks.'
diff --git a/rubocop/cop/migration/prevent_index_creation.rb b/rubocop/cop/migration/prevent_index_creation.rb
index c383466f73b..185f36cb24b 100644
--- a/rubocop/cop/migration/prevent_index_creation.rb
+++ b/rubocop/cop/migration/prevent_index_creation.rb
@@ -5,7 +5,7 @@ module RuboCop
module Cop
module Migration
# Cop that checks if new indexes are introduced to forbidden tables.
- class PreventIndexCreation < RuboCop::Cop::Cop
+ class PreventIndexCreation < RuboCop::Cop::Base
include MigrationHelpers
FORBIDDEN_TABLES = %i[ci_builds].freeze
@@ -41,7 +41,7 @@ module RuboCop
return unless in_migration?(node)
node.each_descendant(:send) do |send_node|
- add_offense(send_node, location: :selector) if offense?(send_node)
+ add_offense(send_node.loc.selector) if offense?(send_node)
end
end
diff --git a/rubocop/cop/migration/prevent_strings.rb b/rubocop/cop/migration/prevent_strings.rb
index 57e29bf74ae..89659050f64 100644
--- a/rubocop/cop/migration/prevent_strings.rb
+++ b/rubocop/cop/migration/prevent_strings.rb
@@ -6,7 +6,7 @@ module RuboCop
module Cop
module Migration
# Cop that enforces using text instead of the string data type
- class PreventStrings < RuboCop::Cop::Cop
+ class PreventStrings < RuboCop::Cop::Base
include MigrationHelpers
MSG = 'Do not use the `string` data type, use `text` instead. ' \
@@ -26,7 +26,7 @@ module RuboCop
node.each_descendant(:send) do |send_node|
next unless string_operation?(send_node)
- add_offense(send_node, location: :selector)
+ add_offense(send_node.loc.selector)
end
end
diff --git a/rubocop/cop/migration/refer_to_index_by_name.rb b/rubocop/cop/migration/refer_to_index_by_name.rb
index fbf3c0d7030..78619472487 100644
--- a/rubocop/cop/migration/refer_to_index_by_name.rb
+++ b/rubocop/cop/migration/refer_to_index_by_name.rb
@@ -5,7 +5,7 @@ require_relative '../../migration_helpers'
module RuboCop
module Cop
module Migration
- class ReferToIndexByName < RuboCop::Cop::Cop
+ class ReferToIndexByName < RuboCop::Cop::Base
include MigrationHelpers
MSG = 'migration methods that refer to existing indexes must do so by name'
@@ -32,7 +32,7 @@ module RuboCop
node.each_descendant(:send) do |send_node|
next unless index_exists_offense?(send_node) || removing_index_offense?(send_node)
- add_offense(send_node, location: :selector)
+ add_offense(send_node.loc.selector)
end
end
diff --git a/rubocop/cop/migration/remove_column.rb b/rubocop/cop/migration/remove_column.rb
index 6a171ac948f..e8477a211e4 100644
--- a/rubocop/cop/migration/remove_column.rb
+++ b/rubocop/cop/migration/remove_column.rb
@@ -7,7 +7,7 @@ module RuboCop
module Migration
# Cop that checks if remove_column is used in a regular (not
# post-deployment) migration.
- class RemoveColumn < RuboCop::Cop::Cop
+ class RemoveColumn < RuboCop::Cop::Base
include MigrationHelpers
MSG = '`remove_column` must only be used in post-deployment migrations'
@@ -22,7 +22,7 @@ module RuboCop
send_method = send_node.children[1]
if send_method == :remove_column
- add_offense(send_node, location: :selector)
+ add_offense(send_node.loc.selector)
end
end
end
diff --git a/rubocop/cop/migration/remove_concurrent_index.rb b/rubocop/cop/migration/remove_concurrent_index.rb
index 30dd59d97bc..459f474d185 100644
--- a/rubocop/cop/migration/remove_concurrent_index.rb
+++ b/rubocop/cop/migration/remove_concurrent_index.rb
@@ -7,7 +7,7 @@ module RuboCop
module Migration
# Cop that checks if `remove_concurrent_index` is used with `up`/`down` methods
# and not `change`.
- class RemoveConcurrentIndex < RuboCop::Cop::Cop
+ class RemoveConcurrentIndex < RuboCop::Cop::Base
include MigrationHelpers
MSG = '`remove_concurrent_index` is not reversible so you must manually define ' \
@@ -18,13 +18,9 @@ module RuboCop
return unless node.children[1] == :remove_concurrent_index
node.each_ancestor(:def) do |def_node|
- add_offense(def_node, location: :name) if method_name(def_node) == :change
+ add_offense(def_node.loc.name) if def_node.method_name == :change
end
end
-
- def method_name(node)
- node.children[0]
- end
end
end
end
diff --git a/rubocop/cop/migration/remove_index.rb b/rubocop/cop/migration/remove_index.rb
index ca5d4af1520..26d271207dc 100644
--- a/rubocop/cop/migration/remove_index.rb
+++ b/rubocop/cop/migration/remove_index.rb
@@ -6,7 +6,7 @@ module RuboCop
module Cop
module Migration
# Cop that checks if indexes are removed in a concurrent manner.
- class RemoveIndex < RuboCop::Cop::Cop
+ class RemoveIndex < RuboCop::Cop::Base
include MigrationHelpers
MSG = '`remove_index` requires downtime, use `remove_concurrent_index` instead'
@@ -15,7 +15,7 @@ module RuboCop
return unless in_migration?(node)
node.each_descendant(:send) do |send_node|
- add_offense(send_node, location: :selector) if method_name(send_node) == :remove_index
+ add_offense(send_node.loc.selector) if method_name(send_node) == :remove_index
end
end
diff --git a/rubocop/cop/migration/safer_boolean_column.rb b/rubocop/cop/migration/safer_boolean_column.rb
index 1d780d96afa..d3d77b16357 100644
--- a/rubocop/cop/migration/safer_boolean_column.rb
+++ b/rubocop/cop/migration/safer_boolean_column.rb
@@ -18,7 +18,7 @@ module RuboCop
#
# See https://gitlab.com/gitlab-org/gitlab/issues/2750 for more
# information.
- class SaferBooleanColumn < RuboCop::Cop::Cop
+ class SaferBooleanColumn < RuboCop::Cop::Base
include MigrationHelpers
DEFAULT_OFFENSE = 'Boolean columns on the `%s` table should have a default. You may wish to use `add_column_with_default`.'
@@ -52,7 +52,7 @@ module RuboCop
NULL_OFFENSE
end
- add_offense(node, location: :expression, message: format(offense, table)) if offense
+ add_offense(node, message: format(offense, table)) if offense
end
def no_default?(opts)
diff --git a/rubocop/cop/migration/schedule_async.rb b/rubocop/cop/migration/schedule_async.rb
index 4fdedecdf64..bc98d45b9c6 100644
--- a/rubocop/cop/migration/schedule_async.rb
+++ b/rubocop/cop/migration/schedule_async.rb
@@ -5,7 +5,7 @@ require_relative '../../migration_helpers'
module RuboCop
module Cop
module Migration
- class ScheduleAsync < RuboCop::Cop::Cop
+ class ScheduleAsync < RuboCop::Cop::Base
include MigrationHelpers
ENFORCED_SINCE = 2020_02_12_00_00_00
@@ -32,7 +32,7 @@ module RuboCop
return if version(node) < ENFORCED_SINCE
return unless calls_background_migration_worker?(node) || calls_ci_database_worker?(node)
- add_offense(node, location: :expression)
+ add_offense(node)
end
end
end
diff --git a/rubocop/cop/migration/sidekiq_queue_migrate.rb b/rubocop/cop/migration/sidekiq_queue_migrate.rb
index 134bda590da..4a7aaa353a3 100644
--- a/rubocop/cop/migration/sidekiq_queue_migrate.rb
+++ b/rubocop/cop/migration/sidekiq_queue_migrate.rb
@@ -7,7 +7,7 @@ module RuboCop
module Migration
# Cop that checks if sidekiq_queue_migrate is used in a regular
# (not post-deployment) migration.
- class SidekiqQueueMigrate < RuboCop::Cop::Cop
+ class SidekiqQueueMigrate < RuboCop::Cop::Base
include MigrationHelpers
MSG = '`sidekiq_queue_migrate` must only be used in post-deployment migrations'
@@ -19,7 +19,7 @@ module RuboCop
send_method = send_node.children[1]
if send_method == :sidekiq_queue_migrate
- add_offense(send_node, location: :selector)
+ add_offense(send_node.loc.selector)
end
end
end
diff --git a/rubocop/cop/migration/timestamps.rb b/rubocop/cop/migration/timestamps.rb
index 44baf17d968..5cc78a8821a 100644
--- a/rubocop/cop/migration/timestamps.rb
+++ b/rubocop/cop/migration/timestamps.rb
@@ -6,7 +6,7 @@ module RuboCop
module Cop
module Migration
# Cop that checks if 'timestamps' method is called with timezone information.
- class Timestamps < RuboCop::Cop::Cop
+ class Timestamps < RuboCop::Cop::Base
include MigrationHelpers
MSG = 'Do not use `timestamps`, use `timestamps_with_timezone` instead'
@@ -16,7 +16,7 @@ module RuboCop
return unless in_migration?(node)
node.each_descendant(:send) do |send_node|
- add_offense(send_node, location: :selector) if method_name(send_node) == :timestamps
+ add_offense(send_node.loc.selector) if method_name(send_node) == :timestamps
end
end
diff --git a/rubocop/cop/migration/update_column_in_batches.rb b/rubocop/cop/migration/update_column_in_batches.rb
index e23042e1b9f..7f4479c62e3 100644
--- a/rubocop/cop/migration/update_column_in_batches.rb
+++ b/rubocop/cop/migration/update_column_in_batches.rb
@@ -7,7 +7,7 @@ module RuboCop
module Migration
# Cop that checks if a spec file exists for any migration using
# `update_column_in_batches`.
- class UpdateColumnInBatches < RuboCop::Cop::Cop
+ class UpdateColumnInBatches < RuboCop::Cop::Base
include MigrationHelpers
MSG = 'Migration running `update_column_in_batches` must have a spec file at' \
@@ -19,9 +19,9 @@ module RuboCop
spec_path = spec_filename(node)
- unless File.exist?(File.expand_path(spec_path, rails_root))
- add_offense(node, location: :expression, message: format(MSG, spec_path))
- end
+ return if File.exist?(File.expand_path(spec_path, rails_root))
+
+ add_offense(node, message: format(MSG, spec_path))
end
private
diff --git a/rubocop/cop/migration/versioned_migration_class.rb b/rubocop/cop/migration/versioned_migration_class.rb
index f2e4550c691..648782f1735 100644
--- a/rubocop/cop/migration/versioned_migration_class.rb
+++ b/rubocop/cop/migration/versioned_migration_class.rb
@@ -5,7 +5,7 @@ require_relative '../../migration_helpers'
module RuboCop
module Cop
module Migration
- class VersionedMigrationClass < RuboCop::Cop::Cop
+ class VersionedMigrationClass < RuboCop::Cop::Base
include MigrationHelpers
ENFORCED_SINCE = 2021_09_02_00_00_00
@@ -26,13 +26,13 @@ module RuboCop
return unless relevant_migration?(node)
return unless activerecord_migration_class?(node)
- add_offense(node, location: :expression, message: MSG_INHERIT)
+ add_offense(node, message: MSG_INHERIT)
end
def on_send(node)
return unless relevant_migration?(node)
- add_offense(node, location: :expression, message: MSG_INCLUDE) if includes_helpers?(node)
+ add_offense(node, message: MSG_INCLUDE) if includes_helpers?(node)
end
private
diff --git a/rubocop/cop/migration/with_lock_retries_disallowed_method.rb b/rubocop/cop/migration/with_lock_retries_disallowed_method.rb
index b3d05ad1a6d..5c96b38dcdc 100644
--- a/rubocop/cop/migration/with_lock_retries_disallowed_method.rb
+++ b/rubocop/cop/migration/with_lock_retries_disallowed_method.rb
@@ -5,7 +5,7 @@ require_relative '../../migration_helpers'
module RuboCop
module Cop
module Migration
- class WithLockRetriesDisallowedMethod < RuboCop::Cop::Cop
+ class WithLockRetriesDisallowedMethod < RuboCop::Cop::Base
include MigrationHelpers
ALLOWED_MIGRATION_METHODS = %i[
@@ -60,8 +60,8 @@ module RuboCop
return unless send_node?(node)
name = node.children[1]
- add_offense(node, location: :expression) unless ALLOWED_MIGRATION_METHODS.include?(name)
- add_offense(node, location: :selector, message: MSG_ONLY_ONE_FK_ALLOWED) if multiple_fks?(node)
+ add_offense(node) unless ALLOWED_MIGRATION_METHODS.include?(name)
+ add_offense(node.loc.selector, message: MSG_ONLY_ONE_FK_ALLOWED) if multiple_fks?(node)
end
def multiple_fks?(node)
diff --git a/rubocop/cop/migration/with_lock_retries_with_change.rb b/rubocop/cop/migration/with_lock_retries_with_change.rb
index 9d11edcb6a1..59dbd6f22d2 100644
--- a/rubocop/cop/migration/with_lock_retries_with_change.rb
+++ b/rubocop/cop/migration/with_lock_retries_with_change.rb
@@ -6,7 +6,7 @@ module RuboCop
module Cop
module Migration
# Cop that prevents usage of `with_lock_retries` within the `change` method.
- class WithLockRetriesWithChange < RuboCop::Cop::Cop
+ class WithLockRetriesWithChange < RuboCop::Cop::Base
include MigrationHelpers
MSG = '`with_lock_retries` cannot be used within `change` so you must manually define ' \
@@ -17,13 +17,9 @@ module RuboCop
return unless node.children[1] == :with_lock_retries
node.each_ancestor(:def) do |def_node|
- add_offense(def_node, location: :name) if method_name(def_node) == :change
+ add_offense(def_node.loc.name) if def_node.method_name == :change
end
end
-
- def method_name(node)
- node.children.first
- end
end
end
end
diff --git a/rubocop/cop/performance/active_record_subtransaction_methods.rb b/rubocop/cop/performance/active_record_subtransaction_methods.rb
index 3b89d3ab858..1789e20ce45 100644
--- a/rubocop/cop/performance/active_record_subtransaction_methods.rb
+++ b/rubocop/cop/performance/active_record_subtransaction_methods.rb
@@ -5,7 +5,7 @@ module RuboCop
module Performance
# Cop that disallows certain methods that rely on subtransactions in their implementation.
# Companion to Performance/ActiveRecordSubtransactions, which bans direct usage of subtransactions.
- class ActiveRecordSubtransactionMethods < RuboCop::Cop::Cop
+ class ActiveRecordSubtransactionMethods < RuboCop::Cop::Base
MSG = 'Methods that rely on subtransactions should not be used. ' \
'For more information see: https://gitlab.com/gitlab-org/gitlab/-/issues/338346'
@@ -21,7 +21,7 @@ module RuboCop
def on_send(node)
return unless DISALLOWED_METHODS.include?(node.method_name)
- add_offense(node, location: :selector)
+ add_offense(node.loc.selector)
end
end
end
diff --git a/rubocop/cop/performance/active_record_subtransactions.rb b/rubocop/cop/performance/active_record_subtransactions.rb
index a550b558e52..165efee7c6b 100644
--- a/rubocop/cop/performance/active_record_subtransactions.rb
+++ b/rubocop/cop/performance/active_record_subtransactions.rb
@@ -3,7 +3,7 @@
module RuboCop
module Cop
module Performance
- class ActiveRecordSubtransactions < RuboCop::Cop::Cop
+ class ActiveRecordSubtransactions < RuboCop::Cop::Base
MSG = 'Subtransactions should not be used. ' \
'For more information see: https://gitlab.com/gitlab-org/gitlab/-/issues/338346'
diff --git a/rubocop/cop/performance/ar_count_each.rb b/rubocop/cop/performance/ar_count_each.rb
index 2fe8e549872..1dae473d87d 100644
--- a/rubocop/cop/performance/ar_count_each.rb
+++ b/rubocop/cop/performance/ar_count_each.rb
@@ -3,7 +3,7 @@
module RuboCop
module Cop
module Performance
- class ARCountEach < RuboCop::Cop::Cop
+ class ARCountEach < RuboCop::Cop::Base
def message(ivar)
"If #{ivar} is AR relation, avoid `#{ivar}.count ...; #{ivar}.each... `, this will trigger two queries. " \
"Use `#{ivar}.load.size ...; #{ivar}.each... ` instead. If #{ivar} is an array, try to use #{ivar}.size."
@@ -35,7 +35,7 @@ module RuboCop
begin_node.each_descendant do |n|
ivar_each = each_match(n)
- add_offense(node, location: :expression, message: message(ivar_count)) if ivar_each == ivar_count
+ add_offense(node, message: message(ivar_count)) if ivar_each == ivar_count
end
end
end
diff --git a/rubocop/cop/performance/ar_exists_and_present_blank.rb b/rubocop/cop/performance/ar_exists_and_present_blank.rb
index 54c2d6bf95a..c2ba6c2a206 100644
--- a/rubocop/cop/performance/ar_exists_and_present_blank.rb
+++ b/rubocop/cop/performance/ar_exists_and_present_blank.rb
@@ -3,7 +3,7 @@
module RuboCop
module Cop
module Performance
- class ARExistsAndPresentBlank < RuboCop::Cop::Cop
+ class ARExistsAndPresentBlank < RuboCop::Cop::Base
def message_present(ivar)
"Avoid `#{ivar}.present?`, because it will generate database query 'Select TABLE.*' which is expensive. "\
"Suggest to use `#{ivar}.any?` to replace `#{ivar}.present?`"
@@ -46,8 +46,8 @@ module RuboCop
ivar_exists = exists_match(n)
next unless ivar_exists
- add_offense(node, location: :expression, message: message_present(ivar_exists)) if ivar_exists == ivar_present
- add_offense(node, location: :expression, message: message_blank(ivar_exists)) if ivar_exists == ivar_blank
+ add_offense(node, message: message_present(ivar_exists)) if ivar_exists == ivar_present
+ add_offense(node, message: message_blank(ivar_exists)) if ivar_exists == ivar_blank
end
end
end
diff --git a/rubocop/cop/performance/readlines_each.rb b/rubocop/cop/performance/readlines_each.rb
index cb4ffaca6e9..7a3a15020db 100644
--- a/rubocop/cop/performance/readlines_each.rb
+++ b/rubocop/cop/performance/readlines_each.rb
@@ -3,7 +3,9 @@
module RuboCop
module Cop
module Performance
- class ReadlinesEach < RuboCop::Cop::Cop
+ class ReadlinesEach < RuboCop::Cop::Base
+ extend RuboCop::Cop::AutoCorrector
+
MESSAGE = 'Avoid `IO.readlines.each`, since it reads contents into memory in full. ' \
'Use `IO.each_line` or `IO.each` instead.'
@@ -17,12 +19,9 @@ module RuboCop
PATTERN
def on_send(node)
- full_file_read_via_class?(node) { add_offense(node, location: :selector, message: MESSAGE) }
- full_file_read_via_instance?(node) { add_offense(node, location: :selector, message: MESSAGE) }
- end
+ return unless full_file_read_via_class?(node) || full_file_read_via_instance?(node)
- def autocorrect(node)
- lambda do |corrector|
+ add_offense(node.loc.selector, message: MESSAGE) do |corrector|
corrector.replace(node.loc.expression, node.source.gsub('readlines.each', 'each_line'))
end
end
diff --git a/rubocop/cop/prefer_class_methods_over_module.rb b/rubocop/cop/prefer_class_methods_over_module.rb
index 39b65073477..d865cc6c003 100644
--- a/rubocop/cop/prefer_class_methods_over_module.rb
+++ b/rubocop/cop/prefer_class_methods_over_module.rb
@@ -26,7 +26,8 @@ module RuboCop
# end
# end
#
- class PreferClassMethodsOverModule < RuboCop::Cop::Cop
+ class PreferClassMethodsOverModule < RuboCop::Cop::Base
+ extend RuboCop::Cop::AutoCorrector
include RangeHelp
MSG = 'Do not use module ClassMethods, use class_methods block instead.'
@@ -36,17 +37,20 @@ module RuboCop
PATTERN
def on_module(node)
- add_offense(node) if node.defined_module_name == 'ClassMethods' && module_extends_activesupport_concern?(node)
- end
+ return unless class_methods_module_in_activesupport_concern?(node)
- def autocorrect(node)
- lambda do |corrector|
+ add_offense(node) do |corrector|
corrector.replace(module_range(node), 'class_methods do')
end
end
private
+ def class_methods_module_in_activesupport_concern?(node)
+ node.defined_module_name == 'ClassMethods' &&
+ module_extends_activesupport_concern?(node)
+ end
+
def module_extends_activesupport_concern?(node)
container_module = container_module_of(node)
return false unless container_module
diff --git a/rubocop/cop/project_path_helper.rb b/rubocop/cop/project_path_helper.rb
index 0d12f2d2b12..104a352949f 100644
--- a/rubocop/cop/project_path_helper.rb
+++ b/rubocop/cop/project_path_helper.rb
@@ -2,7 +2,9 @@
module RuboCop
module Cop
- class ProjectPathHelper < RuboCop::Cop::Cop
+ class ProjectPathHelper < RuboCop::Cop::Base
+ extend RuboCop::Cop::AutoCorrector
+
MSG = 'Use short project path helpers without explicitly passing the namespace: ' \
'`foo_project_bar_path(project, bar)` instead of ' \
'`foo_namespace_project_bar_path(project.namespace, project, bar)`.'
@@ -19,18 +21,14 @@ module RuboCop
return unless method_name(namespace_expr) == :namespace
return unless receiver(namespace_expr) == project_expr
- add_offense(node, location: :selector)
- end
-
- def autocorrect(node)
- helper_name = method_name(node).to_s.sub('namespace_project', 'project')
+ add_offense(node.loc.selector) do |corrector|
+ helper_name = method_name(node).to_s.sub('namespace_project', 'project')
- arguments = arguments(node)
- arguments.shift # Remove namespace argument
+ arguments = arguments(node)
+ arguments.shift # Remove namespace argument
- replacement = "#{helper_name}(#{arguments.map(&:source).join(', ')})"
+ replacement = "#{helper_name}(#{arguments.map(&:source).join(', ')})"
- lambda do |corrector|
corrector.replace(node.source_range, replacement)
end
end
diff --git a/rubocop/cop/put_group_routes_under_scope.rb b/rubocop/cop/put_group_routes_under_scope.rb
index 9adec044da8..83afd112b99 100644
--- a/rubocop/cop/put_group_routes_under_scope.rb
+++ b/rubocop/cop/put_group_routes_under_scope.rb
@@ -6,7 +6,7 @@ module RuboCop
module Cop
# Checks for a group routes outside '/-/' scope.
# For more information see: https://gitlab.com/gitlab-org/gitlab/issues/29572
- class PutGroupRoutesUnderScope < RuboCop::Cop::Cop
+ class PutGroupRoutesUnderScope < RuboCop::Cop::Base
include RoutesUnderScope
MSG = 'Put new group routes under /-/ scope'
diff --git a/rubocop/cop/put_project_routes_under_scope.rb b/rubocop/cop/put_project_routes_under_scope.rb
index cddb147324f..d3b86bad947 100644
--- a/rubocop/cop/put_project_routes_under_scope.rb
+++ b/rubocop/cop/put_project_routes_under_scope.rb
@@ -6,7 +6,7 @@ module RuboCop
module Cop
# Checks for a project routes outside '/-/' scope.
# For more information see: https://gitlab.com/gitlab-org/gitlab/issues/29572
- class PutProjectRoutesUnderScope < RuboCop::Cop::Cop
+ class PutProjectRoutesUnderScope < RuboCop::Cop::Base
include RoutesUnderScope
MSG = 'Put new project routes under /-/ scope'
diff --git a/rubocop/cop/qa/ambiguous_page_object_name.rb b/rubocop/cop/qa/ambiguous_page_object_name.rb
index a4a2c04f61f..a331851bcc5 100644
--- a/rubocop/cop/qa/ambiguous_page_object_name.rb
+++ b/rubocop/cop/qa/ambiguous_page_object_name.rb
@@ -16,7 +16,7 @@ module RuboCop
# # good
# Page::Object.perform do |object| do ...
# Page::Another.perform { |another| ... }
- class AmbiguousPageObjectName < RuboCop::Cop::Cop
+ class AmbiguousPageObjectName < RuboCop::Cop::Base
include QAHelpers
MESSAGE = "Don't use 'page' as a name for a Page Object. Use `%s` instead."
diff --git a/rubocop/cop/qa/element_with_pattern.rb b/rubocop/cop/qa/element_with_pattern.rb
index d0a42497960..387ca3eb517 100644
--- a/rubocop/cop/qa/element_with_pattern.rb
+++ b/rubocop/cop/qa/element_with_pattern.rb
@@ -16,7 +16,7 @@ module RuboCop
# # good
# element :some_element
# element :some_element, required: true
- class ElementWithPattern < RuboCop::Cop::Cop
+ class ElementWithPattern < RuboCop::Cop::Base
include QAHelpers
MESSAGE = "Don't use a pattern for element, create a corresponding `%s` instead."
diff --git a/rubocop/cop/qa/selector_usage.rb b/rubocop/cop/qa/selector_usage.rb
index 568b1c30851..d615bd2926c 100644
--- a/rubocop/cop/qa/selector_usage.rb
+++ b/rubocop/cop/qa/selector_usage.rb
@@ -16,7 +16,7 @@ module RuboCop
# # good
# find('[data-testid="the_selector"]')
# find('#selector')
- class SelectorUsage < RuboCop::Cop::Cop
+ class SelectorUsage < RuboCop::Cop::Base
include QAHelpers
include CodeReuseHelpers
diff --git a/rubocop/cop/rspec/any_instance_of.rb b/rubocop/cop/rspec/any_instance_of.rb
index a939af36c13..e1cacfebfd3 100644
--- a/rubocop/cop/rspec/any_instance_of.rb
+++ b/rubocop/cop/rspec/any_instance_of.rb
@@ -24,7 +24,9 @@ module RuboCop
# expect(instance).to receive(:invalidate_issue_cache_counts)
# end
#
- class AnyInstanceOf < RuboCop::Cop::Cop
+ class AnyInstanceOf < RuboCop::Cop::Base
+ extend RuboCop::Cop::AutoCorrector
+
MESSAGE_EXPECT = 'Do not use `expect_any_instance_of` method, use `expect_next_instance_of` instead.'
MESSAGE_ALLOW = 'Do not use `allow_any_instance_of` method, use `allow_next_instance_of` instead.'
@@ -37,22 +39,19 @@ module RuboCop
def on_send(node)
if expect_any_instance_of?(node)
- add_offense(node, location: :expression, message: MESSAGE_EXPECT)
+ add_offense(node, message: MESSAGE_EXPECT) do |corrector|
+ corrector.replace(
+ node.loc.expression,
+ replacement_any_instance_of(node, 'expect')
+ )
+ end
elsif allow_any_instance_of?(node)
- add_offense(node, location: :expression, message: MESSAGE_ALLOW)
- end
- end
-
- def autocorrect(node)
- replacement =
- if expect_any_instance_of?(node)
- replacement_any_instance_of(node, 'expect')
- elsif allow_any_instance_of?(node)
- replacement_any_instance_of(node, 'allow')
+ add_offense(node, message: MESSAGE_ALLOW) do |corrector|
+ corrector.replace(
+ node.loc.expression,
+ replacement_any_instance_of(node, 'allow')
+ )
end
-
- lambda do |corrector|
- corrector.replace(node.loc.expression, replacement)
end
end
diff --git a/rubocop/cop/rspec/be_success_matcher.rb b/rubocop/cop/rspec/be_success_matcher.rb
index dce9604b3d7..5a011845075 100644
--- a/rubocop/cop/rspec/be_success_matcher.rb
+++ b/rubocop/cop/rspec/be_success_matcher.rb
@@ -21,7 +21,9 @@ module RuboCop
#
# it { is_expected.to be_successful }
#
- class BeSuccessMatcher < RuboCop::Cop::Cop
+ class BeSuccessMatcher < RuboCop::Cop::Base
+ extend RuboCop::Cop::AutoCorrector
+
MESSAGE = 'Do not use deprecated `success?` method, use `successful?` instead.'
def_node_search :expect_to_be_success?, <<~PATTERN
@@ -39,11 +41,7 @@ module RuboCop
def on_send(node)
return unless be_success_usage?(node)
- add_offense(node, location: :expression, message: MESSAGE)
- end
-
- def autocorrect(node)
- lambda do |corrector|
+ add_offense(node, message: MESSAGE) do |corrector|
corrector.insert_after(node.loc.expression, 'ful')
end
end
diff --git a/rubocop/cop/rspec/env_assignment.rb b/rubocop/cop/rspec/env_assignment.rb
index e3075e7bd90..add7897c624 100644
--- a/rubocop/cop/rspec/env_assignment.rb
+++ b/rubocop/cop/rspec/env_assignment.rb
@@ -16,7 +16,9 @@ module RuboCop
# before do
# stub_env('FOO', 'bar')
# end
- class EnvAssignment < RuboCop::Cop::Cop
+ class EnvAssignment < RuboCop::Cop::Base
+ extend RuboCop::Cop::AutoCorrector
+
MESSAGE = "Don't assign to ENV, use `stub_env` instead."
def_node_search :env_assignment?, <<~PATTERN
@@ -28,11 +30,7 @@ module RuboCop
def on_send(node)
return unless env_assignment?(node)
- add_offense(node, location: :expression, message: MESSAGE)
- end
-
- def autocorrect(node)
- lambda do |corrector|
+ add_offense(node, message: MESSAGE) do |corrector|
corrector.replace(node.loc.expression, stub_env(env_key(node), env_value(node)))
end
end
diff --git a/rubocop/cop/rspec/expect_gitlab_tracking.rb b/rubocop/cop/rspec/expect_gitlab_tracking.rb
index e3f790f851c..4f92980baa4 100644
--- a/rubocop/cop/rspec/expect_gitlab_tracking.rb
+++ b/rubocop/cop/rspec/expect_gitlab_tracking.rb
@@ -29,7 +29,7 @@ module RuboCop
# it 'does not expect a snowplow event', :snowplow do
# expect_no_snowplow_event
# end
- class ExpectGitlabTracking < RuboCop::Cop::Cop
+ class ExpectGitlabTracking < RuboCop::Cop::Base
MSG = 'Do not expect directly on `Gitlab::Tracking#event`, add the `snowplow` annotation and use ' \
'`expect_snowplow_event` instead. ' \
'See https://docs.gitlab.com/ee/development/testing_guide/best_practices.html#test-snowplow-events'
diff --git a/rubocop/cop/rspec/factories_in_migration_specs.rb b/rubocop/cop/rspec/factories_in_migration_specs.rb
index f29bbf68cdc..6dde3d4524c 100644
--- a/rubocop/cop/rspec/factories_in_migration_specs.rb
+++ b/rubocop/cop/rspec/factories_in_migration_specs.rb
@@ -13,7 +13,7 @@ module RuboCop
# # good
# let(:users) { table(:users) }
# let(:user) { users.create!(name: 'User 1', username: 'user1') }
- class FactoriesInMigrationSpecs < RuboCop::Cop::Cop
+ class FactoriesInMigrationSpecs < RuboCop::Cop::Base
MESSAGE = "Don't use FactoryBot.%s in migration specs, use `table` instead."
FORBIDDEN_METHODS = %i[build build_list create create_list attributes_for].freeze
@@ -29,7 +29,7 @@ module RuboCop
method = node.children[1]
- add_offense(node, location: :expression, message: MESSAGE % method)
+ add_offense(node, message: MESSAGE % method)
end
end
end
diff --git a/rubocop/cop/rspec/factory_bot/inline_association.rb b/rubocop/cop/rspec/factory_bot/inline_association.rb
index 1c2b8b55b46..ccc6364fb73 100644
--- a/rubocop/cop/rspec/factory_bot/inline_association.rb
+++ b/rubocop/cop/rspec/factory_bot/inline_association.rb
@@ -43,7 +43,9 @@ module RuboCop
#
# creator_id { create(:user).id }
#
- class InlineAssociation < RuboCop::Cop::Cop
+ class InlineAssociation < RuboCop::Cop::Base
+ extend RuboCop::Cop::AutoCorrector
+
MSG = 'Prefer inline `association` over `%{type}`. ' \
'See https://docs.gitlab.com/ee/development/testing_guide/best_practices.html#factories'
@@ -81,11 +83,7 @@ module RuboCop
return if chained_call?(node.parent)
return unless inside_assocation_definition?(node)
- add_offense(node, message: format(MSG, type: type))
- end
-
- def autocorrect(node)
- lambda do |corrector|
+ add_offense(node, message: format(MSG, type: type)) do |corrector|
receiver, type = create_or_build(node)
receiver = "#{receiver.source}." if receiver
expression = "#{receiver}#{type}"
diff --git a/rubocop/cop/rspec/have_gitlab_http_status.rb b/rubocop/cop/rspec/have_gitlab_http_status.rb
index d61fb9f2368..86ece72b4f5 100644
--- a/rubocop/cop/rspec/have_gitlab_http_status.rb
+++ b/rubocop/cop/rspec/have_gitlab_http_status.rb
@@ -22,7 +22,9 @@ module RuboCop
# expect(response).to have_gitlab_http_status(:ok)
# expect(response).not_to have_gitlab_http_status(:ok)
#
- class HaveGitlabHttpStatus < RuboCop::Cop::Cop
+ class HaveGitlabHttpStatus < RuboCop::Cop::Base
+ extend RuboCop::Cop::AutoCorrector
+
CODE_TO_SYMBOL = Rack::Utils::SYMBOL_TO_STATUS_CODE.invert
MSG_MATCHER_NAME =
@@ -66,13 +68,6 @@ module RuboCop
offense_for_matcher(node) || offense_for_response_status(node)
end
- def autocorrect(node)
- lambda do |corrector|
- replacement = replace_matcher(node) || replace_response_status(node)
- corrector.replace(node.source_range, replacement)
- end
- end
-
private
def offense_for_matcher(node)
@@ -85,13 +80,20 @@ module RuboCop
return if offenses.empty?
- add_offense(node, message: message_for(*offenses))
+ add_offense(node, message: message_for(*offenses), &corrector(node))
end
def offense_for_response_status(node)
return unless response_status_eq?(node)
- add_offense(node, message: message_for(MSG_RESPONSE_STATUS))
+ add_offense(node, message: message_for(MSG_RESPONSE_STATUS), &corrector(node))
+ end
+
+ def corrector(node)
+ lambda do |corrector|
+ replacement = replace_matcher(node) || replace_response_status(node)
+ corrector.replace(node.source_range, replacement)
+ end
end
def replace_matcher(node)
diff --git a/rubocop/cop/rspec/httparty_basic_auth.rb b/rubocop/cop/rspec/httparty_basic_auth.rb
index c6b52ac9781..1e0f7ae7af0 100644
--- a/rubocop/cop/rspec/httparty_basic_auth.rb
+++ b/rubocop/cop/rspec/httparty_basic_auth.rb
@@ -12,7 +12,9 @@ module RuboCop
#
# # good
# HTTParty.get(url, basic_auth: { username: 'foo' })
- class HTTPartyBasicAuth < RuboCop::Cop::Cop
+ class HTTPartyBasicAuth < RuboCop::Cop::Base
+ extend RuboCop::Cop::AutoCorrector
+
MESSAGE = "`basic_auth: { user: ... }` does not work - replace `user:` with `username:`"
RESTRICT_ON_SEND = %i(get put post delete).freeze
@@ -35,12 +37,8 @@ module RuboCop
def on_send(node)
return unless m = httparty_basic_auth?(node)
- add_offense(m, location: :expression, message: MESSAGE)
- end
-
- def autocorrect(node)
- lambda do |corrector|
- corrector.replace(node.loc.expression, 'username')
+ add_offense(m, message: MESSAGE) do |corrector|
+ corrector.replace(m, 'username')
end
end
end
diff --git a/rubocop/cop/rspec/modify_sidekiq_middleware.rb b/rubocop/cop/rspec/modify_sidekiq_middleware.rb
index c38f074eb3a..78e3ba223b0 100644
--- a/rubocop/cop/rspec/modify_sidekiq_middleware.rb
+++ b/rubocop/cop/rspec/modify_sidekiq_middleware.rb
@@ -20,7 +20,9 @@ module RuboCop
# end
#
#
- class ModifySidekiqMiddleware < RuboCop::Cop::Cop
+ class ModifySidekiqMiddleware < RuboCop::Cop::Base
+ extend RuboCop::Cop::AutoCorrector
+
MSG = <<~MSG
Don't modify global sidekiq middleware, use the `#with_sidekiq_server_middleware`
helper instead
@@ -35,11 +37,7 @@ module RuboCop
def on_send(node)
return unless modifies_sidekiq_middleware?(node)
- add_offense(node, location: :expression)
- end
-
- def autocorrect(node)
- -> (corrector) do
+ add_offense(node) do |corrector|
corrector.replace(node.loc.expression,
'with_sidekiq_server_middleware')
end
diff --git a/rubocop/cop/rspec/timecop_freeze.rb b/rubocop/cop/rspec/timecop_freeze.rb
index 508b5df7c7f..70e37ecfa55 100644
--- a/rubocop/cop/rspec/timecop_freeze.rb
+++ b/rubocop/cop/rspec/timecop_freeze.rb
@@ -13,7 +13,9 @@ module RuboCop
# # good
# freeze_time(Time.current) { example.run }
#
- class TimecopFreeze < RuboCop::Cop::Cop
+ class TimecopFreeze < RuboCop::Cop::Base
+ extend RuboCop::Cop::AutoCorrector
+
include MatchRange
MESSAGE = 'Do not use `Timecop.freeze`, use `freeze_time` instead. ' \
'See https://gitlab.com/gitlab-org/gitlab/-/issues/214432 for more info.'
@@ -25,11 +27,7 @@ module RuboCop
def on_send(node)
return unless timecop_freeze?(node)
- add_offense(node, location: :expression, message: MESSAGE)
- end
-
- def autocorrect(node)
- -> (corrector) do
+ add_offense(node, message: MESSAGE) do |corrector|
each_match_range(node.source_range, /^(Timecop\.freeze)/) do |match_range|
corrector.replace(match_range, 'freeze_time')
end
diff --git a/rubocop/cop/rspec/timecop_travel.rb b/rubocop/cop/rspec/timecop_travel.rb
index e5416953af7..586567fa0cd 100644
--- a/rubocop/cop/rspec/timecop_travel.rb
+++ b/rubocop/cop/rspec/timecop_travel.rb
@@ -13,7 +13,9 @@ module RuboCop
# # good
# travel_to(1.day.ago) { create(:issue) }
#
- class TimecopTravel < RuboCop::Cop::Cop
+ class TimecopTravel < RuboCop::Cop::Base
+ extend RuboCop::Cop::AutoCorrector
+
include MatchRange
MESSAGE = 'Do not use `Timecop.travel`, use `travel_to` instead. ' \
'See https://gitlab.com/gitlab-org/gitlab/-/issues/214432 for more info.'
@@ -25,11 +27,7 @@ module RuboCop
def on_send(node)
return unless timecop_travel?(node)
- add_offense(node, location: :expression, message: MESSAGE)
- end
-
- def autocorrect(node)
- -> (corrector) do
+ add_offense(node, message: MESSAGE) do |corrector|
each_match_range(node.source_range, /^(Timecop\.travel)/) do |match_range|
corrector.replace(match_range, 'travel_to')
end
diff --git a/rubocop/cop/rspec/web_mock_enable.rb b/rubocop/cop/rspec/web_mock_enable.rb
index bcf7f95dbbd..0bef16a16b0 100644
--- a/rubocop/cop/rspec/web_mock_enable.rb
+++ b/rubocop/cop/rspec/web_mock_enable.rb
@@ -3,7 +3,9 @@
module RuboCop
module Cop
module RSpec
- class WebMockEnable < RuboCop::Cop::Cop
+ class WebMockEnable < RuboCop::Cop::Base
+ extend RuboCop::Cop::AutoCorrector
+
# This cop checks for `WebMock.disable_net_connect!` usage in specs and
# replaces it with `webmock_enable!`
#
@@ -24,13 +26,9 @@ module RuboCop
def on_send(node)
if webmock_disable_net_connect?(node)
- add_offense(node, location: :expression, message: MESSAGE)
- end
- end
-
- def autocorrect(node)
- lambda do |corrector|
- corrector.replace(node, 'webmock_enable!')
+ add_offense(node, message: MESSAGE) do |corrector|
+ corrector.replace(node, 'webmock_enable!')
+ end
end
end
end
diff --git a/rubocop/cop/ruby_interpolation_in_translation.rb b/rubocop/cop/ruby_interpolation_in_translation.rb
index c431b4a1977..fec550bf7c6 100644
--- a/rubocop/cop/ruby_interpolation_in_translation.rb
+++ b/rubocop/cop/ruby_interpolation_in_translation.rb
@@ -2,7 +2,7 @@
module RuboCop
module Cop
- class RubyInterpolationInTranslation < RuboCop::Cop::Cop
+ class RubyInterpolationInTranslation < RuboCop::Cop::Base
MSG = "Don't use ruby interpolation \#{} inside translated strings, instead use \%{}"
TRANSLATION_METHODS = ':_ :s_ :N_ :n_'
diff --git a/rubocop/cop/safe_params.rb b/rubocop/cop/safe_params.rb
index 2720732c161..78c40ee548e 100644
--- a/rubocop/cop/safe_params.rb
+++ b/rubocop/cop/safe_params.rb
@@ -2,7 +2,7 @@
module RuboCop
module Cop
- class SafeParams < RuboCop::Cop::Cop
+ class SafeParams < RuboCop::Cop::Base
MSG = 'Use `safe_params` instead of `params` in url_for.'
METHOD_NAME_PATTERN = :url_for
@@ -11,7 +11,7 @@ module RuboCop
def on_send(node)
return unless method_name(node) == METHOD_NAME_PATTERN
- add_offense(node, location: :expression) unless safe_params?(node)
+ add_offense(node) unless safe_params?(node)
end
private
diff --git a/rubocop/cop/scalability/bulk_perform_with_context.rb b/rubocop/cop/scalability/bulk_perform_with_context.rb
index bb944b2ad62..a31c20d149b 100644
--- a/rubocop/cop/scalability/bulk_perform_with_context.rb
+++ b/rubocop/cop/scalability/bulk_perform_with_context.rb
@@ -6,7 +6,7 @@ require_relative '../../code_reuse_helpers'
module RuboCop
module Cop
module Scalability
- class BulkPerformWithContext < RuboCop::Cop::Cop
+ class BulkPerformWithContext < RuboCop::Cop::Base
include RuboCop::MigrationHelpers
include RuboCop::CodeReuseHelpers
@@ -34,7 +34,7 @@ module RuboCop
return unless schedules_in_batch_without_context?(node)
return if scheduled_for_background_migration?(node)
- add_offense(node, location: :expression)
+ add_offense(node)
end
private
diff --git a/rubocop/cop/scalability/cron_worker_context.rb b/rubocop/cop/scalability/cron_worker_context.rb
index 3cc0d42d7bc..ae8b0b328e2 100644
--- a/rubocop/cop/scalability/cron_worker_context.rb
+++ b/rubocop/cop/scalability/cron_worker_context.rb
@@ -3,7 +3,7 @@
module RuboCop
module Cop
module Scalability
- class CronWorkerContext < RuboCop::Cop::Cop
+ class CronWorkerContext < RuboCop::Cop::Base
MSG = <<~MSG
Manually define an ApplicationContext for cronjob-workers. The context
is required to add metadata to our logs.
@@ -31,7 +31,7 @@ module RuboCop
return if defines_contexts?(node.parent)
return if schedules_with_batch_context?(node.parent)
- add_offense(node.arguments.first, location: :expression)
+ add_offense(node.arguments.first)
end
end
end
diff --git a/rubocop/cop/scalability/file_uploads.rb b/rubocop/cop/scalability/file_uploads.rb
index 83017217e32..3ccb9110e79 100644
--- a/rubocop/cop/scalability/file_uploads.rb
+++ b/rubocop/cop/scalability/file_uploads.rb
@@ -25,7 +25,7 @@ module RuboCop
# optional :file, type: ::API::Validations::Types::WorkhorseFile
# end
#
- class FileUploads < RuboCop::Cop::Cop
+ class FileUploads < RuboCop::Cop::Base
MSG = 'Do not upload files without workhorse acceleration. Please refer to https://docs.gitlab.com/ee/development/uploads.html'
def_node_search :file_type_params?, <<~PATTERN
@@ -43,7 +43,7 @@ module RuboCop
def on_send(node)
return unless be_file_param_usage?(node)
- add_offense(find_file_param(node), location: :expression)
+ add_offense(find_file_param(node))
end
private
diff --git a/rubocop/cop/scalability/idempotent_worker.rb b/rubocop/cop/scalability/idempotent_worker.rb
index 7abde54ce7e..88b5d796def 100644
--- a/rubocop/cop/scalability/idempotent_worker.rb
+++ b/rubocop/cop/scalability/idempotent_worker.rb
@@ -23,7 +23,7 @@ module RuboCop
# end
# end
#
- class IdempotentWorker < RuboCop::Cop::Cop
+ class IdempotentWorker < RuboCop::Cop::Base
include CodeReuseHelpers
HELP_LINK = 'https://github.com/mperham/sidekiq/wiki/Best-Practices#2-make-your-job-idempotent-and-transactional'
@@ -51,7 +51,7 @@ module RuboCop
return unless in_worker?(node)
return if idempotent?(node)
- add_offense(node, location: :expression)
+ add_offense(node)
end
end
end
diff --git a/rubocop/cop/sidekiq_load_balancing/worker_data_consistency.rb b/rubocop/cop/sidekiq_load_balancing/worker_data_consistency.rb
index 7a2e7ee00b4..34c3767ad11 100644
--- a/rubocop/cop/sidekiq_load_balancing/worker_data_consistency.rb
+++ b/rubocop/cop/sidekiq_load_balancing/worker_data_consistency.rb
@@ -23,7 +23,7 @@ module RuboCop
# end
# end
#
- class WorkerDataConsistency < RuboCop::Cop::Cop
+ class WorkerDataConsistency < RuboCop::Cop::Base
include CodeReuseHelpers
HELP_LINK = 'https://docs.gitlab.com/ee/development/sidekiq_style_guide.html#job-data-consistency-strategies'
@@ -57,7 +57,7 @@ module RuboCop
return unless in_worker?(node) && application_worker?(node)
return if data_consistency_defined?(node)
- add_offense(node, location: :expression)
+ add_offense(node)
end
end
end
diff --git a/rubocop/cop/sidekiq_options_queue.rb b/rubocop/cop/sidekiq_options_queue.rb
index 2574a229ec2..3eee59e69fd 100644
--- a/rubocop/cop/sidekiq_options_queue.rb
+++ b/rubocop/cop/sidekiq_options_queue.rb
@@ -3,7 +3,7 @@
module RuboCop
module Cop
# Cop that prevents manually setting a queue in Sidekiq workers.
- class SidekiqOptionsQueue < RuboCop::Cop::Cop
+ class SidekiqOptionsQueue < RuboCop::Cop::Base
MSG = 'Do not manually set a queue; `ApplicationWorker` sets one automatically.'
def_node_matcher :sidekiq_options?, <<~PATTERN
@@ -16,7 +16,7 @@ module RuboCop
node.arguments.first.each_node(:pair) do |pair|
key_name = pair.key.children[0]
- add_offense(pair, location: :expression) if key_name == :queue
+ add_offense(pair) if key_name == :queue
end
end
end
diff --git a/rubocop/cop/static_translation_definition.rb b/rubocop/cop/static_translation_definition.rb
index 121b0c18770..aea4dd6ae34 100644
--- a/rubocop/cop/static_translation_definition.rb
+++ b/rubocop/cop/static_translation_definition.rb
@@ -51,7 +51,7 @@ module RuboCop
# end
# end
#
- class StaticTranslationDefinition < RuboCop::Cop::Cop
+ class StaticTranslationDefinition < RuboCop::Cop::Base
MSG = <<~TEXT.tr("\n", ' ')
Translation is defined in static scope.
Keep translations dynamic. See https://docs.gitlab.com/ee/development/i18n/externalization.html#keep-translations-dynamic
diff --git a/rubocop/cop/usage_data/distinct_count_by_large_foreign_key.rb b/rubocop/cop/usage_data/distinct_count_by_large_foreign_key.rb
index 3aad089d961..a083318288b 100644
--- a/rubocop/cop/usage_data/distinct_count_by_large_foreign_key.rb
+++ b/rubocop/cop/usage_data/distinct_count_by_large_foreign_key.rb
@@ -12,7 +12,7 @@ module RuboCop
# # bad because pipeline_id points to a large table
# distinct_count(Ci::Build, :commit_id)
#
- class DistinctCountByLargeForeignKey < RuboCop::Cop::Cop
+ class DistinctCountByLargeForeignKey < RuboCop::Cop::Base
MSG = 'Avoid doing `%s` on foreign keys for large tables having above 100 million rows.'
def_node_matcher :distinct_count?, <<-PATTERN
@@ -25,7 +25,7 @@ module RuboCop
next if batch_set_to_false?(method_arguments[2])
next if allowed_foreign_key?(method_arguments[1])
- add_offense(node, location: :selector, message: format(MSG, method_name))
+ add_offense(node.loc.selector, message: format(MSG, method_name))
end
end
diff --git a/rubocop/cop/usage_data/histogram_with_large_table.rb b/rubocop/cop/usage_data/histogram_with_large_table.rb
index 961773df55c..35ec568792c 100644
--- a/rubocop/cop/usage_data/histogram_with_large_table.rb
+++ b/rubocop/cop/usage_data/histogram_with_large_table.rb
@@ -11,7 +11,7 @@ module RuboCop
# # bad
# histogram(Issue, buckets: 1..100)
# histogram(User.active, buckets: 1..100)
- class HistogramWithLargeTable < RuboCop::Cop::Cop
+ class HistogramWithLargeTable < RuboCop::Cop::Base
MSG = 'Avoid histogram method on %{model_name}'
# Match one level const as Issue, Gitlab
@@ -38,9 +38,9 @@ module RuboCop
class_name = two_level_matches ? two_level_matches.join('::').to_sym : one_level_matches
- if large_table?(class_name)
- add_offense(node, location: :expression, message: format(MSG, model_name: class_name))
- end
+ return unless large_table?(class_name)
+
+ add_offense(node, message: format(MSG, model_name: class_name))
end
private
diff --git a/rubocop/cop/usage_data/instrumentation_superclass.rb b/rubocop/cop/usage_data/instrumentation_superclass.rb
index 2ff2ed47a23..601f2340582 100644
--- a/rubocop/cop/usage_data/instrumentation_superclass.rb
+++ b/rubocop/cop/usage_data/instrumentation_superclass.rb
@@ -16,7 +16,7 @@ module RuboCop
# class CountIssues < BaseMetric
# # ...
# end
- class InstrumentationSuperclass < RuboCop::Cop::Cop
+ class InstrumentationSuperclass < RuboCop::Cop::Base
MSG = "Instrumentation classes should subclass one of the following: %{allowed_classes}."
BASE_PATTERN = "(const nil? !#allowed_class?)"
diff --git a/rubocop/cop/usage_data/large_table.rb b/rubocop/cop/usage_data/large_table.rb
index d9d44f74d26..7d50eebaa83 100644
--- a/rubocop/cop/usage_data/large_table.rb
+++ b/rubocop/cop/usage_data/large_table.rb
@@ -3,7 +3,7 @@
module RuboCop
module Cop
module UsageData
- class LargeTable < RuboCop::Cop::Cop
+ class LargeTable < RuboCop::Cop::Base
# This cop checks that batch count and distinct_count are used in usage_data.rb files in metrics based on ActiveRecord models.
#
# @example
@@ -56,7 +56,7 @@ module RuboCop
counters_used = node.ancestors.any? { |ancestor| allowed_method?(ancestor) }
unless counters_used
- add_offense(node, location: :expression, message: format(MSG, count_methods: count_methods.join(', '), class_name: class_name))
+ add_offense(node, message: format(MSG, count_methods: count_methods.join(', '), class_name: class_name))
end
end
diff --git a/rubocop/cop/user_admin.rb b/rubocop/cop/user_admin.rb
index 3ba0e770ec1..643e620666b 100644
--- a/rubocop/cop/user_admin.rb
+++ b/rubocop/cop/user_admin.rb
@@ -3,7 +3,7 @@
module RuboCop
module Cop
# Cop that rejects the usage of `User#admin?`
- class UserAdmin < RuboCop::Cop::Cop
+ class UserAdmin < RuboCop::Cop::Base
MSG = 'Direct calls to `User#admin?` to determine admin status should be ' \
'avoided as they will not take into account the policies framework ' \
'and will ignore Admin Mode if enabled. Please use a policy check ' \
@@ -26,7 +26,7 @@ module RuboCop
def on_handler(node)
return unless admin_call?(node)
- add_offense(node, location: :selector)
+ add_offense(node.loc.selector)
end
end
end
diff --git a/spec/config/object_store_settings_spec.rb b/spec/config/object_store_settings_spec.rb
index 1555124fe03..8ddb5652dae 100644
--- a/spec/config/object_store_settings_spec.rb
+++ b/spec/config/object_store_settings_spec.rb
@@ -200,33 +200,6 @@ RSpec.describe ObjectStoreSettings do
expect(settings.external_diffs['object_store']).to be_nil
end
end
-
- context 'with legacy config and legacy background upload is enabled' do
- let(:legacy_settings) do
- {
- 'enabled' => true,
- 'remote_directory' => 'some-bucket',
- 'proxy_download' => false
- }
- end
-
- before do
- stub_env(ObjectStoreSettings::LEGACY_BACKGROUND_UPLOADS_ENV, 'lfs')
- settings.lfs['object_store'] = described_class.legacy_parse(legacy_settings, 'lfs')
- end
-
- it 'enables background_upload and disables direct_upload' do
- subject
-
- expect(settings.artifacts['object_store']).to be_nil
- expect(settings.lfs['object_store']['remote_directory']).to eq('some-bucket')
- expect(settings.lfs['object_store']['bucket_prefix']).to eq(nil)
- # Enable background_upload if the environment variable is available
- expect(settings.lfs['object_store']['direct_upload']).to eq(false)
- expect(settings.lfs['object_store']['background_upload']).to eq(true)
- expect(settings.external_diffs['object_store']).to be_nil
- end
- end
end
end
@@ -266,48 +239,6 @@ RSpec.describe ObjectStoreSettings do
expect(settings['remote_directory']).to eq 'gitlab'
expect(settings['bucket_prefix']).to eq 'artifacts'
end
-
- context 'legacy background upload environment variable is enabled' do
- before do
- stub_env(ObjectStoreSettings::LEGACY_BACKGROUND_UPLOADS_ENV, 'artifacts,lfs')
- end
-
- it 'enables background_upload and disables direct_upload' do
- original_settings = Settingslogic.new({
- 'enabled' => true,
- 'remote_directory' => 'artifacts'
- })
-
- settings = described_class.legacy_parse(original_settings, 'artifacts')
-
- expect(settings['enabled']).to be true
- expect(settings['direct_upload']).to be false
- expect(settings['background_upload']).to be true
- expect(settings['remote_directory']).to eq 'artifacts'
- expect(settings['bucket_prefix']).to eq nil
- end
- end
-
- context 'legacy background upload environment variable is enabled for other types' do
- before do
- stub_env(ObjectStoreSettings::LEGACY_BACKGROUND_UPLOADS_ENV, 'uploads,lfs')
- end
-
- it 'enables direct_upload and disables background_upload' do
- original_settings = Settingslogic.new({
- 'enabled' => true,
- 'remote_directory' => 'artifacts'
- })
-
- settings = described_class.legacy_parse(original_settings, 'artifacts')
-
- expect(settings['enabled']).to be true
- expect(settings['direct_upload']).to be true
- expect(settings['background_upload']).to be false
- expect(settings['remote_directory']).to eq 'artifacts'
- expect(settings['bucket_prefix']).to eq nil
- end
- end
end
describe '.split_bucket_prefix' do
diff --git a/spec/controllers/concerns/continue_params_spec.rb b/spec/controllers/concerns/continue_params_spec.rb
index c010e8ffbd0..ba600b8156a 100644
--- a/spec/controllers/concerns/continue_params_spec.rb
+++ b/spec/controllers/concerns/continue_params_spec.rb
@@ -4,6 +4,7 @@ require 'spec_helper'
RSpec.describe ContinueParams do
let(:controller_class) do
+ # rubocop:disable Rails/ApplicationController
Class.new(ActionController::Base) do
include ContinueParams
@@ -11,6 +12,7 @@ RSpec.describe ContinueParams do
@request ||= Struct.new(:host, :port).new('test.host', 80)
end
end
+ # rubocop:enable Rails/ApplicationController
end
subject(:controller) { controller_class.new }
diff --git a/spec/frontend/releases/stores/modules/detail/actions_spec.js b/spec/frontend/releases/stores/modules/detail/actions_spec.js
index ce3b690213c..48fba3adb24 100644
--- a/spec/frontend/releases/stores/modules/detail/actions_spec.js
+++ b/spec/frontend/releases/stores/modules/detail/actions_spec.js
@@ -352,6 +352,32 @@ describe('Release edit/new actions', () => {
});
});
+ describe('when the GraphQL returns errors as data', () => {
+ beforeEach(() => {
+ gqClient.mutate.mockResolvedValue({ data: { releaseCreate: { errors: ['Yikes!'] } } });
+ });
+
+ it(`commits ${types.RECEIVE_SAVE_RELEASE_ERROR} with an error object`, () => {
+ return testAction(actions.createRelease, undefined, state, [
+ {
+ type: types.RECEIVE_SAVE_RELEASE_ERROR,
+ payload: expect.any(Error),
+ },
+ ]);
+ });
+
+ it(`shows a flash message`, () => {
+ return actions
+ .createRelease({ commit: jest.fn(), dispatch: jest.fn(), state, getters: {} })
+ .then(() => {
+ expect(createFlash).toHaveBeenCalledTimes(1);
+ expect(createFlash).toHaveBeenCalledWith({
+ message: 'Yikes!',
+ });
+ });
+ });
+ });
+
describe('when the GraphQL network request fails', () => {
beforeEach(() => {
gqClient.mutate.mockRejectedValue(error);
diff --git a/spec/graphql/mutations/releases/create_spec.rb b/spec/graphql/mutations/releases/create_spec.rb
index b6b9449aa39..e7c25a20bad 100644
--- a/spec/graphql/mutations/releases/create_spec.rb
+++ b/spec/graphql/mutations/releases/create_spec.rb
@@ -135,7 +135,7 @@ RSpec.describe Mutations::Releases::Create do
it 'has an access error' do
subject
- expect(resolve).to include(errors: ['Access Denied'])
+ expect(resolve).to include(errors: ['You are not allowed to create this tag as it is protected.'])
end
end
end
diff --git a/spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb b/spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb
index 0f87ee82733..e730afc72b5 100644
--- a/spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb
+++ b/spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb
@@ -19,17 +19,36 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do
}
end
+ let(:report_data) do
+ {
+ 'scan' => {
+ 'analyzer' => {
+ 'id' => 'my-dast-analyzer',
+ 'name' => 'My DAST analyzer',
+ 'version' => '0.1.0',
+ 'vendor' => { 'name' => 'A DAST analyzer' }
+ },
+ 'end_time' => '2020-01-28T03:26:02',
+ 'scanned_resources' => [],
+ 'scanner' => {
+ 'id' => 'my-dast-scanner',
+ 'name' => 'My DAST scanner',
+ 'version' => '0.2.0',
+ 'vendor' => { 'name' => 'A DAST scanner' }
+ },
+ 'start_time' => '2020-01-28T03:26:01',
+ 'status' => 'success',
+ 'type' => 'dast'
+ },
+ 'version' => report_version,
+ 'vulnerabilities' => []
+ }
+ end
+
let(:validator) { described_class.new(report_type, report_data, report_version, project: project, scanner: scanner) }
shared_examples 'report is valid' do
context 'and the report is valid' do
- let(:report_data) do
- {
- 'version' => report_version,
- 'vulnerabilities' => []
- }
- end
-
it { is_expected.to be_truthy }
end
end
@@ -245,13 +264,6 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do
shared_examples 'report is valid with no error' do
context 'and the report is valid' do
- let(:report_data) do
- {
- 'version' => report_version,
- 'vulnerabilities' => []
- }
- end
-
it { is_expected.to be_empty }
end
end
@@ -278,7 +290,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do
let(:expected_errors) do
[
- 'root is missing required keys: vulnerabilities'
+ 'root is missing required keys: scan, vulnerabilities'
]
end
diff --git a/spec/lib/gitlab/ci/pipeline/chain/sequence_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/sequence_spec.rb
index e8eb3333b88..ee32661f267 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/sequence_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/sequence_spec.rb
@@ -83,19 +83,36 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Sequence do
.with({ source: 'push' }, 0)
end
- it 'records active jobs by pipeline plan in a histogram' do
- allow(command.metrics)
- .to receive(:active_jobs_histogram)
- .and_return(histogram)
+ describe 'active jobs by pipeline plan histogram' do
+ before do
+ allow(command.metrics)
+ .to receive(:active_jobs_histogram)
+ .and_return(histogram)
+
+ pipeline = create(:ci_pipeline, :running, project: project)
+ create_list(:ci_build, 3, pipeline: pipeline)
+ create(:ci_bridge, pipeline: pipeline)
+ end
- pipeline = create(:ci_pipeline, project: project, status: :running)
- create(:ci_build, :finished, project: project, pipeline: pipeline)
- create(:ci_build, :failed, project: project, pipeline: pipeline)
- create(:ci_build, :running, project: project, pipeline: pipeline)
- subject.build!
+ it 'counts all the active jobs' do
+ subject.build!
- expect(histogram).to have_received(:observe)
- .with(hash_including(plan: project.actual_plan_name), 3)
+ expect(histogram).to have_received(:observe)
+ .with(hash_including(plan: project.actual_plan_name), 4)
+ end
+
+ context 'when feature flag ci_limit_active_jobs_early is disabled' do
+ before do
+ stub_feature_flags(ci_limit_active_jobs_early: false)
+ end
+
+ it 'counts all the active builds' do
+ subject.build!
+
+ expect(histogram).to have_received(:observe)
+ .with(hash_including(plan: project.actual_plan_name), 3)
+ end
+ end
end
end
end
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index 29ff0641aa9..f93aeef4f23 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -466,6 +466,48 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
end
end
+ describe '.jobs_count_in_alive_pipelines' do
+ before do
+ ::Ci::HasStatus::ALIVE_STATUSES.each do |status|
+ alive_pipeline = create(:ci_pipeline, status: status, project: project)
+ create(:ci_build, pipeline: alive_pipeline)
+ create(:ci_bridge, pipeline: alive_pipeline)
+ end
+
+ completed_pipeline = create(:ci_pipeline, :success, project: project)
+ create(:ci_build, pipeline: completed_pipeline)
+
+ old_pipeline = create(:ci_pipeline, :running, project: project, created_at: 2.days.ago)
+ create(:ci_build, pipeline: old_pipeline)
+ end
+
+ it 'includes all jobs in alive pipelines created in the last 24 hours' do
+ expect(described_class.jobs_count_in_alive_pipelines)
+ .to eq(::Ci::HasStatus::ALIVE_STATUSES.count * 2)
+ end
+ end
+
+ describe '.builds_count_in_alive_pipelines' do
+ before do
+ ::Ci::HasStatus::ALIVE_STATUSES.each do |status|
+ alive_pipeline = create(:ci_pipeline, status: status, project: project)
+ create(:ci_build, pipeline: alive_pipeline)
+ create(:ci_bridge, pipeline: alive_pipeline)
+ end
+
+ completed_pipeline = create(:ci_pipeline, :success, project: project)
+ create(:ci_build, pipeline: completed_pipeline)
+
+ old_pipeline = create(:ci_pipeline, :running, project: project, created_at: 2.days.ago)
+ create(:ci_build, pipeline: old_pipeline)
+ end
+
+ it 'includes all builds in alive pipelines created in the last 24 hours' do
+ expect(described_class.builds_count_in_alive_pipelines)
+ .to eq(::Ci::HasStatus::ALIVE_STATUSES.count)
+ end
+ end
+
describe '#merge_request?' do
let_it_be(:merge_request) { create(:merge_request) }
let_it_be_with_reload(:pipeline) do
diff --git a/spec/rubocop/code_reuse_helpers_spec.rb b/spec/rubocop/code_reuse_helpers_spec.rb
index a8f935426e6..a112c9754f3 100644
--- a/spec/rubocop/code_reuse_helpers_spec.rb
+++ b/spec/rubocop/code_reuse_helpers_spec.rb
@@ -342,7 +342,7 @@ RSpec.describe RuboCop::CodeReuseHelpers do
expect(cop)
.to receive(:add_offense)
- .with(send_node, location: :expression, message: 'oops')
+ .with(send_node, message: 'oops')
cop.disallow_send_to(def_node, 'Finder', 'oops')
end
diff --git a/spec/rubocop/cop/active_model_errors_direct_manipulation_spec.rb b/spec/rubocop/cop/active_model_errors_direct_manipulation_spec.rb
index 203c3b4d019..6be2f4945fd 100644
--- a/spec/rubocop/cop/active_model_errors_direct_manipulation_spec.rb
+++ b/spec/rubocop/cop/active_model_errors_direct_manipulation_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../rubocop/cop/active_model_errors_direct_manipulation'
RSpec.describe RuboCop::Cop::ActiveModelErrorsDirectManipulation do
- subject(:cop) { described_class.new }
-
context 'when modifying errors' do
it 'registers an offense' do
expect_offense(<<~PATTERN)
diff --git a/spec/rubocop/cop/active_record_association_reload_spec.rb b/spec/rubocop/cop/active_record_association_reload_spec.rb
index 8f5e40ba5dd..9f101b80d9a 100644
--- a/spec/rubocop/cop/active_record_association_reload_spec.rb
+++ b/spec/rubocop/cop/active_record_association_reload_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../rubocop/cop/active_record_association_reload'
RSpec.describe RuboCop::Cop::ActiveRecordAssociationReload do
- subject(:cop) { described_class.new }
-
context 'when using ActiveRecord::Base' do
it 'registers an offense on reload usage' do
expect_offense(<<~PATTERN)
diff --git a/spec/rubocop/cop/api/base_spec.rb b/spec/rubocop/cop/api/base_spec.rb
index 3f87b6fd7a0..66e99b75643 100644
--- a/spec/rubocop/cop/api/base_spec.rb
+++ b/spec/rubocop/cop/api/base_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/api/base'
RSpec.describe RuboCop::Cop::API::Base do
- subject(:cop) { described_class.new }
-
let(:corrected) do
<<~CORRECTED
class SomeAPI < ::API::Base
diff --git a/spec/rubocop/cop/api/grape_array_missing_coerce_spec.rb b/spec/rubocop/cop/api/grape_array_missing_coerce_spec.rb
index 5f310b68f18..1d1754df838 100644
--- a/spec/rubocop/cop/api/grape_array_missing_coerce_spec.rb
+++ b/spec/rubocop/cop/api/grape_array_missing_coerce_spec.rb
@@ -10,8 +10,6 @@ RSpec.describe RuboCop::Cop::API::GrapeArrayMissingCoerce do
"https://github.com/ruby-grape/grape/blob/master/UPGRADING.md#ensure-that-array-types-have-explicit-coercions"
end
- subject(:cop) { described_class.new }
-
it 'adds an offense with a required parameter' do
expect_offense(<<~TYPE)
class SomeAPI < Grape::API::Instance
diff --git a/spec/rubocop/cop/avoid_becomes_spec.rb b/spec/rubocop/cop/avoid_becomes_spec.rb
index 4bb6c70c19f..d67b79329c9 100644
--- a/spec/rubocop/cop/avoid_becomes_spec.rb
+++ b/spec/rubocop/cop/avoid_becomes_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../rubocop/cop/avoid_becomes'
RSpec.describe RuboCop::Cop::AvoidBecomes do
- subject(:cop) { described_class.new }
-
it 'flags the use of becomes with a constant parameter' do
expect_offense(<<~CODE)
foo.becomes(Project)
diff --git a/spec/rubocop/cop/avoid_break_from_strong_memoize_spec.rb b/spec/rubocop/cop/avoid_break_from_strong_memoize_spec.rb
index c66e2fb07b6..9b7d988cb24 100644
--- a/spec/rubocop/cop/avoid_break_from_strong_memoize_spec.rb
+++ b/spec/rubocop/cop/avoid_break_from_strong_memoize_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../rubocop/cop/avoid_break_from_strong_memoize'
RSpec.describe RuboCop::Cop::AvoidBreakFromStrongMemoize do
- subject(:cop) { described_class.new }
-
it 'flags violation for break inside strong_memoize' do
expect_offense(<<~RUBY)
strong_memoize(:result) do
diff --git a/spec/rubocop/cop/avoid_keyword_arguments_in_sidekiq_workers_spec.rb b/spec/rubocop/cop/avoid_keyword_arguments_in_sidekiq_workers_spec.rb
index 76999891212..eb2417a7eef 100644
--- a/spec/rubocop/cop/avoid_keyword_arguments_in_sidekiq_workers_spec.rb
+++ b/spec/rubocop/cop/avoid_keyword_arguments_in_sidekiq_workers_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../rubocop/cop/avoid_keyword_arguments_in_sidekiq_workers'
RSpec.describe RuboCop::Cop::AvoidKeywordArgumentsInSidekiqWorkers do
- subject(:cop) { described_class.new }
-
it 'flags violation for keyword arguments usage in perform method signature' do
expect_offense(<<~RUBY)
def perform(id:)
diff --git a/spec/rubocop/cop/avoid_return_from_blocks_spec.rb b/spec/rubocop/cop/avoid_return_from_blocks_spec.rb
index 67e7e7912f2..e35705ae791 100644
--- a/spec/rubocop/cop/avoid_return_from_blocks_spec.rb
+++ b/spec/rubocop/cop/avoid_return_from_blocks_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../rubocop/cop/avoid_return_from_blocks'
RSpec.describe RuboCop::Cop::AvoidReturnFromBlocks do
- subject(:cop) { described_class.new }
-
it 'flags violation for return inside a block' do
expect_offense(<<~RUBY)
call do
diff --git a/spec/rubocop/cop/avoid_route_redirect_leading_slash_spec.rb b/spec/rubocop/cop/avoid_route_redirect_leading_slash_spec.rb
index 0205bc9f02a..377050eb301 100644
--- a/spec/rubocop/cop/avoid_route_redirect_leading_slash_spec.rb
+++ b/spec/rubocop/cop/avoid_route_redirect_leading_slash_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../rubocop/cop/avoid_route_redirect_leading_slash'
RSpec.describe RuboCop::Cop::AvoidRouteRedirectLeadingSlash do
- subject(:cop) { described_class.new }
-
before do
allow(cop).to receive(:in_routes?).and_return(true)
end
diff --git a/spec/rubocop/cop/ban_catch_throw_spec.rb b/spec/rubocop/cop/ban_catch_throw_spec.rb
index 9a829a94ef5..a41868410eb 100644
--- a/spec/rubocop/cop/ban_catch_throw_spec.rb
+++ b/spec/rubocop/cop/ban_catch_throw_spec.rb
@@ -5,8 +5,6 @@ require 'rubocop_spec_helper'
require_relative '../../../rubocop/cop/ban_catch_throw'
RSpec.describe RuboCop::Cop::BanCatchThrow do
- subject(:cop) { described_class.new }
-
it 'registers an offense when `catch` or `throw` are used' do
expect_offense(<<~CODE)
catch(:foo) {
diff --git a/spec/rubocop/cop/code_reuse/finder_spec.rb b/spec/rubocop/cop/code_reuse/finder_spec.rb
index 4e49b2c4f9f..8e285e3d988 100644
--- a/spec/rubocop/cop/code_reuse/finder_spec.rb
+++ b/spec/rubocop/cop/code_reuse/finder_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/code_reuse/finder'
RSpec.describe RuboCop::Cop::CodeReuse::Finder do
- subject(:cop) { described_class.new }
-
it 'flags the use of a Finder inside another Finder' do
allow(cop)
.to receive(:in_finder?)
diff --git a/spec/rubocop/cop/code_reuse/presenter_spec.rb b/spec/rubocop/cop/code_reuse/presenter_spec.rb
index 804e61a4c6f..fb7a95f930d 100644
--- a/spec/rubocop/cop/code_reuse/presenter_spec.rb
+++ b/spec/rubocop/cop/code_reuse/presenter_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/code_reuse/presenter'
RSpec.describe RuboCop::Cop::CodeReuse::Presenter do
- subject(:cop) { described_class.new }
-
it 'flags the use of a Presenter in a Service class' do
allow(cop)
.to receive(:in_service_class?)
diff --git a/spec/rubocop/cop/code_reuse/serializer_spec.rb b/spec/rubocop/cop/code_reuse/serializer_spec.rb
index 5ff01812ebb..b1f22c7b969 100644
--- a/spec/rubocop/cop/code_reuse/serializer_spec.rb
+++ b/spec/rubocop/cop/code_reuse/serializer_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/code_reuse/serializer'
RSpec.describe RuboCop::Cop::CodeReuse::Serializer do
- subject(:cop) { described_class.new }
-
it 'flags the use of a Serializer in a Service class' do
allow(cop)
.to receive(:in_service_class?)
diff --git a/spec/rubocop/cop/code_reuse/service_class_spec.rb b/spec/rubocop/cop/code_reuse/service_class_spec.rb
index 5467df9a803..5792b86a535 100644
--- a/spec/rubocop/cop/code_reuse/service_class_spec.rb
+++ b/spec/rubocop/cop/code_reuse/service_class_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/code_reuse/service_class'
RSpec.describe RuboCop::Cop::CodeReuse::ServiceClass do
- subject(:cop) { described_class.new }
-
it 'flags the use of a Service class in a Finder' do
allow(cop)
.to receive(:in_finder?)
diff --git a/spec/rubocop/cop/code_reuse/worker_spec.rb b/spec/rubocop/cop/code_reuse/worker_spec.rb
index 3b3a0788d7d..2df5ebc56fa 100644
--- a/spec/rubocop/cop/code_reuse/worker_spec.rb
+++ b/spec/rubocop/cop/code_reuse/worker_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/code_reuse/worker'
RSpec.describe RuboCop::Cop::CodeReuse::Worker do
- subject(:cop) { described_class.new }
-
it 'flags the use of a worker in a controller' do
allow(cop)
.to receive(:in_controller?)
diff --git a/spec/rubocop/cop/database/disable_referential_integrity_spec.rb b/spec/rubocop/cop/database/disable_referential_integrity_spec.rb
index 25d5dc7cb1d..5d31e55e586 100644
--- a/spec/rubocop/cop/database/disable_referential_integrity_spec.rb
+++ b/spec/rubocop/cop/database/disable_referential_integrity_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/database/disable_referential_integrity'
RSpec.describe RuboCop::Cop::Database::DisableReferentialIntegrity do
- subject(:cop) { described_class.new }
-
it 'does not flag the use of disable_referential_integrity with a send receiver' do
expect_offense(<<~SOURCE)
foo.disable_referential_integrity
diff --git a/spec/rubocop/cop/database/establish_connection_spec.rb b/spec/rubocop/cop/database/establish_connection_spec.rb
index 88bf16083e4..987f68def75 100644
--- a/spec/rubocop/cop/database/establish_connection_spec.rb
+++ b/spec/rubocop/cop/database/establish_connection_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/database/establish_connection'
RSpec.describe RuboCop::Cop::Database::EstablishConnection do
- subject(:cop) { described_class.new }
-
it 'flags the use of ActiveRecord::Base.establish_connection' do
expect_offense(<<~CODE)
ActiveRecord::Base.establish_connection
diff --git a/spec/rubocop/cop/database/multiple_databases_spec.rb b/spec/rubocop/cop/database/multiple_databases_spec.rb
index a5061735848..124e8aaf39c 100644
--- a/spec/rubocop/cop/database/multiple_databases_spec.rb
+++ b/spec/rubocop/cop/database/multiple_databases_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/database/multiple_databases'
RSpec.describe RuboCop::Cop::Database::MultipleDatabases do
- subject(:cop) { described_class.new }
-
it 'flags the use of ActiveRecord::Base.connection' do
expect_offense(<<~SOURCE)
ActiveRecord::Base.connection.inspect
diff --git a/spec/rubocop/cop/database/rescue_query_canceled_spec.rb b/spec/rubocop/cop/database/rescue_query_canceled_spec.rb
index 170fe06bb9e..2418b45e3bb 100644
--- a/spec/rubocop/cop/database/rescue_query_canceled_spec.rb
+++ b/spec/rubocop/cop/database/rescue_query_canceled_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/database/rescue_query_canceled'
RSpec.describe RuboCop::Cop::Database::RescueQueryCanceled do
- subject(:cop) { described_class.new }
-
it 'flags the use of ActiveRecord::QueryCanceled' do
expect_offense(<<~CODE)
begin
diff --git a/spec/rubocop/cop/database/rescue_statement_timeout_spec.rb b/spec/rubocop/cop/database/rescue_statement_timeout_spec.rb
index 9048930860d..bfeba2b4d00 100644
--- a/spec/rubocop/cop/database/rescue_statement_timeout_spec.rb
+++ b/spec/rubocop/cop/database/rescue_statement_timeout_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/database/rescue_statement_timeout'
RSpec.describe RuboCop::Cop::Database::RescueStatementTimeout do
- subject(:cop) { described_class.new }
-
it 'flags the use of ActiveRecord::StatementTimeout' do
expect_offense(<<~CODE)
begin
diff --git a/spec/rubocop/cop/default_scope_spec.rb b/spec/rubocop/cop/default_scope_spec.rb
index 3a0607c32b8..d1f26cdce46 100644
--- a/spec/rubocop/cop/default_scope_spec.rb
+++ b/spec/rubocop/cop/default_scope_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../rubocop/cop/default_scope'
RSpec.describe RuboCop::Cop::DefaultScope do
- subject(:cop) { described_class.new }
-
it 'does not flag the use of default_scope with a send receiver' do
expect_no_offenses('foo.default_scope')
end
diff --git a/spec/rubocop/cop/destroy_all_spec.rb b/spec/rubocop/cop/destroy_all_spec.rb
index cdc1fbbb531..f984822a4e8 100644
--- a/spec/rubocop/cop/destroy_all_spec.rb
+++ b/spec/rubocop/cop/destroy_all_spec.rb
@@ -4,18 +4,16 @@ require 'rubocop_spec_helper'
require_relative '../../../rubocop/cop/destroy_all'
RSpec.describe RuboCop::Cop::DestroyAll do
- subject(:cop) { described_class.new }
-
it 'flags the use of destroy_all with a send receiver' do
expect_offense(<<~CODE)
- foo.destroy_all # rubocop: disable Cop/DestroyAll
+ foo.destroy_all
^^^^^^^^^^^^^^^ Use `delete_all` instead of `destroy_all`. [...]
CODE
end
it 'flags the use of destroy_all with a constant receiver' do
expect_offense(<<~CODE)
- User.destroy_all # rubocop: disable Cop/DestroyAll
+ User.destroy_all
^^^^^^^^^^^^^^^^ Use `delete_all` instead of `destroy_all`. [...]
CODE
end
@@ -30,7 +28,7 @@ RSpec.describe RuboCop::Cop::DestroyAll do
it 'flags the use of destroy_all with a local variable receiver' do
expect_offense(<<~CODE)
users = User.all
- users.destroy_all # rubocop: disable Cop/DestroyAll
+ users.destroy_all
^^^^^^^^^^^^^^^^^ Use `delete_all` instead of `destroy_all`. [...]
CODE
end
diff --git a/spec/rubocop/cop/file_decompression_spec.rb b/spec/rubocop/cop/file_decompression_spec.rb
index 8b4aa8d57c3..19d71a2e85b 100644
--- a/spec/rubocop/cop/file_decompression_spec.rb
+++ b/spec/rubocop/cop/file_decompression_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../rubocop/cop/file_decompression'
RSpec.describe RuboCop::Cop::FileDecompression do
- subject(:cop) { described_class.new }
-
it 'does not flag when using a system command not related to file decompression' do
expect_no_offenses('system("ls")')
end
diff --git a/spec/rubocop/cop/filename_length_spec.rb b/spec/rubocop/cop/filename_length_spec.rb
index d8d0affd9cc..1ea368d282f 100644
--- a/spec/rubocop/cop/filename_length_spec.rb
+++ b/spec/rubocop/cop/filename_length_spec.rb
@@ -5,8 +5,6 @@ require 'rubocop/rspec/support'
require_relative '../../../rubocop/cop/filename_length'
RSpec.describe RuboCop::Cop::FilenameLength do
- subject(:cop) { described_class.new }
-
it 'does not flag files with names 100 characters long' do
expect_no_offenses('puts "it does not matter"', 'a' * 100)
end
diff --git a/spec/rubocop/cop/gemspec/avoid_executing_git_spec.rb b/spec/rubocop/cop/gemspec/avoid_executing_git_spec.rb
index c94fb9da113..6a1982d8101 100644
--- a/spec/rubocop/cop/gemspec/avoid_executing_git_spec.rb
+++ b/spec/rubocop/cop/gemspec/avoid_executing_git_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/gemspec/avoid_executing_git'
RSpec.describe RuboCop::Cop::Gemspec::AvoidExecutingGit do
- subject(:cop) { described_class.new }
-
it 'flags violation for executing git' do
expect_offense(<<~RUBY)
Gem::Specification.new do |gem|
diff --git a/spec/rubocop/cop/gitlab/avoid_feature_category_not_owned_spec.rb b/spec/rubocop/cop/gitlab/avoid_feature_category_not_owned_spec.rb
index 19a82231a80..9cacee5f75d 100644
--- a/spec/rubocop/cop/gitlab/avoid_feature_category_not_owned_spec.rb
+++ b/spec/rubocop/cop/gitlab/avoid_feature_category_not_owned_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/gitlab/avoid_feature_category_not_owned'
RSpec.describe RuboCop::Cop::Gitlab::AvoidFeatureCategoryNotOwned do
- subject(:cop) { described_class.new }
-
shared_examples 'defining feature category on a class' do
it 'flags a method call on a class' do
expect_offense(<<~SOURCE)
@@ -31,7 +29,7 @@ RSpec.describe RuboCop::Cop::Gitlab::AvoidFeatureCategoryNotOwned do
context 'in controllers' do
before do
- allow(subject).to receive(:in_controller?).and_return(true)
+ allow(cop).to receive(:in_controller?).and_return(true)
end
it_behaves_like 'defining feature category on a class'
@@ -39,7 +37,7 @@ RSpec.describe RuboCop::Cop::Gitlab::AvoidFeatureCategoryNotOwned do
context 'in workers' do
before do
- allow(subject).to receive(:in_worker?).and_return(true)
+ allow(cop).to receive(:in_worker?).and_return(true)
end
it_behaves_like 'defining feature category on a class'
@@ -47,7 +45,7 @@ RSpec.describe RuboCop::Cop::Gitlab::AvoidFeatureCategoryNotOwned do
context 'for grape endpoints' do
before do
- allow(subject).to receive(:in_api?).and_return(true)
+ allow(cop).to receive(:in_api?).and_return(true)
end
it_behaves_like 'defining feature category on a class'
diff --git a/spec/rubocop/cop/gitlab/avoid_uploaded_file_from_params_spec.rb b/spec/rubocop/cop/gitlab/avoid_uploaded_file_from_params_spec.rb
index bbdc6ca2470..09d5552d40c 100644
--- a/spec/rubocop/cop/gitlab/avoid_uploaded_file_from_params_spec.rb
+++ b/spec/rubocop/cop/gitlab/avoid_uploaded_file_from_params_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/gitlab/avoid_uploaded_file_from_params'
RSpec.describe RuboCop::Cop::Gitlab::AvoidUploadedFileFromParams do
- subject(:cop) { described_class.new }
-
context 'when using UploadedFile.from_params' do
it 'flags its call' do
expect_offense(<<~SOURCE)
diff --git a/spec/rubocop/cop/gitlab/bulk_insert_spec.rb b/spec/rubocop/cop/gitlab/bulk_insert_spec.rb
index 3cce93628fe..28fdd18b0f5 100644
--- a/spec/rubocop/cop/gitlab/bulk_insert_spec.rb
+++ b/spec/rubocop/cop/gitlab/bulk_insert_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/gitlab/bulk_insert'
RSpec.describe RuboCop::Cop::Gitlab::BulkInsert do
- subject(:cop) { described_class.new }
-
it 'flags the use of ApplicationRecord.legacy_bulk_insert' do
expect_offense(<<~SOURCE)
ApplicationRecord.legacy_bulk_insert('merge_request_diff_files', rows)
diff --git a/spec/rubocop/cop/gitlab/change_timezone_spec.rb b/spec/rubocop/cop/gitlab/change_timezone_spec.rb
index a3b5912e7e9..d5100cb662a 100644
--- a/spec/rubocop/cop/gitlab/change_timezone_spec.rb
+++ b/spec/rubocop/cop/gitlab/change_timezone_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/gitlab/change_timezone'
RSpec.describe RuboCop::Cop::Gitlab::ChangeTimezone do
- subject(:cop) { described_class.new }
-
context 'Time.zone=' do
it 'registers an offense with no 2nd argument' do
expect_offense(<<~PATTERN)
diff --git a/spec/rubocop/cop/gitlab/const_get_inherit_false_spec.rb b/spec/rubocop/cop/gitlab/const_get_inherit_false_spec.rb
index 1b13bcd4595..99cc9e0b469 100644
--- a/spec/rubocop/cop/gitlab/const_get_inherit_false_spec.rb
+++ b/spec/rubocop/cop/gitlab/const_get_inherit_false_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/gitlab/const_get_inherit_false'
RSpec.describe RuboCop::Cop::Gitlab::ConstGetInheritFalse do
- subject(:cop) { described_class.new }
-
context 'Object.const_get' do
it 'registers an offense with no 2nd argument and corrects' do
expect_offense(<<~PATTERN)
diff --git a/spec/rubocop/cop/gitlab/delegate_predicate_methods_spec.rb b/spec/rubocop/cop/gitlab/delegate_predicate_methods_spec.rb
index f910e8a7a54..1b497954aee 100644
--- a/spec/rubocop/cop/gitlab/delegate_predicate_methods_spec.rb
+++ b/spec/rubocop/cop/gitlab/delegate_predicate_methods_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/gitlab/delegate_predicate_methods'
RSpec.describe RuboCop::Cop::Gitlab::DelegatePredicateMethods do
- subject(:cop) { described_class.new }
-
it 'registers offense for single predicate method with allow_nil:true' do
expect_offense(<<~SOURCE)
delegate :is_foo?, :do_foo, to: :bar, allow_nil: true
diff --git a/spec/rubocop/cop/gitlab/deprecate_track_redis_hll_event_spec.rb b/spec/rubocop/cop/gitlab/deprecate_track_redis_hll_event_spec.rb
index a5370487794..eed30e11a98 100644
--- a/spec/rubocop/cop/gitlab/deprecate_track_redis_hll_event_spec.rb
+++ b/spec/rubocop/cop/gitlab/deprecate_track_redis_hll_event_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/gitlab/deprecate_track_redis_hll_event'
RSpec.describe RuboCop::Cop::Gitlab::DeprecateTrackRedisHLLEvent do
- subject(:cop) { described_class.new }
-
it 'does not flag the use of track_event' do
expect_no_offenses('track_event :show, name: "p_analytics_insights"')
end
diff --git a/spec/rubocop/cop/gitlab/duplicate_spec_location_spec.rb b/spec/rubocop/cop/gitlab/duplicate_spec_location_spec.rb
index 1a108d4cd41..9a1639806c8 100644
--- a/spec/rubocop/cop/gitlab/duplicate_spec_location_spec.rb
+++ b/spec/rubocop/cop/gitlab/duplicate_spec_location_spec.rb
@@ -5,8 +5,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/gitlab/duplicate_spec_location'
RSpec.describe RuboCop::Cop::Gitlab::DuplicateSpecLocation do
- subject(:cop) { described_class.new }
-
let(:rails_root) { '../../../../' }
def full_path(path)
diff --git a/spec/rubocop/cop/gitlab/event_store_subscriber_spec.rb b/spec/rubocop/cop/gitlab/event_store_subscriber_spec.rb
index 9fe28481565..7c692d5aad4 100644
--- a/spec/rubocop/cop/gitlab/event_store_subscriber_spec.rb
+++ b/spec/rubocop/cop/gitlab/event_store_subscriber_spec.rb
@@ -5,8 +5,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/gitlab/event_store_subscriber'
RSpec.describe RuboCop::Cop::Gitlab::EventStoreSubscriber do
- subject(:cop) { described_class.new }
-
context 'when an event store subscriber overrides #perform' do
it 'registers an offense' do
expect_offense(<<~WORKER)
diff --git a/spec/rubocop/cop/gitlab/except_spec.rb b/spec/rubocop/cop/gitlab/except_spec.rb
index 60359ffa8bb..47048b8f658 100644
--- a/spec/rubocop/cop/gitlab/except_spec.rb
+++ b/spec/rubocop/cop/gitlab/except_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/gitlab/except'
RSpec.describe RuboCop::Cop::Gitlab::Except do
- subject(:cop) { described_class.new }
-
it 'flags the use of Gitlab::SQL::Except.new' do
expect_offense(<<~SOURCE)
Gitlab::SQL::Except.new([foo])
diff --git a/spec/rubocop/cop/gitlab/feature_available_usage_spec.rb b/spec/rubocop/cop/gitlab/feature_available_usage_spec.rb
index 5b56800cc1c..30edd33a318 100644
--- a/spec/rubocop/cop/gitlab/feature_available_usage_spec.rb
+++ b/spec/rubocop/cop/gitlab/feature_available_usage_spec.rb
@@ -6,8 +6,6 @@ require 'rubocop/rspec/support'
require_relative '../../../../rubocop/cop/gitlab/feature_available_usage'
RSpec.describe RuboCop::Cop::Gitlab::FeatureAvailableUsage do
- subject(:cop) { described_class.new }
-
context 'no arguments given' do
it 'does not flag the use of Gitlab::Sourcegraph.feature_available? with no arguments' do
expect_no_offenses('Gitlab::Sourcegraph.feature_available?')
diff --git a/spec/rubocop/cop/gitlab/finder_with_find_by_spec.rb b/spec/rubocop/cop/gitlab/finder_with_find_by_spec.rb
index 29a93b96228..6e01ef1bdec 100644
--- a/spec/rubocop/cop/gitlab/finder_with_find_by_spec.rb
+++ b/spec/rubocop/cop/gitlab/finder_with_find_by_spec.rb
@@ -5,8 +5,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/gitlab/finder_with_find_by'
RSpec.describe RuboCop::Cop::Gitlab::FinderWithFindBy do
- subject(:cop) { described_class.new }
-
context 'when calling execute.find' do
it 'registers an offense and corrects' do
expect_offense(<<~CODE)
diff --git a/spec/rubocop/cop/gitlab/httparty_spec.rb b/spec/rubocop/cop/gitlab/httparty_spec.rb
index e1e72c11bd1..09204009d9b 100644
--- a/spec/rubocop/cop/gitlab/httparty_spec.rb
+++ b/spec/rubocop/cop/gitlab/httparty_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/gitlab/httparty'
RSpec.describe RuboCop::Cop::Gitlab::HTTParty do # rubocop:disable RSpec/FilePath
- subject(:cop) { described_class.new }
-
shared_examples('registering include offense') do
it 'registers an offense when the class includes HTTParty' do
expect_offense(source)
diff --git a/spec/rubocop/cop/gitlab/intersect_spec.rb b/spec/rubocop/cop/gitlab/intersect_spec.rb
index d2920c0b16b..c81dae9af97 100644
--- a/spec/rubocop/cop/gitlab/intersect_spec.rb
+++ b/spec/rubocop/cop/gitlab/intersect_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/gitlab/intersect'
RSpec.describe RuboCop::Cop::Gitlab::Intersect do
- subject(:cop) { described_class.new }
-
it 'flags the use of Gitlab::SQL::Intersect.new' do
expect_offense(<<~SOURCE)
Gitlab::SQL::Intersect.new([foo])
diff --git a/spec/rubocop/cop/gitlab/json_spec.rb b/spec/rubocop/cop/gitlab/json_spec.rb
index c56b78c5750..e4ec107747d 100644
--- a/spec/rubocop/cop/gitlab/json_spec.rb
+++ b/spec/rubocop/cop/gitlab/json_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/gitlab/json'
RSpec.describe RuboCop::Cop::Gitlab::Json do
- subject(:cop) { described_class.new }
-
context 'when ::JSON is called' do
it 'registers an offense' do
expect_offense(<<~RUBY)
diff --git a/spec/rubocop/cop/gitlab/mark_used_feature_flags_spec.rb b/spec/rubocop/cop/gitlab/mark_used_feature_flags_spec.rb
index 515620bd820..ac7e41dda44 100644
--- a/spec/rubocop/cop/gitlab/mark_used_feature_flags_spec.rb
+++ b/spec/rubocop/cop/gitlab/mark_used_feature_flags_spec.rb
@@ -10,8 +10,6 @@ RSpec.describe RuboCop::Cop::Gitlab::MarkUsedFeatureFlags do
%w[a_feature_flag foo_hello foo_world baz_experiment_percentage bar_baz]
end
- subject(:cop) { described_class.new }
-
before do
allow(cop).to receive(:defined_feature_flags).and_return(defined_feature_flags)
allow(cop).to receive(:usage_data_counters_known_event_feature_flags).and_return([])
diff --git a/spec/rubocop/cop/gitlab/module_with_instance_variables_spec.rb b/spec/rubocop/cop/gitlab/module_with_instance_variables_spec.rb
index bf8409534f7..9f1691696eb 100644
--- a/spec/rubocop/cop/gitlab/module_with_instance_variables_spec.rb
+++ b/spec/rubocop/cop/gitlab/module_with_instance_variables_spec.rb
@@ -6,8 +6,6 @@ require_relative '../../../../rubocop/cop/gitlab/module_with_instance_variables'
RSpec.describe RuboCop::Cop::Gitlab::ModuleWithInstanceVariables do
let(:msg) { "Do not use instance variables in a module. [...]" }
- subject(:cop) { described_class.new }
-
shared_examples('registering offense') do
it 'registers an offense when instance variable is used in a module' do
expect_offense(source)
diff --git a/spec/rubocop/cop/gitlab/namespaced_class_spec.rb b/spec/rubocop/cop/gitlab/namespaced_class_spec.rb
index f868a259f81..b16c3aba5c7 100644
--- a/spec/rubocop/cop/gitlab/namespaced_class_spec.rb
+++ b/spec/rubocop/cop/gitlab/namespaced_class_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/gitlab/namespaced_class'
RSpec.describe RuboCop::Cop::Gitlab::NamespacedClass do
- subject(:cop) { described_class.new }
-
shared_examples 'enforces namespaced classes' do
def namespaced(code)
return code unless namespace
diff --git a/spec/rubocop/cop/gitlab/policy_rule_boolean_spec.rb b/spec/rubocop/cop/gitlab/policy_rule_boolean_spec.rb
index ae50a1fa676..d00a9861c77 100644
--- a/spec/rubocop/cop/gitlab/policy_rule_boolean_spec.rb
+++ b/spec/rubocop/cop/gitlab/policy_rule_boolean_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/gitlab/policy_rule_boolean'
RSpec.describe RuboCop::Cop::Gitlab::PolicyRuleBoolean do
- subject(:cop) { described_class.new }
-
it 'registers offense for &&' do
expect_offense(<<~SOURCE)
rule { conducts_electricity && batteries }.enable :light_bulb
diff --git a/spec/rubocop/cop/gitlab/predicate_memoization_spec.rb b/spec/rubocop/cop/gitlab/predicate_memoization_spec.rb
index 40c2c30284f..1ca34ad90da 100644
--- a/spec/rubocop/cop/gitlab/predicate_memoization_spec.rb
+++ b/spec/rubocop/cop/gitlab/predicate_memoization_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/gitlab/predicate_memoization'
RSpec.describe RuboCop::Cop::Gitlab::PredicateMemoization do
- subject(:cop) { described_class.new }
-
shared_examples('not registering offense') do
it 'does not register offenses' do
expect_no_offenses(source)
diff --git a/spec/rubocop/cop/gitlab/rails_logger_spec.rb b/spec/rubocop/cop/gitlab/rails_logger_spec.rb
index ab47406d055..c9d361b49b8 100644
--- a/spec/rubocop/cop/gitlab/rails_logger_spec.rb
+++ b/spec/rubocop/cop/gitlab/rails_logger_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/gitlab/rails_logger'
RSpec.describe RuboCop::Cop::Gitlab::RailsLogger do
- subject(:cop) { described_class.new }
-
described_class::LOG_METHODS.each do |method|
it "flags the use of Rails.logger.#{method} with a constant receiver" do
node = "Rails.logger.#{method}('some error')"
diff --git a/spec/rubocop/cop/gitlab/union_spec.rb b/spec/rubocop/cop/gitlab/union_spec.rb
index d8080e8298b..4042fe0263a 100644
--- a/spec/rubocop/cop/gitlab/union_spec.rb
+++ b/spec/rubocop/cop/gitlab/union_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/gitlab/union'
RSpec.describe RuboCop::Cop::Gitlab::Union do
- subject(:cop) { described_class.new }
-
it 'flags the use of Gitlab::SQL::Union.new' do
expect_offense(<<~SOURCE)
Gitlab::SQL::Union.new([foo])
diff --git a/spec/rubocop/cop/graphql/authorize_types_spec.rb b/spec/rubocop/cop/graphql/authorize_types_spec.rb
index 3ea4d3e4a4d..a30cd5a1688 100644
--- a/spec/rubocop/cop/graphql/authorize_types_spec.rb
+++ b/spec/rubocop/cop/graphql/authorize_types_spec.rb
@@ -5,8 +5,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/graphql/authorize_types'
RSpec.describe RuboCop::Cop::Graphql::AuthorizeTypes do
- subject(:cop) { described_class.new }
-
it 'adds an offense when there is no authorize call' do
expect_offense(<<~TYPE)
module Types
diff --git a/spec/rubocop/cop/graphql/descriptions_spec.rb b/spec/rubocop/cop/graphql/descriptions_spec.rb
index f4fd78c846d..8826e700fdf 100644
--- a/spec/rubocop/cop/graphql/descriptions_spec.rb
+++ b/spec/rubocop/cop/graphql/descriptions_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/graphql/descriptions'
RSpec.describe RuboCop::Cop::Graphql::Descriptions do
- subject(:cop) { described_class.new }
-
context 'with fields' do
it 'adds an offense when there is no description' do
expect_offense(<<~TYPE)
diff --git a/spec/rubocop/cop/graphql/gid_expected_type_spec.rb b/spec/rubocop/cop/graphql/gid_expected_type_spec.rb
index c6cd3ba0913..563c16a99df 100644
--- a/spec/rubocop/cop/graphql/gid_expected_type_spec.rb
+++ b/spec/rubocop/cop/graphql/gid_expected_type_spec.rb
@@ -5,8 +5,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/graphql/gid_expected_type'
RSpec.describe RuboCop::Cop::Graphql::GIDExpectedType do
- subject(:cop) { described_class.new }
-
it 'adds an offense when there is no expected_type parameter' do
expect_offense(<<~TYPE)
GitlabSchema.object_from_id(received_id)
diff --git a/spec/rubocop/cop/graphql/graphql_name_position_spec.rb b/spec/rubocop/cop/graphql/graphql_name_position_spec.rb
index 7bbbbed6e05..5db6fe6a801 100644
--- a/spec/rubocop/cop/graphql/graphql_name_position_spec.rb
+++ b/spec/rubocop/cop/graphql/graphql_name_position_spec.rb
@@ -5,8 +5,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/graphql/graphql_name_position'
RSpec.describe RuboCop::Cop::Graphql::GraphqlNamePosition do
- subject(:cop) { described_class.new }
-
it 'adds an offense when graphql_name is not on the first line' do
expect_offense(<<~TYPE)
module Types
diff --git a/spec/rubocop/cop/graphql/id_type_spec.rb b/spec/rubocop/cop/graphql/id_type_spec.rb
index fcd64561fe4..3a56753d39e 100644
--- a/spec/rubocop/cop/graphql/id_type_spec.rb
+++ b/spec/rubocop/cop/graphql/id_type_spec.rb
@@ -5,8 +5,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/graphql/id_type'
RSpec.describe RuboCop::Cop::Graphql::IDType do
- subject(:cop) { described_class.new }
-
it 'adds an offense when GraphQL::Types::ID is used as a param to #argument' do
expect_offense(<<~TYPE)
argument :some_arg, GraphQL::Types::ID, some: other, params: do_not_matter
diff --git a/spec/rubocop/cop/graphql/json_type_spec.rb b/spec/rubocop/cop/graphql/json_type_spec.rb
index d048fc4178b..c72e5b5b1c9 100644
--- a/spec/rubocop/cop/graphql/json_type_spec.rb
+++ b/spec/rubocop/cop/graphql/json_type_spec.rb
@@ -8,8 +8,6 @@ RSpec.describe RuboCop::Cop::Graphql::JSONType do
'Avoid using GraphQL::Types::JSON. See: https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#json'
end
- subject(:cop) { described_class.new }
-
context 'fields' do
it 'adds an offense when GraphQL::Types::JSON is used' do
expect_offense(<<~RUBY)
diff --git a/spec/rubocop/cop/graphql/old_types_spec.rb b/spec/rubocop/cop/graphql/old_types_spec.rb
index cb3d0087cbe..45d47f3b516 100644
--- a/spec/rubocop/cop/graphql/old_types_spec.rb
+++ b/spec/rubocop/cop/graphql/old_types_spec.rb
@@ -7,8 +7,6 @@ require_relative '../../../../rubocop/cop/graphql/old_types'
RSpec.describe RuboCop::Cop::Graphql::OldTypes do
using RSpec::Parameterized::TableSyntax
- subject(:cop) { described_class.new }
-
where(:old_type, :message) do
'GraphQL::ID_TYPE' | 'Avoid using GraphQL::ID_TYPE. Use GraphQL::Types::ID instead'
'GraphQL::INT_TYPE' | 'Avoid using GraphQL::INT_TYPE. Use GraphQL::Types::Int instead'
diff --git a/spec/rubocop/cop/graphql/resolver_type_spec.rb b/spec/rubocop/cop/graphql/resolver_type_spec.rb
index 7b5213fdb3d..ade1bfc2cca 100644
--- a/spec/rubocop/cop/graphql/resolver_type_spec.rb
+++ b/spec/rubocop/cop/graphql/resolver_type_spec.rb
@@ -5,8 +5,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/graphql/resolver_type'
RSpec.describe RuboCop::Cop::Graphql::ResolverType do
- subject(:cop) { described_class.new }
-
it 'adds an offense when there is no type annotation' do
expect_offense(<<~SRC)
module Resolvers
diff --git a/spec/rubocop/cop/group_public_or_visible_to_user_spec.rb b/spec/rubocop/cop/group_public_or_visible_to_user_spec.rb
index b51c3d94aaa..c948ea606b8 100644
--- a/spec/rubocop/cop/group_public_or_visible_to_user_spec.rb
+++ b/spec/rubocop/cop/group_public_or_visible_to_user_spec.rb
@@ -9,8 +9,6 @@ RSpec.describe RuboCop::Cop::GroupPublicOrVisibleToUser do
"Please ensure that you are not using it on its own and that the amount of rows being filtered is reasonable."
end
- subject(:cop) { described_class.new }
-
it 'flags the use of Group.public_or_visible_to_user with a constant receiver' do
expect_offense(<<~CODE)
Group.public_or_visible_to_user
diff --git a/spec/rubocop/cop/ignored_columns_spec.rb b/spec/rubocop/cop/ignored_columns_spec.rb
index 7c4f9c13856..c6c44399624 100644
--- a/spec/rubocop/cop/ignored_columns_spec.rb
+++ b/spec/rubocop/cop/ignored_columns_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../rubocop/cop/ignored_columns'
RSpec.describe RuboCop::Cop::IgnoredColumns do
- subject(:cop) { described_class.new }
-
it 'flags direct use of ignored_columns instead of the IgnoredColumns concern' do
expect_offense(<<~RUBY)
class Foo < ApplicationRecord
diff --git a/spec/rubocop/cop/include_sidekiq_worker_spec.rb b/spec/rubocop/cop/include_sidekiq_worker_spec.rb
index bbb5232a1b4..f86bb1427db 100644
--- a/spec/rubocop/cop/include_sidekiq_worker_spec.rb
+++ b/spec/rubocop/cop/include_sidekiq_worker_spec.rb
@@ -5,8 +5,6 @@ require 'rubocop_spec_helper'
require_relative '../../../rubocop/cop/include_sidekiq_worker'
RSpec.describe RuboCop::Cop::IncludeSidekiqWorker do
- subject(:cop) { described_class.new }
-
context 'when `Sidekiq::Worker` is included' do
it 'registers an offense and corrects', :aggregate_failures do
expect_offense(<<~CODE)
diff --git a/spec/rubocop/cop/inject_enterprise_edition_module_spec.rb b/spec/rubocop/cop/inject_enterprise_edition_module_spec.rb
index 91ef2532e99..3063a474bd7 100644
--- a/spec/rubocop/cop/inject_enterprise_edition_module_spec.rb
+++ b/spec/rubocop/cop/inject_enterprise_edition_module_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../rubocop/cop/inject_enterprise_edition_module'
RSpec.describe RuboCop::Cop::InjectEnterpriseEditionModule do
- subject(:cop) { described_class.new }
-
it 'flags the use of `prepend_mod_with` in the middle of a file' do
expect_offense(<<~SOURCE)
class Foo
diff --git a/spec/rubocop/cop/lint/last_keyword_argument_spec.rb b/spec/rubocop/cop/lint/last_keyword_argument_spec.rb
index c2f3706cdb1..b0551a79c50 100644
--- a/spec/rubocop/cop/lint/last_keyword_argument_spec.rb
+++ b/spec/rubocop/cop/lint/last_keyword_argument_spec.rb
@@ -4,16 +4,15 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/lint/last_keyword_argument'
RSpec.describe RuboCop::Cop::Lint::LastKeywordArgument do
- subject(:cop) { described_class.new }
-
before do
described_class.instance_variable_set(:@keyword_warnings, nil)
+ allow(Dir).to receive(:glob).and_call_original
+ allow(File).to receive(:read).and_call_original
end
context 'deprecation files does not exist' do
before do
- allow(Dir).to receive(:glob).and_return([])
- allow(File).to receive(:exist?).and_return(false)
+ allow(Dir).to receive(:glob).with(described_class::DEPRECATIONS_GLOB).and_return([])
end
it 'does not register an offense' do
@@ -58,7 +57,8 @@ RSpec.describe RuboCop::Cop::Lint::LastKeywordArgument do
before do
allow(Dir).to receive(:glob).and_return(['deprecations/service/create_spec.yml', 'deprecations/api/projects_spec.yml'])
- allow(File).to receive(:read).and_return(create_spec_yaml, projects_spec_yaml)
+ allow(File).to receive(:read).with('deprecations/service/create_spec.yml').and_return(create_spec_yaml)
+ allow(File).to receive(:read).with('deprecations/api/projects_spec.yml').and_return(projects_spec_yaml)
end
it 'registers an offense for last keyword warning' do
diff --git a/spec/rubocop/cop/migration/add_concurrent_index_spec.rb b/spec/rubocop/cop/migration/add_concurrent_index_spec.rb
index 6344cbb3b5a..185b64b0334 100644
--- a/spec/rubocop/cop/migration/add_concurrent_index_spec.rb
+++ b/spec/rubocop/cop/migration/add_concurrent_index_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/migration/add_concurrent_index'
RSpec.describe RuboCop::Cop::Migration::AddConcurrentIndex do
- subject(:cop) { described_class.new }
-
context 'when in migration' do
before do
allow(cop).to receive(:in_migration?).and_return(true)
diff --git a/spec/rubocop/cop/migration/add_index_spec.rb b/spec/rubocop/cop/migration/add_index_spec.rb
index 595cb31e14e..338dbf73a3a 100644
--- a/spec/rubocop/cop/migration/add_index_spec.rb
+++ b/spec/rubocop/cop/migration/add_index_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/migration/add_index'
RSpec.describe RuboCop::Cop::Migration::AddIndex do
- subject(:cop) { described_class.new }
-
context 'in migration' do
before do
allow(cop).to receive(:in_migration?).and_return(true)
diff --git a/spec/rubocop/cop/migration/add_limit_to_text_columns_spec.rb b/spec/rubocop/cop/migration/add_limit_to_text_columns_spec.rb
index 78db7938fa3..85a86a27c48 100644
--- a/spec/rubocop/cop/migration/add_limit_to_text_columns_spec.rb
+++ b/spec/rubocop/cop/migration/add_limit_to_text_columns_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/migration/add_limit_to_text_columns'
RSpec.describe RuboCop::Cop::Migration::AddLimitToTextColumns do
- subject(:cop) { described_class.new }
-
context 'when in migration' do
let(:msg) { 'Text columns should always have a limit set (255 is suggested)[...]' }
diff --git a/spec/rubocop/cop/migration/add_timestamps_spec.rb b/spec/rubocop/cop/migration/add_timestamps_spec.rb
index 593a0b00f07..fcc2f4aa363 100644
--- a/spec/rubocop/cop/migration/add_timestamps_spec.rb
+++ b/spec/rubocop/cop/migration/add_timestamps_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/migration/add_timestamps'
RSpec.describe RuboCop::Cop::Migration::AddTimestamps do
- subject(:cop) { described_class.new }
-
let(:migration_with_add_timestamps) do
%q(
class Users < ActiveRecord::Migration[4.2]
diff --git a/spec/rubocop/cop/migration/background_migration_base_class_spec.rb b/spec/rubocop/cop/migration/background_migration_base_class_spec.rb
index 140820e84bd..8cc85ac692c 100644
--- a/spec/rubocop/cop/migration/background_migration_base_class_spec.rb
+++ b/spec/rubocop/cop/migration/background_migration_base_class_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/migration/background_migration_base_class'
RSpec.describe RuboCop::Cop::Migration::BackgroundMigrationBaseClass do
- subject(:cop) { described_class.new }
-
context 'when the migration class inherits from BatchedMigrationJob' do
it 'does not register any offenses' do
expect_no_offenses(<<~RUBY)
diff --git a/spec/rubocop/cop/migration/background_migration_record_spec.rb b/spec/rubocop/cop/migration/background_migration_record_spec.rb
index 9e482293b93..d5a451e00c9 100644
--- a/spec/rubocop/cop/migration/background_migration_record_spec.rb
+++ b/spec/rubocop/cop/migration/background_migration_record_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/migration/background_migration_record'
RSpec.describe RuboCop::Cop::Migration::BackgroundMigrationRecord do
- subject(:cop) { described_class.new }
-
context 'outside of a migration' do
it 'does not register any offenses' do
expect_no_offenses(<<~SOURCE)
diff --git a/spec/rubocop/cop/migration/complex_indexes_require_name_spec.rb b/spec/rubocop/cop/migration/complex_indexes_require_name_spec.rb
index 4ffe9b17011..7329d399330 100644
--- a/spec/rubocop/cop/migration/complex_indexes_require_name_spec.rb
+++ b/spec/rubocop/cop/migration/complex_indexes_require_name_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/migration/complex_indexes_require_name'
RSpec.describe RuboCop::Cop::Migration::ComplexIndexesRequireName do
- subject(:cop) { described_class.new }
-
context 'when in migration' do
let(:msg) { 'indexes added with custom options must be explicitly named' }
diff --git a/spec/rubocop/cop/migration/datetime_spec.rb b/spec/rubocop/cop/migration/datetime_spec.rb
index b8ec8674b56..400abe3be70 100644
--- a/spec/rubocop/cop/migration/datetime_spec.rb
+++ b/spec/rubocop/cop/migration/datetime_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/migration/datetime'
RSpec.describe RuboCop::Cop::Migration::Datetime do
- subject(:cop) { described_class.new }
-
let(:create_table_migration_without_datetime) do
%q(
class Users < ActiveRecord::Migration[6.0]
diff --git a/spec/rubocop/cop/migration/drop_table_spec.rb b/spec/rubocop/cop/migration/drop_table_spec.rb
index d172b0c5bb0..dd5f93eaafc 100644
--- a/spec/rubocop/cop/migration/drop_table_spec.rb
+++ b/spec/rubocop/cop/migration/drop_table_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/migration/drop_table'
RSpec.describe RuboCop::Cop::Migration::DropTable do
- subject(:cop) { described_class.new }
-
context 'when in deployment migration' do
let(:msg) do
'`drop_table` in deployment migrations requires downtime. Drop tables in post-deployment migrations instead.'
diff --git a/spec/rubocop/cop/migration/migration_record_spec.rb b/spec/rubocop/cop/migration/migration_record_spec.rb
index e941b8f8a87..96a1d8fa107 100644
--- a/spec/rubocop/cop/migration/migration_record_spec.rb
+++ b/spec/rubocop/cop/migration/migration_record_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/migration/migration_record'
RSpec.describe RuboCop::Cop::Migration::MigrationRecord do
- subject(:cop) { described_class.new }
-
shared_examples 'a disabled cop' do |klass|
it 'does not register any offenses' do
expect_no_offenses(<<~SOURCE)
diff --git a/spec/rubocop/cop/migration/prevent_global_enable_lock_retries_with_disable_ddl_transaction_spec.rb b/spec/rubocop/cop/migration/prevent_global_enable_lock_retries_with_disable_ddl_transaction_spec.rb
index 7afecfd39b2..1035ed2fb4a 100644
--- a/spec/rubocop/cop/migration/prevent_global_enable_lock_retries_with_disable_ddl_transaction_spec.rb
+++ b/spec/rubocop/cop/migration/prevent_global_enable_lock_retries_with_disable_ddl_transaction_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/migration/prevent_global_enable_lock_retries_with_disable_ddl_transaction'
RSpec.describe RuboCop::Cop::Migration::PreventGlobalEnableLockRetriesWithDisableDdlTransaction do
- subject(:cop) { described_class.new }
-
context 'when in migration' do
before do
allow(cop).to receive(:in_migration?).and_return(true)
diff --git a/spec/rubocop/cop/migration/prevent_index_creation_spec.rb b/spec/rubocop/cop/migration/prevent_index_creation_spec.rb
index 54393e69cf2..9d886467a48 100644
--- a/spec/rubocop/cop/migration/prevent_index_creation_spec.rb
+++ b/spec/rubocop/cop/migration/prevent_index_creation_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/migration/prevent_index_creation'
RSpec.describe RuboCop::Cop::Migration::PreventIndexCreation do
- subject(:cop) { described_class.new }
-
let(:forbidden_tables) { %w(ci_builds) }
let(:forbidden_tables_list) { forbidden_tables.join(', ') }
diff --git a/spec/rubocop/cop/migration/prevent_strings_spec.rb b/spec/rubocop/cop/migration/prevent_strings_spec.rb
index 6f5d1ca4368..f1adeae6786 100644
--- a/spec/rubocop/cop/migration/prevent_strings_spec.rb
+++ b/spec/rubocop/cop/migration/prevent_strings_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/migration/prevent_strings'
RSpec.describe RuboCop::Cop::Migration::PreventStrings do
- subject(:cop) { described_class.new }
-
context 'when in migration' do
before do
allow(cop).to receive(:in_migration?).and_return(true)
diff --git a/spec/rubocop/cop/migration/refer_to_index_by_name_spec.rb b/spec/rubocop/cop/migration/refer_to_index_by_name_spec.rb
index 18d5353ce46..acdc6843584 100644
--- a/spec/rubocop/cop/migration/refer_to_index_by_name_spec.rb
+++ b/spec/rubocop/cop/migration/refer_to_index_by_name_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/migration/refer_to_index_by_name'
RSpec.describe RuboCop::Cop::Migration::ReferToIndexByName do
- subject(:cop) { described_class.new }
-
context 'when in migration' do
before do
allow(cop).to receive(:in_migration?).and_return(true)
diff --git a/spec/rubocop/cop/migration/remove_column_spec.rb b/spec/rubocop/cop/migration/remove_column_spec.rb
index 89edb3b420e..4aa842969fe 100644
--- a/spec/rubocop/cop/migration/remove_column_spec.rb
+++ b/spec/rubocop/cop/migration/remove_column_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/migration/remove_column'
RSpec.describe RuboCop::Cop::Migration::RemoveColumn do
- subject(:cop) { described_class.new }
-
def source(meth = 'change')
"def #{meth}; remove_column :table, :column; end"
end
diff --git a/spec/rubocop/cop/migration/remove_concurrent_index_spec.rb b/spec/rubocop/cop/migration/remove_concurrent_index_spec.rb
index 86bd3a2edea..1d59390d659 100644
--- a/spec/rubocop/cop/migration/remove_concurrent_index_spec.rb
+++ b/spec/rubocop/cop/migration/remove_concurrent_index_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/migration/remove_concurrent_index'
RSpec.describe RuboCop::Cop::Migration::RemoveConcurrentIndex do
- subject(:cop) { described_class.new }
-
context 'in migration' do
before do
allow(cop).to receive(:in_migration?).and_return(true)
diff --git a/spec/rubocop/cop/migration/remove_index_spec.rb b/spec/rubocop/cop/migration/remove_index_spec.rb
index bc8571b7e4d..24823b47d53 100644
--- a/spec/rubocop/cop/migration/remove_index_spec.rb
+++ b/spec/rubocop/cop/migration/remove_index_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/migration/remove_index'
RSpec.describe RuboCop::Cop::Migration::RemoveIndex do
- subject(:cop) { described_class.new }
-
context 'when in migration' do
before do
allow(cop).to receive(:in_migration?).and_return(true)
diff --git a/spec/rubocop/cop/migration/safer_boolean_column_spec.rb b/spec/rubocop/cop/migration/safer_boolean_column_spec.rb
index ef9bfb20cc8..2050051cac7 100644
--- a/spec/rubocop/cop/migration/safer_boolean_column_spec.rb
+++ b/spec/rubocop/cop/migration/safer_boolean_column_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/migration/safer_boolean_column'
RSpec.describe RuboCop::Cop::Migration::SaferBooleanColumn do
- subject(:cop) { described_class.new }
-
context 'in migration' do
before do
allow(cop).to receive(:in_migration?).and_return(true)
diff --git a/spec/rubocop/cop/migration/sidekiq_queue_migrate_spec.rb b/spec/rubocop/cop/migration/sidekiq_queue_migrate_spec.rb
index 7f451fb7b28..46c460b5d49 100644
--- a/spec/rubocop/cop/migration/sidekiq_queue_migrate_spec.rb
+++ b/spec/rubocop/cop/migration/sidekiq_queue_migrate_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/migration/sidekiq_queue_migrate'
RSpec.describe RuboCop::Cop::Migration::SidekiqQueueMigrate do
- subject(:cop) { described_class.new }
-
def source(meth = 'change')
"def #{meth}; sidekiq_queue_migrate 'queue', to: 'new_queue'; end"
end
diff --git a/spec/rubocop/cop/migration/timestamps_spec.rb b/spec/rubocop/cop/migration/timestamps_spec.rb
index 5508e0f564e..706fd8a3d0f 100644
--- a/spec/rubocop/cop/migration/timestamps_spec.rb
+++ b/spec/rubocop/cop/migration/timestamps_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/migration/timestamps'
RSpec.describe RuboCop::Cop::Migration::Timestamps do
- subject(:cop) { described_class.new }
-
let(:migration_with_timestamps) do
%q(
class Users < ActiveRecord::Migration[4.2]
diff --git a/spec/rubocop/cop/migration/versioned_migration_class_spec.rb b/spec/rubocop/cop/migration/versioned_migration_class_spec.rb
index 0ede5439069..b44f5d64a62 100644
--- a/spec/rubocop/cop/migration/versioned_migration_class_spec.rb
+++ b/spec/rubocop/cop/migration/versioned_migration_class_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/migration/versioned_migration_class'
RSpec.describe RuboCop::Cop::Migration::VersionedMigrationClass do
- subject(:cop) { described_class.new }
-
let(:migration) do
<<~SOURCE
class TestMigration < Gitlab::Database::Migration[1.0]
diff --git a/spec/rubocop/cop/migration/with_lock_retries_disallowed_method_spec.rb b/spec/rubocop/cop/migration/with_lock_retries_disallowed_method_spec.rb
index 67e45ac06e0..5762f78820c 100644
--- a/spec/rubocop/cop/migration/with_lock_retries_disallowed_method_spec.rb
+++ b/spec/rubocop/cop/migration/with_lock_retries_disallowed_method_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/migration/with_lock_retries_disallowed_method'
RSpec.describe RuboCop::Cop::Migration::WithLockRetriesDisallowedMethod do
- subject(:cop) { described_class.new }
-
context 'when in migration' do
before do
allow(cop).to receive(:in_migration?).and_return(true)
diff --git a/spec/rubocop/cop/migration/with_lock_retries_with_change_spec.rb b/spec/rubocop/cop/migration/with_lock_retries_with_change_spec.rb
index fc9f8a14e3f..fed9176ea97 100644
--- a/spec/rubocop/cop/migration/with_lock_retries_with_change_spec.rb
+++ b/spec/rubocop/cop/migration/with_lock_retries_with_change_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/migration/with_lock_retries_with_change'
RSpec.describe RuboCop::Cop::Migration::WithLockRetriesWithChange do
- subject(:cop) { described_class.new }
-
context 'when in migration' do
before do
allow(cop).to receive(:in_migration?).and_return(true)
diff --git a/spec/rubocop/cop/performance/active_record_subtransaction_methods_spec.rb b/spec/rubocop/cop/performance/active_record_subtransaction_methods_spec.rb
index 1394dfe7f18..ac58ca1edf3 100644
--- a/spec/rubocop/cop/performance/active_record_subtransaction_methods_spec.rb
+++ b/spec/rubocop/cop/performance/active_record_subtransaction_methods_spec.rb
@@ -6,8 +6,6 @@ require 'rspec-parameterized'
require_relative '../../../../rubocop/cop/performance/active_record_subtransaction_methods'
RSpec.describe RuboCop::Cop::Performance::ActiveRecordSubtransactionMethods do
- subject(:cop) { described_class.new }
-
let(:message) { described_class::MSG }
shared_examples 'a method that uses a subtransaction' do |method_name|
diff --git a/spec/rubocop/cop/performance/active_record_subtransactions_spec.rb b/spec/rubocop/cop/performance/active_record_subtransactions_spec.rb
index 55889654272..e839a3e9367 100644
--- a/spec/rubocop/cop/performance/active_record_subtransactions_spec.rb
+++ b/spec/rubocop/cop/performance/active_record_subtransactions_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/performance/active_record_subtransactions'
RSpec.describe RuboCop::Cop::Performance::ActiveRecordSubtransactions do
- subject(:cop) { described_class.new }
-
let(:message) { described_class::MSG }
context 'when calling #transaction with only requires_new: true' do
diff --git a/spec/rubocop/cop/performance/ar_count_each_spec.rb b/spec/rubocop/cop/performance/ar_count_each_spec.rb
index e37a306efbb..a86b3f2b983 100644
--- a/spec/rubocop/cop/performance/ar_count_each_spec.rb
+++ b/spec/rubocop/cop/performance/ar_count_each_spec.rb
@@ -4,11 +4,9 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/performance/ar_count_each'
RSpec.describe RuboCop::Cop::Performance::ARCountEach do
- subject(:cop) { described_class.new }
-
context 'when it is not haml file' do
it 'does not flag it as an offense' do
- expect(subject).to receive(:in_haml_file?).with(anything).at_least(:once).and_return(false)
+ expect(cop).to receive(:in_haml_file?).with(anything).at_least(:once).and_return(false)
expect_no_offenses <<~SOURCE
show(@users.count)
@@ -19,7 +17,7 @@ RSpec.describe RuboCop::Cop::Performance::ARCountEach do
context 'when it is haml file' do
before do
- expect(subject).to receive(:in_haml_file?).with(anything).at_least(:once).and_return(true)
+ expect(cop).to receive(:in_haml_file?).with(anything).at_least(:once).and_return(true)
end
context 'when the same object uses count and each' do
diff --git a/spec/rubocop/cop/performance/ar_exists_and_present_blank_spec.rb b/spec/rubocop/cop/performance/ar_exists_and_present_blank_spec.rb
index 4a2e62623a4..070e792eeec 100644
--- a/spec/rubocop/cop/performance/ar_exists_and_present_blank_spec.rb
+++ b/spec/rubocop/cop/performance/ar_exists_and_present_blank_spec.rb
@@ -4,11 +4,9 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/performance/ar_exists_and_present_blank'
RSpec.describe RuboCop::Cop::Performance::ARExistsAndPresentBlank do
- subject(:cop) { described_class.new }
-
context 'when it is not haml file' do
it 'does not flag it as an offense' do
- expect(subject).to receive(:in_haml_file?).with(anything).at_least(:once).and_return(false)
+ expect(cop).to receive(:in_haml_file?).with(anything).at_least(:once).and_return(false)
expect_no_offenses <<~SOURCE
return unless @users.exists?
@@ -19,7 +17,7 @@ RSpec.describe RuboCop::Cop::Performance::ARExistsAndPresentBlank do
context 'when it is haml file' do
before do
- expect(subject).to receive(:in_haml_file?).with(anything).at_least(:once).and_return(true)
+ expect(cop).to receive(:in_haml_file?).with(anything).at_least(:once).and_return(true)
end
context 'the same object uses exists? and present?' do
diff --git a/spec/rubocop/cop/performance/readlines_each_spec.rb b/spec/rubocop/cop/performance/readlines_each_spec.rb
index 16421bcdaac..d876cbf79a5 100644
--- a/spec/rubocop/cop/performance/readlines_each_spec.rb
+++ b/spec/rubocop/cop/performance/readlines_each_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/performance/readlines_each'
RSpec.describe RuboCop::Cop::Performance::ReadlinesEach do
- subject(:cop) { described_class.new }
-
let(:message) { 'Avoid `IO.readlines.each`, since it reads contents into memory in full. Use `IO.each_line` or `IO.each` instead.' }
shared_examples_for(:class_read) do |klass|
diff --git a/spec/rubocop/cop/prefer_class_methods_over_module_spec.rb b/spec/rubocop/cop/prefer_class_methods_over_module_spec.rb
index 455d08951bd..a2a4270c48e 100644
--- a/spec/rubocop/cop/prefer_class_methods_over_module_spec.rb
+++ b/spec/rubocop/cop/prefer_class_methods_over_module_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../rubocop/cop/prefer_class_methods_over_module'
RSpec.describe RuboCop::Cop::PreferClassMethodsOverModule do
- subject(:cop) { described_class.new }
-
it 'flags violation when using module ClassMethods and corrects', :aggregate_failures do
expect_offense(<<~RUBY)
module Foo
diff --git a/spec/rubocop/cop/project_path_helper_spec.rb b/spec/rubocop/cop/project_path_helper_spec.rb
index d8e66489e3c..3153c928c77 100644
--- a/spec/rubocop/cop/project_path_helper_spec.rb
+++ b/spec/rubocop/cop/project_path_helper_spec.rb
@@ -5,8 +5,6 @@ require 'rubocop_spec_helper'
require_relative '../../../rubocop/cop/project_path_helper'
RSpec.describe RuboCop::Cop::ProjectPathHelper do
- subject(:cop) { described_class.new }
-
context "when using namespace_project with the project's namespace" do
let(:source) { 'edit_namespace_project_issue_path(@issue.project.namespace, @issue.project, @issue)' }
let(:correct_source) { 'edit_project_issue_path(@issue.project, @issue)' }
diff --git a/spec/rubocop/cop/put_group_routes_under_scope_spec.rb b/spec/rubocop/cop/put_group_routes_under_scope_spec.rb
index a68cb30ac91..8697345cddc 100644
--- a/spec/rubocop/cop/put_group_routes_under_scope_spec.rb
+++ b/spec/rubocop/cop/put_group_routes_under_scope_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../rubocop/cop/put_group_routes_under_scope'
RSpec.describe RuboCop::Cop::PutGroupRoutesUnderScope do
- subject(:cop) { described_class.new }
-
%w[resource resources get post put patch delete].each do |route_method|
it "registers an offense when route is outside scope for `#{route_method}`" do
offense = "#{route_method} :notes"
diff --git a/spec/rubocop/cop/put_project_routes_under_scope_spec.rb b/spec/rubocop/cop/put_project_routes_under_scope_spec.rb
index 82cafbeb73c..65d330b0f05 100644
--- a/spec/rubocop/cop/put_project_routes_under_scope_spec.rb
+++ b/spec/rubocop/cop/put_project_routes_under_scope_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../rubocop/cop/put_project_routes_under_scope'
RSpec.describe RuboCop::Cop::PutProjectRoutesUnderScope do
- subject(:cop) { described_class.new }
-
%w[resource resources get post put patch delete].each do |route_method|
it "registers an offense when route is outside scope for `#{route_method}`" do
offense = "#{route_method} :notes"
diff --git a/spec/rubocop/cop/qa/ambiguous_page_object_name_spec.rb b/spec/rubocop/cop/qa/ambiguous_page_object_name_spec.rb
index dd03c531b36..ab270090c7d 100644
--- a/spec/rubocop/cop/qa/ambiguous_page_object_name_spec.rb
+++ b/spec/rubocop/cop/qa/ambiguous_page_object_name_spec.rb
@@ -7,8 +7,6 @@ require_relative '../../../../rubocop/cop/qa/ambiguous_page_object_name'
RSpec.describe RuboCop::Cop::QA::AmbiguousPageObjectName do
let(:source_file) { 'qa/page.rb' }
- subject(:cop) { described_class.new }
-
context 'in a QA file' do
before do
allow(cop).to receive(:in_qa_file?).and_return(true)
diff --git a/spec/rubocop/cop/qa/element_with_pattern_spec.rb b/spec/rubocop/cop/qa/element_with_pattern_spec.rb
index eb098e8f288..1febdaf9c3b 100644
--- a/spec/rubocop/cop/qa/element_with_pattern_spec.rb
+++ b/spec/rubocop/cop/qa/element_with_pattern_spec.rb
@@ -7,8 +7,6 @@ require_relative '../../../../rubocop/cop/qa/element_with_pattern'
RSpec.describe RuboCop::Cop::QA::ElementWithPattern do
let(:source_file) { 'qa/page.rb' }
- subject(:cop) { described_class.new }
-
context 'in a QA file' do
before do
allow(cop).to receive(:in_qa_file?).and_return(true)
diff --git a/spec/rubocop/cop/qa/selector_usage_spec.rb b/spec/rubocop/cop/qa/selector_usage_spec.rb
index 4045c82a5d8..0ec289c1da6 100644
--- a/spec/rubocop/cop/qa/selector_usage_spec.rb
+++ b/spec/rubocop/cop/qa/selector_usage_spec.rb
@@ -5,8 +5,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/qa/selector_usage'
RSpec.describe RuboCop::Cop::QA::SelectorUsage do
- subject(:cop) { described_class.new }
-
shared_examples 'non-qa file usage' do
it 'reports an offense' do
expect_offense(<<-RUBY)
diff --git a/spec/rubocop/cop/rspec/any_instance_of_spec.rb b/spec/rubocop/cop/rspec/any_instance_of_spec.rb
index 948664c110a..f9675e17842 100644
--- a/spec/rubocop/cop/rspec/any_instance_of_spec.rb
+++ b/spec/rubocop/cop/rspec/any_instance_of_spec.rb
@@ -5,8 +5,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/rspec/any_instance_of'
RSpec.describe RuboCop::Cop::RSpec::AnyInstanceOf do
- subject(:cop) { described_class.new }
-
context 'when calling allow_any_instance_of' do
let(:source) do
<<~SRC
diff --git a/spec/rubocop/cop/rspec/be_success_matcher_spec.rb b/spec/rubocop/cop/rspec/be_success_matcher_spec.rb
index 02eefe23df5..c26fa32db8e 100644
--- a/spec/rubocop/cop/rspec/be_success_matcher_spec.rb
+++ b/spec/rubocop/cop/rspec/be_success_matcher_spec.rb
@@ -6,8 +6,6 @@ require_relative '../../../../rubocop/cop/rspec/be_success_matcher'
RSpec.describe RuboCop::Cop::RSpec::BeSuccessMatcher do
let(:source_file) { 'spec/foo_spec.rb' }
- subject(:cop) { described_class.new }
-
shared_examples 'cop' do |good:, bad:|
context "using #{bad} call" do
it 'registers an offense and corrects', :aggregate_failures do
diff --git a/spec/rubocop/cop/rspec/env_assignment_spec.rb b/spec/rubocop/cop/rspec/env_assignment_spec.rb
index 10559a30271..6212cda0b88 100644
--- a/spec/rubocop/cop/rspec/env_assignment_spec.rb
+++ b/spec/rubocop/cop/rspec/env_assignment_spec.rb
@@ -10,8 +10,6 @@ RSpec.describe RuboCop::Cop::RSpec::EnvAssignment do
let(:source_file) { 'spec/foo_spec.rb' }
- subject(:cop) { described_class.new }
-
shared_examples 'an offensive and correction ENV#[]= call' do |content, autocorrected_content|
it "registers an offense for `#{content}` and corrects", :aggregate_failures do
expect_offense(<<~CODE)
diff --git a/spec/rubocop/cop/rspec/expect_gitlab_tracking_spec.rb b/spec/rubocop/cop/rspec/expect_gitlab_tracking_spec.rb
index ad044b29a97..a07cf472ef0 100644
--- a/spec/rubocop/cop/rspec/expect_gitlab_tracking_spec.rb
+++ b/spec/rubocop/cop/rspec/expect_gitlab_tracking_spec.rb
@@ -6,8 +6,6 @@ require_relative '../../../../rubocop/cop/rspec/expect_gitlab_tracking'
RSpec.describe RuboCop::Cop::RSpec::ExpectGitlabTracking do
let(:source_file) { 'spec/foo_spec.rb' }
- subject(:cop) { described_class.new }
-
good_samples = [
'expect_snowplow_event(category: nil, action: nil)',
'expect_snowplow_event(category: "EventCategory", action: "event_action")',
diff --git a/spec/rubocop/cop/rspec/factories_in_migration_specs_spec.rb b/spec/rubocop/cop/rspec/factories_in_migration_specs_spec.rb
index 14fd5de45df..e41dd338387 100644
--- a/spec/rubocop/cop/rspec/factories_in_migration_specs_spec.rb
+++ b/spec/rubocop/cop/rspec/factories_in_migration_specs_spec.rb
@@ -5,8 +5,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/rspec/factories_in_migration_specs'
RSpec.describe RuboCop::Cop::RSpec::FactoriesInMigrationSpecs do
- subject(:cop) { described_class.new }
-
shared_examples 'an offensive factory call' do |namespace|
%i[build build_list create create_list attributes_for].each do |forbidden_method|
namespaced_forbidden_method = "#{namespace}#{forbidden_method}(:user)"
diff --git a/spec/rubocop/cop/rspec/factory_bot/inline_association_spec.rb b/spec/rubocop/cop/rspec/factory_bot/inline_association_spec.rb
index 260c622498f..008af734a99 100644
--- a/spec/rubocop/cop/rspec/factory_bot/inline_association_spec.rb
+++ b/spec/rubocop/cop/rspec/factory_bot/inline_association_spec.rb
@@ -6,8 +6,6 @@ require 'rspec-parameterized'
require_relative '../../../../../rubocop/cop/rspec/factory_bot/inline_association'
RSpec.describe RuboCop::Cop::RSpec::FactoryBot::InlineAssociation do
- subject(:cop) { described_class.new }
-
shared_examples 'offense' do |code_snippet, autocorrected|
# We allow `create` or `FactoryBot.create` or `::FactoryBot.create`
let(:type) { code_snippet[/^(?:::)?(?:FactoryBot\.)?(\w+)/, 1] }
diff --git a/spec/rubocop/cop/rspec/have_gitlab_http_status_spec.rb b/spec/rubocop/cop/rspec/have_gitlab_http_status_spec.rb
index 356fe20556d..e8a60b9cad7 100644
--- a/spec/rubocop/cop/rspec/have_gitlab_http_status_spec.rb
+++ b/spec/rubocop/cop/rspec/have_gitlab_http_status_spec.rb
@@ -10,8 +10,6 @@ RSpec.describe RuboCop::Cop::RSpec::HaveGitlabHttpStatus do
let(:source_file) { 'spec/foo_spec.rb' }
- subject(:cop) { described_class.new }
-
shared_examples 'offense' do |bad, good|
it 'registers an offense', :aggregate_failures do
expect_offense(<<~CODE, node: bad)
diff --git a/spec/rubocop/cop/rspec/htt_party_basic_auth_spec.rb b/spec/rubocop/cop/rspec/htt_party_basic_auth_spec.rb
index 8dc68e877ce..537a7a9a7e9 100644
--- a/spec/rubocop/cop/rspec/htt_party_basic_auth_spec.rb
+++ b/spec/rubocop/cop/rspec/htt_party_basic_auth_spec.rb
@@ -5,8 +5,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/rspec/httparty_basic_auth'
RSpec.describe RuboCop::Cop::RSpec::HTTPartyBasicAuth do
- subject(:cop) { described_class.new }
-
context 'when passing `basic_auth: { user: ... }`' do
it 'registers an offense and corrects', :aggregate_failures do
expect_offense(<<~SOURCE, 'spec/foo.rb')
diff --git a/spec/rubocop/cop/rspec/modify_sidekiq_middleware_spec.rb b/spec/rubocop/cop/rspec/modify_sidekiq_middleware_spec.rb
index 82aa16b72bb..3227b075758 100644
--- a/spec/rubocop/cop/rspec/modify_sidekiq_middleware_spec.rb
+++ b/spec/rubocop/cop/rspec/modify_sidekiq_middleware_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/rspec/modify_sidekiq_middleware'
RSpec.describe RuboCop::Cop::RSpec::ModifySidekiqMiddleware do
- subject(:cop) { described_class.new }
-
it 'registers an offense and corrects', :aggregate_failures do
expect_offense(<<~CODE)
Sidekiq::Testing.server_middleware do |chain|
diff --git a/spec/rubocop/cop/rspec/timecop_freeze_spec.rb b/spec/rubocop/cop/rspec/timecop_freeze_spec.rb
index 4e376a63617..4361f587da3 100644
--- a/spec/rubocop/cop/rspec/timecop_freeze_spec.rb
+++ b/spec/rubocop/cop/rspec/timecop_freeze_spec.rb
@@ -5,8 +5,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/rspec/timecop_freeze'
RSpec.describe RuboCop::Cop::RSpec::TimecopFreeze do
- subject(:cop) { described_class.new }
-
context 'when calling Timecop.freeze' do
it 'registers an offense and corrects', :aggregate_failures do
expect_offense(<<~CODE)
diff --git a/spec/rubocop/cop/rspec/timecop_travel_spec.rb b/spec/rubocop/cop/rspec/timecop_travel_spec.rb
index 3d048707878..89c46ff6c59 100644
--- a/spec/rubocop/cop/rspec/timecop_travel_spec.rb
+++ b/spec/rubocop/cop/rspec/timecop_travel_spec.rb
@@ -5,8 +5,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/rspec/timecop_travel'
RSpec.describe RuboCop::Cop::RSpec::TimecopTravel do
- subject(:cop) { described_class.new }
-
context 'when calling Timecop.travel' do
it 'registers an offense and corrects', :aggregate_failures do
expect_offense(<<~CODE)
diff --git a/spec/rubocop/cop/rspec/top_level_describe_path_spec.rb b/spec/rubocop/cop/rspec/top_level_describe_path_spec.rb
index 0e9a597dc11..90101e09023 100644
--- a/spec/rubocop/cop/rspec/top_level_describe_path_spec.rb
+++ b/spec/rubocop/cop/rspec/top_level_describe_path_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/rspec/top_level_describe_path'
RSpec.describe RuboCop::Cop::RSpec::TopLevelDescribePath do
- subject(:cop) { described_class.new }
-
context 'when the file ends in _spec.rb' do
it 'registers no offenses' do
expect_no_offenses(<<~SOURCE, 'spec/foo_spec.rb')
diff --git a/spec/rubocop/cop/rspec/web_mock_enable_spec.rb b/spec/rubocop/cop/rspec/web_mock_enable_spec.rb
index 1b10e7c901a..63ffc06f1ca 100644
--- a/spec/rubocop/cop/rspec/web_mock_enable_spec.rb
+++ b/spec/rubocop/cop/rspec/web_mock_enable_spec.rb
@@ -5,8 +5,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/rspec/web_mock_enable'
RSpec.describe RuboCop::Cop::RSpec::WebMockEnable do
- subject(:cop) { described_class.new }
-
context 'when calling WebMock.disable_net_connect!' do
it 'registers an offence and autocorrects it' do
expect_offense(<<~RUBY)
diff --git a/spec/rubocop/cop/ruby_interpolation_in_translation_spec.rb b/spec/rubocop/cop/ruby_interpolation_in_translation_spec.rb
index b960a1d093e..b687e91601c 100644
--- a/spec/rubocop/cop/ruby_interpolation_in_translation_spec.rb
+++ b/spec/rubocop/cop/ruby_interpolation_in_translation_spec.rb
@@ -9,8 +9,6 @@ require_relative '../../../rubocop/cop/ruby_interpolation_in_translation'
RSpec.describe RuboCop::Cop::RubyInterpolationInTranslation do
let(:msg) { "Don't use ruby interpolation \#{} inside translated strings, instead use %{}" }
- subject(:cop) { described_class.new }
-
it 'does not add an offense for a regular messages' do
expect_no_offenses('_("Hello world")')
end
diff --git a/spec/rubocop/cop/safe_params_spec.rb b/spec/rubocop/cop/safe_params_spec.rb
index 135e815eb53..e6d86019d18 100644
--- a/spec/rubocop/cop/safe_params_spec.rb
+++ b/spec/rubocop/cop/safe_params_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../rubocop/cop/safe_params'
RSpec.describe RuboCop::Cop::SafeParams do
- subject(:cop) { described_class.new }
-
it 'flags the params as an argument of url_for' do
expect_offense(<<~SOURCE)
url_for(params)
diff --git a/spec/rubocop/cop/scalability/bulk_perform_with_context_spec.rb b/spec/rubocop/cop/scalability/bulk_perform_with_context_spec.rb
index ba5b150e1f9..bd248cd028a 100644
--- a/spec/rubocop/cop/scalability/bulk_perform_with_context_spec.rb
+++ b/spec/rubocop/cop/scalability/bulk_perform_with_context_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/scalability/bulk_perform_with_context'
RSpec.describe RuboCop::Cop::Scalability::BulkPerformWithContext do
- subject(:cop) { described_class.new }
-
it "adds an offense when calling bulk_perform_async" do
expect_offense(<<~CODE)
Worker.bulk_perform_async(args)
diff --git a/spec/rubocop/cop/scalability/cron_worker_context_spec.rb b/spec/rubocop/cop/scalability/cron_worker_context_spec.rb
index bdd1406a0e6..bcf93b04d6a 100644
--- a/spec/rubocop/cop/scalability/cron_worker_context_spec.rb
+++ b/spec/rubocop/cop/scalability/cron_worker_context_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/scalability/cron_worker_context'
RSpec.describe RuboCop::Cop::Scalability::CronWorkerContext do
- subject(:cop) { described_class.new }
-
it 'adds an offense when including CronjobQueue' do
expect_offense(<<~CODE)
class SomeWorker
diff --git a/spec/rubocop/cop/scalability/file_uploads_spec.rb b/spec/rubocop/cop/scalability/file_uploads_spec.rb
index c9e1e02be1a..1395615479f 100644
--- a/spec/rubocop/cop/scalability/file_uploads_spec.rb
+++ b/spec/rubocop/cop/scalability/file_uploads_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/scalability/file_uploads'
RSpec.describe RuboCop::Cop::Scalability::FileUploads do
- subject(:cop) { described_class.new }
-
let(:message) { 'Do not upload files without workhorse acceleration. Please refer to https://docs.gitlab.com/ee/development/uploads.html' }
context 'with required params' do
diff --git a/spec/rubocop/cop/scalability/idempotent_worker_spec.rb b/spec/rubocop/cop/scalability/idempotent_worker_spec.rb
index c1f841a46ec..b1984721803 100644
--- a/spec/rubocop/cop/scalability/idempotent_worker_spec.rb
+++ b/spec/rubocop/cop/scalability/idempotent_worker_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/scalability/idempotent_worker'
RSpec.describe RuboCop::Cop::Scalability::IdempotentWorker do
- subject(:cop) { described_class.new }
-
before do
allow(cop)
.to receive(:in_worker?)
diff --git a/spec/rubocop/cop/sidekiq_load_balancing/worker_data_consistency_spec.rb b/spec/rubocop/cop/sidekiq_load_balancing/worker_data_consistency_spec.rb
index eef78397f0a..7b6578a0744 100644
--- a/spec/rubocop/cop/sidekiq_load_balancing/worker_data_consistency_spec.rb
+++ b/spec/rubocop/cop/sidekiq_load_balancing/worker_data_consistency_spec.rb
@@ -4,8 +4,6 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/sidekiq_load_balancing/worker_data_consistency'
RSpec.describe RuboCop::Cop::SidekiqLoadBalancing::WorkerDataConsistency do
- subject(:cop) { described_class.new }
-
before do
allow(cop)
.to receive(:in_worker?)
diff --git a/spec/rubocop/cop/sidekiq_options_queue_spec.rb b/spec/rubocop/cop/sidekiq_options_queue_spec.rb
index 8b7a67cff26..da126090a81 100644
--- a/spec/rubocop/cop/sidekiq_options_queue_spec.rb
+++ b/spec/rubocop/cop/sidekiq_options_queue_spec.rb
@@ -5,8 +5,6 @@ require 'rubocop_spec_helper'
require_relative '../../../rubocop/cop/sidekiq_options_queue'
RSpec.describe RuboCop::Cop::SidekiqOptionsQueue do
- subject(:cop) { described_class.new }
-
it 'registers an offense when `sidekiq_options` is used with the `queue` option' do
expect_offense(<<~CODE)
sidekiq_options queue: "some_queue"
diff --git a/spec/rubocop/cop/static_translation_definition_spec.rb b/spec/rubocop/cop/static_translation_definition_spec.rb
index 33945064b3f..10b4f162504 100644
--- a/spec/rubocop/cop/static_translation_definition_spec.rb
+++ b/spec/rubocop/cop/static_translation_definition_spec.rb
@@ -11,8 +11,6 @@ RSpec.describe RuboCop::Cop::StaticTranslationDefinition do
let(:msg) { described_class::MSG }
- subject(:cop) { described_class.new }
-
shared_examples 'offense' do |code|
it 'registers an offense' do
expect_offense(code)
diff --git a/spec/rubocop/cop/usage_data/distinct_count_by_large_foreign_key_spec.rb b/spec/rubocop/cop/usage_data/distinct_count_by_large_foreign_key_spec.rb
index 14b6df8de4e..b4d113a9bcc 100644
--- a/spec/rubocop/cop/usage_data/distinct_count_by_large_foreign_key_spec.rb
+++ b/spec/rubocop/cop/usage_data/distinct_count_by_large_foreign_key_spec.rb
@@ -13,8 +13,6 @@ RSpec.describe RuboCop::Cop::UsageData::DistinctCountByLargeForeignKey do
})
end
- subject(:cop) { described_class.new(config) }
-
context 'when counting by disallowed key' do
it 'registers an offense' do
expect_offense(<<~CODE)
diff --git a/spec/rubocop/cop/usage_data/histogram_with_large_table_spec.rb b/spec/rubocop/cop/usage_data/histogram_with_large_table_spec.rb
index df9d538d2ae..efa4e27dc9c 100644
--- a/spec/rubocop/cop/usage_data/histogram_with_large_table_spec.rb
+++ b/spec/rubocop/cop/usage_data/histogram_with_large_table_spec.rb
@@ -14,8 +14,6 @@ RSpec.describe RuboCop::Cop::UsageData::HistogramWithLargeTable do
})
end
- subject(:cop) { described_class.new(config) }
-
context 'with large tables' do
context 'with one-level constants' do
context 'when calling histogram(Issue)' do
diff --git a/spec/rubocop/cop/usage_data/instrumentation_superclass_spec.rb b/spec/rubocop/cop/usage_data/instrumentation_superclass_spec.rb
index 8d2427e6e69..a55f0852f35 100644
--- a/spec/rubocop/cop/usage_data/instrumentation_superclass_spec.rb
+++ b/spec/rubocop/cop/usage_data/instrumentation_superclass_spec.rb
@@ -14,8 +14,6 @@ RSpec.describe RuboCop::Cop::UsageData::InstrumentationSuperclass do
})
end
- subject(:cop) { described_class.new(config) }
-
context 'with class definition' do
context 'when inheriting from allowed superclass' do
it 'does not register an offense' do
diff --git a/spec/rubocop/cop/usage_data/large_table_spec.rb b/spec/rubocop/cop/usage_data/large_table_spec.rb
index befdc1caead..fa94f878cea 100644
--- a/spec/rubocop/cop/usage_data/large_table_spec.rb
+++ b/spec/rubocop/cop/usage_data/large_table_spec.rb
@@ -18,8 +18,6 @@ RSpec.describe RuboCop::Cop::UsageData::LargeTable do
})
end
- subject(:cop) { described_class.new(config) }
-
context 'when in usage_data files' do
before do
allow(cop).to receive(:usage_data_files?).and_return(true)
diff --git a/spec/rubocop/cop/user_admin_spec.rb b/spec/rubocop/cop/user_admin_spec.rb
index b34418adf91..99e87d619c0 100644
--- a/spec/rubocop/cop/user_admin_spec.rb
+++ b/spec/rubocop/cop/user_admin_spec.rb
@@ -6,8 +6,6 @@ require 'rubocop'
require_relative '../../../rubocop/cop/user_admin'
RSpec.describe RuboCop::Cop::UserAdmin do
- subject(:cop) { described_class.new }
-
it 'flags a method call' do
expect_offense(<<~SOURCE)
user.admin?
diff --git a/spec/rubocop_spec_helper.rb b/spec/rubocop_spec_helper.rb
index c49437137e3..a37415a25de 100644
--- a/spec/rubocop_spec_helper.rb
+++ b/spec/rubocop_spec_helper.rb
@@ -14,4 +14,7 @@ RSpec.configure do |config|
config.define_derived_metadata(file_path: %r{spec/rubocop}) do |metadata|
metadata[:type] = :rubocop
end
+
+ # Include config shared context for all cop specs.
+ config.include_context 'config', type: :rubocop
end
diff --git a/spec/services/releases/create_service_spec.rb b/spec/services/releases/create_service_spec.rb
index 2421fab0eec..5f49eed3e77 100644
--- a/spec/services/releases/create_service_spec.rb
+++ b/spec/services/releases/create_service_spec.rb
@@ -70,6 +70,28 @@ RSpec.describe Releases::CreateService do
expect(result[:release]).not_to be_nil
end
+ context 'and the tag would be protected' do
+ let!(:protected_tag) { create(:protected_tag, project: project, name: tag_name) }
+
+ context 'and the user does not have permissions' do
+ let(:user) { create(:user) }
+
+ before do
+ project.add_developer(user)
+ end
+
+ it 'raises an error' do
+ result = service.execute
+
+ expect(result[:status]).to eq(:error)
+ end
+ end
+
+ context 'and the user has permissions' do
+ it_behaves_like 'a successful release creation'
+ end
+ end
+
context 'and tag_message is provided' do
let(:ref) { 'master' }
let(:tag_name) { 'foobar' }
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 160f7fda543..18820eefe31 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -125,9 +125,6 @@ RSpec.configure do |config|
end
end
- # Re-run failures locally with `--only-failures`
- config.example_status_persistence_file_path = ENV.fetch('RSPEC_LAST_RUN_RESULTS_FILE', './spec/examples.txt')
-
config.define_derived_metadata(file_path: %r{(ee)?/spec/.+_spec\.rb\z}) do |metadata|
location = metadata[:location]
diff --git a/spec/support/rspec.rb b/spec/support/rspec.rb
index a11b720d060..2d37501f7c6 100644
--- a/spec/support/rspec.rb
+++ b/spec/support/rspec.rb
@@ -11,6 +11,9 @@ require_relative "helpers/fast_rails_root"
RSpec::Expectations.configuration.on_potential_false_positives = :raise
RSpec.configure do |config|
+ # Re-run failures locally with `--only-failures`
+ config.example_status_persistence_file_path = ENV.fetch('RSPEC_LAST_RUN_RESULTS_FILE', './spec/examples.txt')
+
config.mock_with :rspec do |mocks|
mocks.verify_doubled_constant_names = true
end
diff --git a/vendor/gems/omniauth-azure-oauth2/Gemfile.lock b/vendor/gems/omniauth-azure-oauth2/Gemfile.lock
index d2bbe3e8d2f..0bd5d401175 100644
--- a/vendor/gems/omniauth-azure-oauth2/Gemfile.lock
+++ b/vendor/gems/omniauth-azure-oauth2/Gemfile.lock
@@ -3,7 +3,7 @@ PATH
specs:
omniauth-azure-oauth2 (0.0.10)
jwt (>= 1.0, < 3.0)
- omniauth (~> 2.0)
+ omniauth (~> 1.0, < 3)
omniauth-oauth2 (~> 1.4)
GEM
@@ -19,17 +19,16 @@ GEM
multi_xml (0.6.0)
mustermann (2.0.2)
ruby2_keywords (~> 0.0.1)
- oauth2 (2.0.3)
+ oauth2 (2.0.6)
faraday (>= 0.17.3, < 3.0)
jwt (>= 1.0, < 3.0)
multi_xml (~> 0.5)
rack (>= 1.2, < 3)
rash_alt (>= 0.4, < 1)
- version_gem (~> 1.0)
- omniauth (2.1.0)
+ version_gem (~> 1.1)
+ omniauth (1.9.1)
hashie (>= 3.4.6)
- rack (>= 2.2.3)
- rack-protection
+ rack (>= 1.6.2, < 3)
omniauth-oauth2 (1.7.3)
oauth2 (>= 1.4, < 3)
omniauth (>= 1.9, < 3)
@@ -71,4 +70,4 @@ DEPENDENCIES
sinatra
BUNDLED WITH
- 2.3.21
+ 2.3.20
diff --git a/vendor/gems/omniauth-azure-oauth2/lib/omniauth/strategies/azure_oauth2.rb b/vendor/gems/omniauth-azure-oauth2/lib/omniauth/strategies/azure_oauth2.rb
index d71911b9876..f18babc0619 100644
--- a/vendor/gems/omniauth-azure-oauth2/lib/omniauth/strategies/azure_oauth2.rb
+++ b/vendor/gems/omniauth-azure-oauth2/lib/omniauth/strategies/azure_oauth2.rb
@@ -59,10 +59,8 @@ module OmniAuth
super.merge(resource: azure_resource || options.resource)
end
- # for compatibility with OmniAuth 2.0
- # see https://github.com/RIPAGlobal/omniauth-azure-activedirectory-v2/pull/6
def callback_url
- full_host + callback_path
+ full_host + script_name + callback_path
end
def raw_info
diff --git a/vendor/gems/omniauth-azure-oauth2/omniauth-azure-oauth2.gemspec b/vendor/gems/omniauth-azure-oauth2/omniauth-azure-oauth2.gemspec
index 1299285b945..6e1bc583881 100644
--- a/vendor/gems/omniauth-azure-oauth2/omniauth-azure-oauth2.gemspec
+++ b/vendor/gems/omniauth-azure-oauth2/omniauth-azure-oauth2.gemspec
@@ -15,7 +15,7 @@ Gem::Specification.new do |gem|
gem.version = OmniAuth::AzureOauth2::VERSION
gem.license = "MIT"
- gem.add_runtime_dependency 'omniauth', '~> 2.0'
+ gem.add_runtime_dependency 'omniauth', '~> 1.0', '< 3'
gem.add_dependency 'jwt', ['>= 1.0', '< 3.0']
gem.add_runtime_dependency 'omniauth-oauth2', '~> 1.4'
diff --git a/vendor/gems/omniauth-cas3/Gemfile.lock b/vendor/gems/omniauth-cas3/Gemfile.lock
index a856e78f00f..4c59eb05d50 100644
--- a/vendor/gems/omniauth-cas3/Gemfile.lock
+++ b/vendor/gems/omniauth-cas3/Gemfile.lock
@@ -4,30 +4,29 @@ PATH
omniauth-cas3 (1.1.4)
addressable (~> 2.3)
nokogiri (~> 1.7, >= 1.7.1)
- omniauth (~> 2.0)
+ omniauth (~> 1.2, < 3)
GEM
remote: https://rubygems.org/
specs:
- addressable (2.8.1)
- public_suffix (>= 2.0.2, < 6.0)
+ addressable (2.8.0)
+ public_suffix (>= 2.0.2, < 5.0)
awesome_print (1.9.2)
crack (0.4.5)
rexml
diff-lcs (1.5.0)
hashdiff (1.0.1)
hashie (5.0.0)
+ mini_portile2 (2.8.0)
nokogiri (1.13.7)
+ mini_portile2 (~> 2.8.0)
racc (~> 1.4)
- omniauth (2.1.0)
+ omniauth (1.9.1)
hashie (>= 3.4.6)
- rack (>= 2.2.3)
- rack-protection
- public_suffix (5.0.0)
+ rack (>= 1.6.2, < 3)
+ public_suffix (4.0.7)
racc (1.6.0)
rack (2.2.4)
- rack-protection (2.2.2)
- rack
rack-test (0.8.3)
rack (>= 1.0, < 3)
rake (10.5.0)
@@ -45,7 +44,7 @@ GEM
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.11.0)
rspec-support (3.11.0)
- webmock (3.18.1)
+ webmock (3.14.0)
addressable (>= 2.8.0)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
@@ -62,4 +61,4 @@ DEPENDENCIES
webmock
BUNDLED WITH
- 2.3.21
+ 2.3.18
diff --git a/vendor/gems/omniauth-cas3/omniauth-cas3.gemspec b/vendor/gems/omniauth-cas3/omniauth-cas3.gemspec
index c976d85df99..abbcaa268d0 100644
--- a/vendor/gems/omniauth-cas3/omniauth-cas3.gemspec
+++ b/vendor/gems/omniauth-cas3/omniauth-cas3.gemspec
@@ -14,7 +14,7 @@ Gem::Specification.new do |gem|
gem.require_paths = ["lib"]
gem.version = Omniauth::Cas3::VERSION
- gem.add_dependency 'omniauth', '~> 2.0'
+ gem.add_dependency 'omniauth', '~> 1.2', '< 3'
gem.add_dependency 'nokogiri', '~> 1.7', '>= 1.7.1'
gem.add_dependency 'addressable', '~> 2.3'
diff --git a/vendor/gems/omniauth-gitlab/Gemfile.lock b/vendor/gems/omniauth-gitlab/Gemfile.lock
index b59ba59b95b..b5979104080 100644
--- a/vendor/gems/omniauth-gitlab/Gemfile.lock
+++ b/vendor/gems/omniauth-gitlab/Gemfile.lock
@@ -2,7 +2,7 @@ PATH
remote: .
specs:
omniauth-gitlab (4.0.0)
- omniauth (~> 2.0)
+ omniauth (~> 1.0)
omniauth-oauth2 (~> 1.7.1)
GEM
@@ -24,16 +24,13 @@ GEM
rack (>= 1.2, < 3)
rash_alt (>= 0.4, < 1)
version_gem (~> 1.0)
- omniauth (2.1.0)
+ omniauth (1.9.1)
hashie (>= 3.4.6)
- rack (>= 2.2.3)
- rack-protection
+ rack (>= 1.6.2, < 3)
omniauth-oauth2 (1.7.3)
oauth2 (>= 1.4, < 3)
omniauth (>= 1.9, < 3)
- rack (2.2.4)
- rack-protection (2.2.2)
- rack
+ rack (2.2.3.1)
rake (13.0.6)
rash_alt (0.4.12)
hashie (>= 3.4)
diff --git a/vendor/gems/omniauth-gitlab/omniauth-gitlab.gemspec b/vendor/gems/omniauth-gitlab/omniauth-gitlab.gemspec
index ca4b8d904f0..be25cb50af6 100644
--- a/vendor/gems/omniauth-gitlab/omniauth-gitlab.gemspec
+++ b/vendor/gems/omniauth-gitlab/omniauth-gitlab.gemspec
@@ -16,7 +16,7 @@ Gem::Specification.new do |gem|
gem.test_files = Dir['spec/**/*.rb']
gem.require_paths = ['lib']
- gem.add_dependency 'omniauth', '~> 2.0'
+ gem.add_dependency 'omniauth', '~> 1.0'
gem.add_dependency 'omniauth-oauth2', '~> 1.7.1'
gem.add_development_dependency 'rspec', '~> 3.1'
gem.add_development_dependency 'rspec-its', '~> 1.0'
diff --git a/vendor/gems/omniauth-google-oauth2/CHANGELOG.md b/vendor/gems/omniauth-google-oauth2/CHANGELOG.md
index 5b252048fd6..7d3e1234f2d 100644
--- a/vendor/gems/omniauth-google-oauth2/CHANGELOG.md
+++ b/vendor/gems/omniauth-google-oauth2/CHANGELOG.md
@@ -1,106 +1,6 @@
# Changelog
All notable changes to this project will be documented in this file.
-## 1.0.1 - 2022-03-10
-
-### Added
-- Output granted scopes in credentials block of the auth hash.
-- Migrated to GitHub actions.
-
-### Deprecated
-- Nothing.
-
-### Removed
-- Nothing.
-
-### Fixed
-- Overriding the `redirect_uri` via params or JSON request body.
-
-## 1.0.0 - 2021-03-14
-
-### Added
-- Support for Omniauth 2.x!
-
-### Deprecated
-- Nothing.
-
-### Removed
-- Support for Omniauth 1.x.
-
-### Fixed
-- Nothing.
-
-## 0.8.2 - 2021-03-14
-
-### Added
-- Constrains the version to Omniauth 1.x.
-
-### Deprecated
-- Nothing.
-
-### Removed
-- Nothing.
-
-### Fixed
-- Nothing.
-
-## 0.8.1 - 2020-12-12
-
-### Added
-- Support reading the access token from a json request body.
-
-### Deprecated
-- Nothing.
-
-### Removed
-- No longer verify the iat claim for JWT.
-
-### Fixed
-- A few minor issues with .rubocop.yml.
-- Issues with image resizing code when the image came with size information from Google.
-
-## 0.8.0 - 2019-08-21
-
-### Added
-- Updated omniauth-oauth2 to v1.6.0 for security fixes.
-
-### Deprecated
-- Nothing.
-
-### Removed
-- Ruby 2.1 support.
-
-### Fixed
-- Nothing.
-
-## 0.7.0 - 2019-06-03
-
-### Added
-- Ensure `info[:email]` is always verified, and include `unverified_email`
-
-### Deprecated
-- Nothing.
-
-### Removed
-- Nothing.
-
-### Fixed
-- Nothing.
-
-## 0.6.1 - 2019-03-07
-
-### Added
-- Return `email` and `email_verified` keys in response.
-
-### Deprecated
-- Nothing.
-
-### Removed
-- Nothing.
-
-### Fixed
-- Nothing.
-
## 0.6.0 - 2018-12-28
### Added
@@ -112,7 +12,6 @@ All notable changes to this project will be documented in this file.
### Removed
- Support for JWT 1.x.
- Support for `raw_friend_info` and `raw_image_info`.
-- Stop using Google+ API endpoints.
### Fixed
- Nothing.
diff --git a/vendor/gems/omniauth-google-oauth2/Gemfile.lock b/vendor/gems/omniauth-google-oauth2/Gemfile.lock
index 6c3f5ff3f68..a7f71e0a376 100644
--- a/vendor/gems/omniauth-google-oauth2/Gemfile.lock
+++ b/vendor/gems/omniauth-google-oauth2/Gemfile.lock
@@ -1,11 +1,10 @@
PATH
remote: .
specs:
- omniauth-google-oauth2 (1.0.1)
+ omniauth-google-oauth2 (0.6.0)
jwt (>= 2.0)
- oauth2 (~> 2.0)
- omniauth (~> 2.0)
- omniauth-oauth2 (~> 1.7.1)
+ omniauth (>= 1.9, < 3)
+ omniauth-oauth2 (>= 1.5)
GEM
remote: https://rubygems.org/
@@ -26,10 +25,9 @@ GEM
rack (>= 1.2, < 3)
rash_alt (>= 0.4, < 1)
version_gem (~> 1.0)
- omniauth (2.1.0)
+ omniauth (1.9.2)
hashie (>= 3.4.6)
- rack (>= 2.2.3)
- rack-protection
+ rack (>= 1.6.2, < 3)
omniauth-oauth2 (1.7.3)
oauth2 (>= 1.4, < 3)
omniauth (>= 1.9, < 3)
@@ -37,8 +35,6 @@ GEM
parser (3.1.2.0)
ast (~> 2.4.1)
rack (2.2.4)
- rack-protection (2.2.2)
- rack
rainbow (3.1.1)
rake (12.3.3)
rash_alt (0.4.12)
diff --git a/vendor/gems/omniauth-google-oauth2/README.md b/vendor/gems/omniauth-google-oauth2/README.md
index 80c611392ca..5d811693a60 100644
--- a/vendor/gems/omniauth-google-oauth2/README.md
+++ b/vendor/gems/omniauth-google-oauth2/README.md
@@ -1,4 +1,5 @@
[![Gem Version](https://badge.fury.io/rb/omniauth-google-oauth2.svg)](https://badge.fury.io/rb/omniauth-google-oauth2)
+[![Build Status](https://travis-ci.org/zquestz/omniauth-google-oauth2.svg)](https://travis-ci.org/zquestz/omniauth-google-oauth2)
# OmniAuth Google OAuth2 Strategy
@@ -33,7 +34,6 @@ Here's an example for adding the middleware to a Rails app in `config/initialize
Rails.application.config.middleware.use OmniAuth::Builder do
provider :google_oauth2, ENV['GOOGLE_CLIENT_ID'], ENV['GOOGLE_CLIENT_SECRET']
end
-OmniAuth.config.allowed_request_methods = %i[get]
```
You can now access the OmniAuth Google OAuth2 URL: `/auth/google_oauth2`
@@ -54,10 +54,10 @@ You can configure several options, which you pass in to the `provider` method vi
* `prompt`: A space-delimited list of string values that determines whether the user is re-prompted for authentication and/or consent. Possible values are:
* `none`: No authentication or consent pages will be displayed; it will return an error if the user is not already authenticated and has not pre-configured consent for the requested scopes. This can be used as a method to check for existing authentication and/or consent.
- * `consent`: The user will always be prompted for consent, even if they have previously allowed access a given set of scopes.
+ * `consent`: The user will always be prompted for consent, even if he has previously allowed access a given set of scopes.
* `select_account`: The user will always be prompted to select a user account. This allows a user who has multiple current account sessions to select one amongst them.
- If no value is specified, the user only sees the authentication page if they are not logged in and only sees the consent page the first time they authorize a given set of scopes.
+ If no value is specified, the user only sees the authentication page if he is not logged in and only sees the consent page the first time he authorizes a given set of scopes.
* `image_aspect_ratio`: The shape of the user's profile picture. Possible values are:
* `original`: Picture maintains its original aspect ratio.
@@ -73,7 +73,7 @@ You can configure several options, which you pass in to the `provider` method vi
* `hd`: (Optional) Limit sign-in to a particular Google Apps hosted domain. This can be simply string `'domain.com'` or an array `%w(domain.com domain.co)`. More information at: https://developers.google.com/accounts/docs/OpenIDConnect#hd-param
-* `jwt_leeway`: Number of seconds passed to the JWT library as leeway. Defaults to 60 seconds. Note this only works if you use jwt 2.1, as the leeway option was removed in later versions.
+* `jwt_leeway`: Number of seconds passed to the JWT library as leeway. Defaults to 60 seconds.
* `skip_jwt`: Skip JWT processing. This is for users who are seeing JWT decoding errors with the `iat` field. Always try adjusting the leeway before disabling JWT processing.
@@ -81,11 +81,9 @@ You can configure several options, which you pass in to the `provider` method vi
* `include_granted_scopes`: If this is provided with the value true, and the authorization request is granted, the authorization will include any previous authorizations granted to this user/application combination for other scopes. See Google's [Incremental Authorization](https://developers.google.com/accounts/docs/OAuth2WebServer#incrementalAuth) for additional details.
-* `openid_realm`: Set the OpenID realm value, to allow upgrading from OpenID based authentication to OAuth 2 based authentication. When this is set correctly an `openid_id` value will be set in `['extra']['id_info']` in the authentication hash with the value of the user's OpenID ID URL.
+* `openid_realm`: Set the OpenID realm value, to allow upgrading from OpenID based authentication to OAuth 2 based authentication. When this is set correctly an `openid_id` value will be set in `[:extra][:id_info]` in the authentication hash with the value of the user's OpenID ID URL.
-* `provider_ignores_state`: You will need to set this to `true` when using the `One-time Code Flow` below. In this flow there is no server side redirect that would set the state.
-
-Here's an example of a possible configuration where the strategy name is changed, the user is asked for extra permissions, the user is always prompted to select their account when logging in and the user's profile picture is returned as a thumbnail:
+Here's an example of a possible configuration where the strategy name is changed, the user is asked for extra permissions, the user is always prompted to select his account when logging in and the user's profile picture is returned as a thumbnail:
```ruby
Rails.application.config.middleware.use OmniAuth::Builder do
@@ -178,8 +176,6 @@ devise :omniauthable, omniauth_providers: [:google_oauth2]
Then make sure your callbacks controller is setup.
```ruby
-# app/controllers/users/omniauth_callbacks_controller.rb:
-
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def google_oauth2
# You need to implement the method below in your model (e.g. app/models/user.rb)
@@ -189,7 +185,7 @@ class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
flash[:notice] = I18n.t 'devise.omniauth_callbacks.success', kind: 'Google'
sign_in_and_redirect @user, event: :authentication
else
- session['devise.google_data'] = request.env['omniauth.auth'].except('extra') # Removing extra as it can overflow some session stores
+ session['devise.google_data'] = request.env['omniauth.auth'].except(:extra) # Removing extra as it can overflow some session stores
redirect_to new_user_registration_url, alert: @user.errors.full_messages.join("\n")
end
end
@@ -217,10 +213,6 @@ end
For your views you can login using:
```erb
-<%# omniauth-google-oauth2 1.0.x uses OmniAuth 2 and requires using HTTP Post to initiate authentication: %>
-<%= link_to "Sign in with Google", user_google_oauth2_omniauth_authorize_path, method: :post %>
-
-<%# omniauth-google-oauth2 prior 1.0.0: %>
<%= link_to "Sign in with Google", user_google_oauth2_omniauth_authorize_path %>
<%# Devise prior 4.1.0: %>
@@ -231,7 +223,7 @@ An overview is available at https://github.com/plataformatec/devise/wiki/OmniAut
### One-time Code Flow (Hybrid Authentication)
-Google describes the One-time Code Flow [here](https://developers.google.com/identity/sign-in/web/server-side-flow). This hybrid authentication flow has significant functional and security advantages over a pure server-side or pure client-side flow. The following steps occur in this flow:
+Google describes the One-time Code Flow [here](https://developers.google.com/+/web/signin/server-side-flow). This hybrid authentication flow has significant functional and security advantages over a pure server-side or pure client-side flow. The following steps occur in this flow:
1. The client (web browser) authenticates the user directly via Google's JS API. During this process assorted modals may be rendered by Google.
2. On successful authentication, Google returns a one-time use code, which requires the Google client secret (which is only available server-side).
@@ -240,7 +232,7 @@ Google describes the One-time Code Flow [here](https://developers.google.com/ide
This flow is immune to replay attacks, and conveys no useful information to a man in the middle.
-The omniauth-google-oauth2 gem supports this mode of operation when `provider_ignores_state` is set to `true`. Implementors simply need to add the appropriate JavaScript to their web page, and they can take advantage of this flow. An example JavaScript snippet follows.
+The omniauth-google-oauth2 gem supports this mode of operation out of the box. Implementors simply need to add the appropriate JavaScript to their web page, and they can take advantage of this flow. An example JavaScript snippet follows.
```javascript
// Basic hybrid auth example following the pattern at:
@@ -255,7 +247,7 @@ function init() {
// Ready.
$('.google-login-button').click(function(e) {
e.preventDefault();
-
+
gapi.auth2.authorize({
client_id: 'YOUR_CLIENT_ID',
cookie_policy: 'single_host_origin',
@@ -268,7 +260,7 @@ function init() {
success: function(data) {
// response from server
}
- });
+ });
} else {
// google authentication failed
}
@@ -288,66 +280,6 @@ In that case, ensure to send an additional parameter `redirect_uri=` (empty stri
If you're making POST requests to `/auth/google_oauth2/callback` from another domain, then you need to make sure `'X-Requested-With': 'XMLHttpRequest'` header is included with your request, otherwise your server might respond with `OAuth2::Error, : Invalid Value` error.
-#### Getting around the `redirect_uri_mismatch` error (See [Issue #365](https://github.com/zquestz/omniauth-google-oauth2/issues/365))
-
-If you are struggling with a persistent `redirect_uri_mismatch`, you can instead pass the `access_token` from [`getAuthResponse`](https://developers.google.com/identity/sign-in/web/reference#googleusergetauthresponseincludeauthorizationdata) directly to the `auth/google_oauth2/callback` endpoint, like so:
-
-```javascript
-// Initialize the GoogleAuth object
-let googleAuth;
-gapi.load('client:auth2', async () => {
- await gapi.client.init({ scope: '...', client_id: '...' });
- googleAuth = gapi.auth2.getAuthInstance();
-});
-
-// Call this when the Google Sign In button is clicked
-async function signInGoogle() {
- const googleUser = await googleAuth.signIn(); // wait for the user to authorize through the modal
- const { access_token } = googleUser.getAuthResponse();
-
- const data = new FormData();
- data.append('access_token', access_token);
-
- const response = await api.post('/auth/google_oauth2/callback', data)
- console.log(response);
-}
-```
-
-#### Using Axios
-If you're making a GET resquests from another domain using `access_token`.
-```
-axios
- .get(
- 'url(path to your callback}',
- { params: { access_token: 'token' } },
- headers....
- )
-```
-
-If you're making a POST resquests from another domain using `access_token`.
-```
-axios
- .post(
- 'url(path to your callback}',
- { access_token: 'token' },
- headers....
- )
-
---OR--
-
-axios
- .post(
- 'url(path to your callback}',
- null,
- {
- params: {
- access_token: 'token'
- },
- headers....
- }
- )
-```
-
## Fixing Protocol Mismatch for `redirect_uri` in Rails
Just set the `full_host` in OmniAuth based on the Rails.env.
diff --git a/vendor/gems/omniauth-google-oauth2/examples/Gemfile b/vendor/gems/omniauth-google-oauth2/examples/Gemfile
index ba019344a67..cd02ff9bf7d 100644
--- a/vendor/gems/omniauth-google-oauth2/examples/Gemfile
+++ b/vendor/gems/omniauth-google-oauth2/examples/Gemfile
@@ -2,7 +2,6 @@
source 'https://rubygems.org'
-gem 'omniauth-google-oauth2', '~> 0.8.1'
+gem 'omniauth-google-oauth2', '~> 0.5'
gem 'rubocop'
gem 'sinatra', '~> 1.4'
-gem 'webrick'
diff --git a/vendor/gems/omniauth-google-oauth2/examples/omni_auth.rb b/vendor/gems/omniauth-google-oauth2/examples/omni_auth.rb
index 0a94164d766..127b62a9aaf 100644
--- a/vendor/gems/omniauth-google-oauth2/examples/omni_auth.rb
+++ b/vendor/gems/omniauth-google-oauth2/examples/omni_auth.rb
@@ -10,10 +10,6 @@ Rails.application.config.middleware.use OmniAuth::Builder do
#
provider :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET'], scope: 'email,profile'
- # Custom redirect_uri
- #
- # provider :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET'], scope: 'email,profile', redirect_uri: 'https://localhost:3000/redirect'
-
# Manual setup for offline access with a refresh token.
#
# provider :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET'], access_type: 'offline'
diff --git a/vendor/gems/omniauth-google-oauth2/lib/omniauth/google_oauth2/version.rb b/vendor/gems/omniauth-google-oauth2/lib/omniauth/google_oauth2/version.rb
index 93ae5e9e990..565fb5d6642 100644
--- a/vendor/gems/omniauth-google-oauth2/lib/omniauth/google_oauth2/version.rb
+++ b/vendor/gems/omniauth-google-oauth2/lib/omniauth/google_oauth2/version.rb
@@ -2,6 +2,6 @@
module OmniAuth
module GoogleOauth2
- VERSION = '1.0.1'
+ VERSION = '0.6.0'
end
end
diff --git a/vendor/gems/omniauth-google-oauth2/lib/omniauth/strategies/google_oauth2.rb b/vendor/gems/omniauth-google-oauth2/lib/omniauth/strategies/google_oauth2.rb
index 4ce32eb80d1..62e2d4462e5 100644
--- a/vendor/gems/omniauth-google-oauth2/lib/omniauth/strategies/google_oauth2.rb
+++ b/vendor/gems/omniauth-google-oauth2/lib/omniauth/strategies/google_oauth2.rb
@@ -1,7 +1,6 @@
# frozen_string_literal: true
require 'jwt'
-require 'oauth2'
require 'omniauth/strategies/oauth2'
require 'uri'
@@ -14,7 +13,6 @@ module OmniAuth
BASE_SCOPES = %w[profile email openid].freeze
DEFAULT_SCOPE = 'email,profile'
USER_INFO_URL = 'https://www.googleapis.com/oauth2/v3/userinfo'
- IMAGE_SIZE_REGEXP = /(s\d+(-c)?)|(w\d+-h\d+(-c)?)|(w\d+(-c)?)|(h\d+(-c)?)|c/
option :name, 'google_oauth2'
option :skip_friends, true
@@ -49,8 +47,6 @@ module OmniAuth
prune!(
name: raw_info['name'],
email: verified_email,
- unverified_email: raw_info['email'],
- email_verified: raw_info['email_verified'],
first_name: raw_info['given_name'],
last_name: raw_info['family_name'],
image: image_url,
@@ -60,11 +56,6 @@ module OmniAuth
)
end
- credentials do
- # Tokens and expiration will be used from OAuth2 strategy credentials block
- prune!({ 'scope' => token_info(access_token.token)['scope'] })
- end
-
extra do
hash = {}
hash[:id_token] = access_token['id_token']
@@ -81,7 +72,7 @@ module OmniAuth
verify_sub: false,
verify_expiration: true,
verify_not_before: true,
- verify_iat: false,
+ verify_iat: true,
verify_jti: false,
leeway: options[:jwt_leeway])
@@ -101,51 +92,31 @@ module OmniAuth
verify_hd(access_token)
access_token
end
-
alias build_access_token custom_build_access_token
private
def callback_url
- options[:redirect_uri] || (full_host + callback_path)
+ options[:redirect_uri] || (full_host + script_name + callback_path)
end
def get_access_token(request)
- verifier = request.params['code']
- redirect_uri = request.params['redirect_uri']
- access_token = request.params['access_token']
- if verifier && request.xhr?
- client_get_token(verifier, redirect_uri || 'postmessage')
- elsif verifier
- client_get_token(verifier, redirect_uri || callback_url)
- elsif access_token && verify_token(access_token)
+ if request.xhr? && request.params['code']
+ verifier = request.params['code']
+ redirect_uri = request.params['redirect_uri'] || 'postmessage'
+ client.auth_code.get_token(verifier, get_token_options(redirect_uri), deep_symbolize(options.auth_token_params || {}))
+ elsif request.params['code'] && request.params['redirect_uri']
+ verifier = request.params['code']
+ redirect_uri = request.params['redirect_uri']
+ client.auth_code.get_token(verifier, get_token_options(redirect_uri), deep_symbolize(options.auth_token_params || {}))
+ elsif verify_token(request.params['access_token'])
::OAuth2::AccessToken.from_hash(client, request.params.dup)
- elsif request.content_type =~ /json/i
- begin
- body = JSON.parse(request.body.read)
- request.body.rewind # rewind request body for downstream middlewares
- verifier = body && body['code']
- access_token = body && body['access_token']
- redirect_uri ||= body && body['redirect_uri']
- if verifier
- client_get_token(verifier, redirect_uri || 'postmessage')
- elsif verify_token(access_token)
- ::OAuth2::AccessToken.from_hash(client, body.dup)
- end
- rescue JSON::ParserError => e
- warn "[omniauth google-oauth2] JSON parse error=#{e}"
- end
+ else
+ verifier = request.params['code']
+ client.auth_code.get_token(verifier, get_token_options(callback_url), deep_symbolize(options.auth_token_params))
end
end
- def client_get_token(verifier, redirect_uri)
- client.auth_code.get_token(verifier, get_token_options(redirect_uri), get_token_params)
- end
-
- def get_token_params
- deep_symbolize(options.auth_token_params || {})
- end
-
def get_scope(params)
raw_scope = params[:scope] || DEFAULT_SCOPE
scope_list = raw_scope.split(' ').map { |item| item.split(',') }.flatten
@@ -153,11 +124,7 @@ module OmniAuth
scope_list.join(' ')
end
- def verified_email
- raw_info['email_verified'] ? raw_info['email'] : nil
- end
-
- def get_token_options(redirect_uri = '')
+ def get_token_options(redirect_uri)
{ redirect_uri: redirect_uri }.merge(token_params.to_hash(symbolize_keys: true))
end
@@ -168,6 +135,10 @@ module OmniAuth
end
end
+ def verified_email
+ raw_info['email_verified'] ? raw_info['email'] : nil
+ end
+
def image_url
return nil unless raw_info['picture']
@@ -178,10 +149,6 @@ module OmniAuth
if path_index && image_size_opts_passed?
u.path.insert(path_index, image_params)
u.path = u.path.gsub('//', '/')
-
- # Check if the image is already sized!
- split_path = u.path.split('/')
- u.path = u.path.sub("/#{split_path[-3]}", '') if split_path[-3] =~ IMAGE_SIZE_REGEXP
end
u.query = strip_unnecessary_query_parameters(u.query)
@@ -220,21 +187,12 @@ module OmniAuth
URI.encode_www_form(stripped_params)
end
- def token_info(access_token)
- return nil unless access_token
-
- @token_info ||= Hash.new do |h, k|
- h[k] = client.request(:get, 'https://www.googleapis.com/oauth2/v3/tokeninfo', params: { access_token: access_token }).parsed
- end
-
- @token_info[access_token]
- end
-
def verify_token(access_token)
return false unless access_token
- token_info = token_info(access_token)
- token_info['aud'] == options.client_id || options.authorized_client_ids.include?(token_info['aud'])
+ raw_response = client.request(:get, 'https://www.googleapis.com/oauth2/v3/tokeninfo',
+ params: { access_token: access_token }).parsed
+ raw_response['aud'] == options.client_id || options.authorized_client_ids.include?(raw_response['aud'])
end
def verify_hd(access_token)
diff --git a/vendor/gems/omniauth-google-oauth2/omniauth-google-oauth2.gemspec b/vendor/gems/omniauth-google-oauth2/omniauth-google-oauth2.gemspec
index a50d67bc9a0..fb66d7ee282 100644
--- a/vendor/gems/omniauth-google-oauth2/omniauth-google-oauth2.gemspec
+++ b/vendor/gems/omniauth-google-oauth2/omniauth-google-oauth2.gemspec
@@ -15,15 +15,14 @@ Gem::Specification.new do |gem|
gem.email = ['quest@mac.com']
gem.homepage = 'https://github.com/zquestz/omniauth-google-oauth2'
- gem.files = Dir.glob("lib/**/*.*")
+ gem.files = Dir.glob("lib/**/*.*")
gem.require_paths = ['lib']
- gem.required_ruby_version = '>= 2.2'
+ gem.required_ruby_version = '>= 2.1'
gem.add_runtime_dependency 'jwt', '>= 2.0'
- gem.add_runtime_dependency 'oauth2', '~> 2.0'
- gem.add_runtime_dependency 'omniauth', '~> 2.0'
- gem.add_runtime_dependency 'omniauth-oauth2', '~> 1.7.1'
+ gem.add_runtime_dependency 'omniauth', '>= 1.9', '< 3'
+ gem.add_runtime_dependency 'omniauth-oauth2', '>= 1.5'
gem.add_development_dependency 'rake', '~> 12.0'
gem.add_development_dependency 'rspec', '~> 3.6'
diff --git a/vendor/gems/omniauth-google-oauth2/spec/omniauth/strategies/google_oauth2_spec.rb b/vendor/gems/omniauth-google-oauth2/spec/omniauth/strategies/google_oauth2_spec.rb
index 3a2bcf07e54..6bc6f6d9e95 100644
--- a/vendor/gems/omniauth-google-oauth2/spec/omniauth/strategies/google_oauth2_spec.rb
+++ b/vendor/gems/omniauth-google-oauth2/spec/omniauth/strategies/google_oauth2_spec.rb
@@ -3,7 +3,6 @@
require 'spec_helper'
require 'json'
require 'omniauth-google-oauth2'
-require 'stringio'
describe OmniAuth::Strategies::GoogleOauth2 do
let(:request) { double('Request', params: {}, cookies: {}, env: {}) }
@@ -178,8 +177,8 @@ describe OmniAuth::Strategies::GoogleOauth2 do
describe 'scope' do
it 'should expand scope shortcuts' do
- @options = { scope: 'calendar' }
- expect(subject.authorize_params['scope']).to eq('https://www.googleapis.com/auth/calendar')
+ @options = { scope: 'plus.me' }
+ expect(subject.authorize_params['scope']).to eq('https://www.googleapis.com/auth/plus.me')
end
it 'should leave base scopes as is' do
@@ -289,92 +288,14 @@ describe OmniAuth::Strategies::GoogleOauth2 do
end
end
- describe '#callback_url' do
- let(:base_url) { 'https://example.com' }
-
+ describe '#callback_path' do
it 'has the correct default callback path' do
- allow(subject).to receive(:full_host) { base_url }
- allow(subject).to receive(:script_name) { '' }
- expect(subject.send(:callback_url)).to eq(base_url + '/auth/google_oauth2/callback')
- end
-
- it 'should set the callback path with script_name if present' do
- allow(subject).to receive(:full_host) { base_url }
- allow(subject).to receive(:script_name) { '/v1' }
- expect(subject.send(:callback_url)).to eq(base_url + '/v1/auth/google_oauth2/callback')
+ expect(subject.callback_path).to eq('/auth/google_oauth2/callback')
end
it 'should set the callback_path parameter if present' do
@options = { callback_path: '/auth/foo/callback' }
- allow(subject).to receive(:full_host) { base_url }
- allow(subject).to receive(:script_name) { '' }
- expect(subject.send(:callback_url)).to eq(base_url + '/auth/foo/callback')
- end
- end
-
- describe '#info' do
- let(:client) do
- OAuth2::Client.new('abc', 'def') do |builder|
- builder.request :url_encoded
- builder.adapter :test do |stub|
- stub.get('/oauth2/v3/userinfo') { [200, { 'content-type' => 'application/json' }, response_hash.to_json] }
- end
- end
- end
- let(:access_token) { OAuth2::AccessToken.from_hash(client, {}) }
- before { allow(subject).to receive(:access_token).and_return(access_token) }
-
- context 'with verified email' do
- let(:response_hash) do
- { email: 'something@domain.invalid', email_verified: true }
- end
-
- it 'should return equal email and unverified_email' do
- expect(subject.info[:email]).to eq('something@domain.invalid')
- expect(subject.info[:unverified_email]).to eq('something@domain.invalid')
- end
- end
-
- context 'with unverified email' do
- let(:response_hash) do
- { email: 'something@domain.invalid', email_verified: false }
- end
-
- it 'should return nil email, and correct unverified email' do
- expect(subject.info[:email]).to eq(nil)
- expect(subject.info[:unverified_email]).to eq('something@domain.invalid')
- end
- end
- end
-
- describe '#credentials' do
- let(:client) { OAuth2::Client.new('abc', 'def') }
- let(:access_token) { OAuth2::AccessToken.from_hash(client, access_token: 'valid_access_token', expires_at: 123_456_789, refresh_token: 'valid_refresh_token') }
- before(:each) do
- allow(subject).to receive(:access_token).and_return(access_token)
- subject.options.client_options[:connection_build] = proc do |builder|
- builder.request :url_encoded
- builder.adapter :test do |stub|
- stub.get('/oauth2/v3/tokeninfo?access_token=valid_access_token') do
- [200, { 'Content-Type' => 'application/json; charset=UTF-8' }, JSON.dump(
- aud: '000000000000.apps.googleusercontent.com',
- sub: '123456789',
- scope: 'profile email'
- )]
- end
- end
- end
- end
-
- it 'should return access token and (optionally) refresh token' do
- expect(subject.credentials.to_h).to \
- match(hash_including(
- 'token' => 'valid_access_token',
- 'refresh_token' => 'valid_refresh_token',
- 'scope' => 'profile email',
- 'expires_at' => 123_456_789,
- 'expires' => true
- ))
+ expect(subject.callback_path).to eq('/auth/foo/callback')
end
end
@@ -392,7 +313,7 @@ describe OmniAuth::Strategies::GoogleOauth2 do
before { allow(subject).to receive(:access_token).and_return(access_token) }
describe 'id_token' do
- shared_examples 'id_token issued by valid issuer' do |issuer|
+ shared_examples 'id_token issued by valid issuer' do |issuer| # rubocop:disable Metrics/BlockLength
context 'when the id_token is passed into the access token' do
let(:token_info) do
{
@@ -505,12 +426,6 @@ describe OmniAuth::Strategies::GoogleOauth2 do
expect(subject.info[:image]).to eq('https://lh3.googleusercontent.com/url/s50/photo.jpg')
end
- it 'should return the image with size specified in the `image_size` option when sizing is in the picture' do
- @options = { image_size: 50 }
- allow(subject).to receive(:raw_info) { { 'picture' => 'https://lh4.googleusercontent.com/url/s96-c/photo.jpg' } }
- expect(subject.info[:image]).to eq('https://lh4.googleusercontent.com/url/s50/photo.jpg')
- end
-
it 'should handle a picture with too many slashes correctly' do
@options = { image_size: 50 }
allow(subject).to receive(:raw_info) { { 'picture' => 'https://lh3.googleusercontent.com/url//photo.jpg' } }
@@ -541,48 +456,24 @@ describe OmniAuth::Strategies::GoogleOauth2 do
expect(subject.info[:image]).to eq('https://lh3.googleusercontent.com/url/w50-h40/photo.jpg')
end
- it 'should return the image with width and height specified in the `image_size` option when sizing is in the picture' do
- @options = { image_size: { width: 50, height: 40 } }
- allow(subject).to receive(:raw_info) { { 'picture' => 'https://lh3.googleusercontent.com/url/w100-h80-c/photo.jpg' } }
- expect(subject.info[:image]).to eq('https://lh3.googleusercontent.com/url/w50-h40/photo.jpg')
- end
-
it 'should return square image when `image_aspect_ratio` is specified' do
@options = { image_aspect_ratio: 'square' }
allow(subject).to receive(:raw_info) { { 'picture' => 'https://lh3.googleusercontent.com/url/photo.jpg' } }
expect(subject.info[:image]).to eq('https://lh3.googleusercontent.com/url/c/photo.jpg')
end
- it 'should return square image when `image_aspect_ratio` is specified and sizing is in the picture' do
- @options = { image_aspect_ratio: 'square' }
- allow(subject).to receive(:raw_info) { { 'picture' => 'https://lh3.googleusercontent.com/url/c/photo.jpg' } }
- expect(subject.info[:image]).to eq('https://lh3.googleusercontent.com/url/c/photo.jpg')
- end
-
it 'should return square sized image when `image_aspect_ratio` and `image_size` is set' do
@options = { image_aspect_ratio: 'square', image_size: 50 }
allow(subject).to receive(:raw_info) { { 'picture' => 'https://lh3.googleusercontent.com/url/photo.jpg' } }
expect(subject.info[:image]).to eq('https://lh3.googleusercontent.com/url/s50-c/photo.jpg')
end
- it 'should return square sized image when `image_aspect_ratio` and `image_size` is set and sizing is in the picture' do
- @options = { image_aspect_ratio: 'square', image_size: 50 }
- allow(subject).to receive(:raw_info) { { 'picture' => 'https://lh3.googleusercontent.com/url/s90/photo.jpg' } }
- expect(subject.info[:image]).to eq('https://lh3.googleusercontent.com/url/s50-c/photo.jpg')
- end
-
it 'should return square sized image when `image_aspect_ratio` and `image_size` has height and width' do
@options = { image_aspect_ratio: 'square', image_size: { width: 50, height: 40 } }
allow(subject).to receive(:raw_info) { { 'picture' => 'https://lh3.googleusercontent.com/url/photo.jpg' } }
expect(subject.info[:image]).to eq('https://lh3.googleusercontent.com/url/w50-h40-c/photo.jpg')
end
- it 'should return square sized image when `image_aspect_ratio` and `image_size` has height and width and sizing is in the picture' do
- @options = { image_aspect_ratio: 'square', image_size: { width: 50, height: 40 } }
- allow(subject).to receive(:raw_info) { { 'picture' => 'https://lh3.googleusercontent.com/url/w100-h80/photo.jpg' } }
- expect(subject.info[:image]).to eq('https://lh3.googleusercontent.com/url/w50-h40-c/photo.jpg')
- end
-
it 'should return original image if image url does not end in `photo.jpg`' do
@options = { image_size: 50 }
allow(subject).to receive(:raw_info) { { 'picture' => 'https://lh3.googleusercontent.com/url/photograph.jpg' } }
@@ -656,58 +547,9 @@ describe OmniAuth::Strategies::GoogleOauth2 do
expect(token.client).to eq(:client)
end
- it 'reads the code from a json request body' do
- body = StringIO.new(%({"code":"json_access_token"}))
- client = double(:client)
- auth_code = double(:auth_code)
-
- allow(request).to receive(:xhr?).and_return(false)
- allow(request).to receive(:content_type).and_return('application/json')
- allow(request).to receive(:body).and_return(body)
- allow(client).to receive(:auth_code).and_return(auth_code)
- expect(subject).to receive(:client).and_return(client)
-
- expect(auth_code).to receive(:get_token).with('json_access_token', { redirect_uri: 'postmessage' }, {})
-
- subject.build_access_token
- end
-
- it 'reads the redirect uri from a json request body' do
- body = StringIO.new(%({"code":"json_access_token", "redirect_uri":"sample"}))
- client = double(:client)
- auth_code = double(:auth_code)
-
- allow(request).to receive(:xhr?).and_return(false)
- allow(request).to receive(:content_type).and_return('application/json')
- allow(request).to receive(:body).and_return(body)
- allow(client).to receive(:auth_code).and_return(auth_code)
- expect(subject).to receive(:client).and_return(client)
-
- expect(auth_code).to receive(:get_token).with('json_access_token', { redirect_uri: 'sample' }, {})
-
- subject.build_access_token
- end
-
- it 'reads the access token from a json request body' do
- body = StringIO.new(%({"access_token":"valid_access_token"}))
-
- allow(request).to receive(:xhr?).and_return(false)
- allow(request).to receive(:content_type).and_return('application/json')
- allow(request).to receive(:body).and_return(body)
- expect(subject).to receive(:client).and_return(:client)
-
- expect(subject).to receive(:verify_token).with('valid_access_token').and_return true
-
- token = subject.build_access_token
- expect(token).to be_instance_of(::OAuth2::AccessToken)
- expect(token.token).to eq('valid_access_token')
- expect(token.client).to eq(:client)
- end
-
it 'should use callback_url without query_string if this is not an AJAX request' do
allow(request).to receive(:xhr?).and_return(false)
allow(request).to receive(:params).and_return('code' => 'valid_code')
- allow(request).to receive(:content_type).and_return('application/x-www-form-urlencoded')
client = double(:client)
auth_code = double(:auth_code)
diff --git a/vendor/gems/omniauth-salesforce/Gemfile.lock b/vendor/gems/omniauth-salesforce/Gemfile.lock
index 0317b16dd9f..0eb983bcd76 100644
--- a/vendor/gems/omniauth-salesforce/Gemfile.lock
+++ b/vendor/gems/omniauth-salesforce/Gemfile.lock
@@ -2,7 +2,7 @@ PATH
remote: .
specs:
omniauth-salesforce (1.0.5)
- omniauth (~> 2.0)
+ omniauth (~> 1.0, < 3)
omniauth-oauth2 (~> 1.0)
GEM
@@ -53,17 +53,16 @@ GEM
notiffany (0.1.3)
nenv (~> 0.1)
shellany (~> 0.0)
- oauth2 (2.0.3)
+ oauth2 (2.0.7)
faraday (>= 0.17.3, < 3.0)
jwt (>= 1.0, < 3.0)
multi_xml (~> 0.5)
rack (>= 1.2, < 3)
rash_alt (>= 0.4, < 1)
- version_gem (~> 1.0)
- omniauth (2.1.0)
+ version_gem (~> 1.1)
+ omniauth (1.9.2)
hashie (>= 3.4.6)
- rack (>= 2.2.3)
- rack-protection
+ rack (>= 1.6.2, < 3)
omniauth-oauth2 (1.7.3)
oauth2 (>= 1.4, < 3)
omniauth (>= 1.9, < 3)
@@ -72,8 +71,6 @@ GEM
method_source (~> 1.0)
public_suffix (5.0.0)
rack (2.2.4)
- rack-protection (2.2.2)
- rack
rack-test (2.0.2)
rack (>= 1.3)
rash_alt (0.4.12)
@@ -121,4 +118,4 @@ DEPENDENCIES
webmock
BUNDLED WITH
- 2.3.21
+ 2.3.20
diff --git a/vendor/gems/omniauth-salesforce/omniauth-salesforce.gemspec b/vendor/gems/omniauth-salesforce/omniauth-salesforce.gemspec
index 9c87746e9fd..0b9cfbd73ff 100755
--- a/vendor/gems/omniauth-salesforce/omniauth-salesforce.gemspec
+++ b/vendor/gems/omniauth-salesforce/omniauth-salesforce.gemspec
@@ -15,7 +15,7 @@ Gem::Specification.new do |gem|
gem.version = OmniAuth::Salesforce::VERSION
gem.license = "MIT"
- gem.add_dependency 'omniauth', '~> 2.0'
+ gem.add_dependency 'omniauth', '~> 1.0', '< 3'
gem.add_dependency 'omniauth-oauth2', '~> 1.0'
gem.add_development_dependency 'rspec', '~> 2.7'
gem.add_development_dependency 'rack-test'
diff --git a/vendor/gems/omniauth_crowd/Gemfile.lock b/vendor/gems/omniauth_crowd/Gemfile.lock
index 43518582535..56c9bd4cc7e 100644
--- a/vendor/gems/omniauth_crowd/Gemfile.lock
+++ b/vendor/gems/omniauth_crowd/Gemfile.lock
@@ -4,7 +4,7 @@ PATH
omniauth_crowd (2.4.0)
activesupport
nokogiri (>= 1.4.4)
- omniauth (~> 2.0)
+ omniauth (~> 1.0, < 3)
GEM
remote: http://rubygems.org/
@@ -29,15 +29,12 @@ GEM
nokogiri (1.13.8)
mini_portile2 (~> 2.8.0)
racc (~> 1.4)
- omniauth (2.1.0)
+ omniauth (1.9.1)
hashie (>= 3.4.6)
- rack (>= 2.2.3)
- rack-protection
+ rack (>= 1.6.2, < 3)
public_suffix (4.0.7)
racc (1.6.0)
rack (2.2.4)
- rack-protection (2.2.2)
- rack
rack-test (2.0.2)
rack (>= 1.3)
rake (13.0.6)
diff --git a/vendor/gems/omniauth_crowd/omniauth_crowd.gemspec b/vendor/gems/omniauth_crowd/omniauth_crowd.gemspec
index dcbf403419f..1707c7f3f10 100644
--- a/vendor/gems/omniauth_crowd/omniauth_crowd.gemspec
+++ b/vendor/gems/omniauth_crowd/omniauth_crowd.gemspec
@@ -15,7 +15,7 @@ Gem::Specification.new do |gem|
gem.require_paths = ["lib"]
gem.version = OmniAuth::Crowd::VERSION
- gem.add_runtime_dependency 'omniauth', '~> 2.0'
+ gem.add_runtime_dependency 'omniauth', '~> 1.0', '< 3'
gem.add_runtime_dependency 'nokogiri', '>= 1.4.4'
gem.add_runtime_dependency 'activesupport', '>= 0'
gem.add_development_dependency(%q<rack>, [">= 0"])