diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-04-07 21:08:29 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-04-07 21:08:29 +0300 |
commit | c2bdb9d02768a61bee7560113f4d4c83dc91338e (patch) | |
tree | e242f8d39df80ec39a59eb73ad96ee389c8a4d41 | |
parent | fe4751154c331e35c0e6575a3aedc02b210a1c63 (diff) |
Add latest changes from gitlab-org/gitlab@master
68 files changed, 1795 insertions, 931 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ac072f69b5b..c62de7d7ab0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -16,7 +16,7 @@ stages: # in cases where jobs require Docker-in-Docker, the job # definition must be extended with `.use-docker-in-docker` default: - image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:debian-${DEBIAN_VERSION}-ruby-2.7.patched-golang-1.16-git-2.33-lfs-2.9-chrome-97-node-16.14-yarn-1.22-postgresql-11-graphicsmagick-1.3.36 + image: $DEFAULT_CI_IMAGE tags: - gitlab-org # All jobs are interruptible by default @@ -58,6 +58,8 @@ workflow: - if: '$CI_COMMIT_BRANCH =~ /^security\//' variables: + PG_VERSION: "12" + DEFAULT_CI_IMAGE: "${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:debian-${DEBIAN_VERSION}-ruby-2.7.patched-golang-1.16-git-2.33-lfs-2.9-chrome-97-node-16.14-yarn-1.22-postgresql-${PG_VERSION}-graphicsmagick-1.3.36" RAILS_ENV: "test" NODE_ENV: "test" BUNDLE_WITHOUT: "production:development" diff --git a/.gitlab/ci/global.gitlab-ci.yml b/.gitlab/ci/global.gitlab-ci.yml index 96f81a7feee..4069dfe9a2b 100644 --- a/.gitlab/ci/global.gitlab-ci.yml +++ b/.gitlab/ci/global.gitlab-ci.yml @@ -44,16 +44,16 @@ - lib/gitlab/setup_helper.rb prefix: "gitaly-binaries-${DEBIAN-VERSION}" paths: - - tmp/tests/gitaly/_build/bin/ - - tmp/tests/gitaly/_build/deps/git/install/ - - tmp/tests/gitaly/config.toml - - tmp/tests/gitaly/gitaly2.config.toml - - tmp/tests/gitaly/internal/ - - tmp/tests/gitaly/run/ - - tmp/tests/gitaly/run2/ - - tmp/tests/gitaly/Makefile - - tmp/tests/gitaly/praefect.config.toml - - tmp/tests/gitaly/ruby/ + - ${TMP_TEST_FOLDER}/gitaly/_build/bin/ + - ${TMP_TEST_FOLDER}/gitaly/_build/deps/git/install/ + - ${TMP_TEST_FOLDER}/gitaly/config.toml + - ${TMP_TEST_FOLDER}/gitaly/gitaly2.config.toml + - ${TMP_TEST_FOLDER}/gitaly/internal/ + - ${TMP_TEST_FOLDER}/gitaly/run/ + - ${TMP_TEST_FOLDER}/gitaly/run2/ + - ${TMP_TEST_FOLDER}/gitaly/Makefile + - ${TMP_TEST_FOLDER}/gitaly/praefect.config.toml + - ${TMP_TEST_FOLDER}/gitaly/ruby/ policy: pull .go-pkg-cache: &go-pkg-cache @@ -214,34 +214,33 @@ - *storybook-node-modules-cache-push .use-pg11: - image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:debian-${DEBIAN_VERSION}-ruby-2.7.patched-golang-1.16-git-2.33-lfs-2.9-chrome-97-node-16.14-yarn-1.22-postgresql-11-graphicsmagick-1.3.36 services: - name: postgres:11.6 command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"] - name: redis:5.0-alpine variables: POSTGRES_HOST_AUTH_METHOD: trust + PG_VERSION: "11" .use-pg12: - image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:debian-${DEBIAN_VERSION}-ruby-2.7.patched-golang-1.16-git-2.33-lfs-2.9-chrome-97-node-16.14-yarn-1.22-postgresql-12-graphicsmagick-1.3.36 services: - name: postgres:12 command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"] - name: redis:6.0-alpine variables: POSTGRES_HOST_AUTH_METHOD: trust + PG_VERSION: "12" .use-pg13: - image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:debian-${DEBIAN_VERSION}-ruby-2.7.patched-golang-1.16-git-2.33-lfs-2.9-chrome-97-node-16.14-yarn-1.22-postgresql-13-graphicsmagick-1.3.36 services: - name: postgres:13 command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"] - name: redis:5.0-alpine variables: POSTGRES_HOST_AUTH_METHOD: trust + PG_VERSION: "13" .use-pg11-ee: - image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:debian-${DEBIAN_VERSION}-ruby-2.7.patched-golang-1.16-git-2.33-lfs-2.9-chrome-97-node-16.14-yarn-1.22-postgresql-11-graphicsmagick-1.3.36 services: - name: postgres:11.6 command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"] @@ -250,9 +249,9 @@ command: ["elasticsearch", "-E", "discovery.type=single-node"] variables: POSTGRES_HOST_AUTH_METHOD: trust + PG_VERSION: "11" .use-pg12-ee: - image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:debian-${DEBIAN_VERSION}-ruby-2.7.patched-golang-1.16-git-2.33-lfs-2.9-chrome-97-node-16.14-yarn-1.22-postgresql-12-graphicsmagick-1.3.36 services: - name: postgres:12 command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"] @@ -261,9 +260,9 @@ command: ["elasticsearch", "-E", "discovery.type=single-node"] variables: POSTGRES_HOST_AUTH_METHOD: trust + PG_VERSION: "12" .use-pg13-ee: - image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:debian-${DEBIAN_VERSION}-ruby-2.7.patched-golang-1.16-git-2.33-lfs-2.9-chrome-97-node-16.14-yarn-1.22-postgresql-13-graphicsmagick-1.3.36 services: - name: postgres:13 command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"] @@ -272,6 +271,7 @@ command: ["elasticsearch", "-E", "discovery.type=single-node"] variables: POSTGRES_HOST_AUTH_METHOD: trust + PG_VERSION: "13" .use-kaniko: image: diff --git a/.haml-lint.yml b/.haml-lint.yml index 8d084a0c356..75139cb43dd 100644 --- a/.haml-lint.yml +++ b/.haml-lint.yml @@ -124,7 +124,6 @@ linters: - Performance/RedundantMatch - Performance/StringReplacement - Rails/LinkToBlank - - Rails/Presence - Rails/RequestReferer - Style/ColonMethodCall - Style/ConditionalAssignment diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 502534e5010..d041ce385e3 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -25,15 +25,6 @@ Layout/MultilineOperationIndentation: Layout/SpaceInLambdaLiteral: Enabled: false -# Offense count: 1209 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters. -# SupportedStyles: space, no_space -# SupportedStylesForEmptyBraces: space, no_space -Layout/SpaceInsideBlockBraces: - Enabled: false - EnforcedStyle: space - # Offense count: 585 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. @@ -41,22 +32,6 @@ Layout/SpaceInsideBlockBraces: Layout/SpaceInsideParens: Enabled: false -# Offense count: 18 -Lint/BinaryOperatorWithIdenticalOperands: - Exclude: - - 'ee/spec/lib/ee/gitlab/application_context_spec.rb' - - 'spec/helpers/visibility_level_helper_spec.rb' - - 'spec/lib/gitlab/conan_token_spec.rb' - - 'spec/lib/gitlab/git/conflict/parser_spec.rb' - - 'spec/lib/gitlab/graphql/lazy_spec.rb' - - 'spec/models/ci/build_trace_chunk_spec.rb' - - 'spec/models/clusters/platforms/kubernetes_spec.rb' - - 'spec/models/concerns/where_composite_spec.rb' - - 'spec/models/metrics/dashboard/annotation_spec.rb' - - 'spec/models/repository_spec.rb' - - 'spec/models/ssh_host_key_spec.rb' - - 'spec/tooling/danger/sidekiq_queues_spec.rb' - # Offense count: 84 Lint/ConstantDefinitionInBlock: Enabled: false diff --git a/.rubocop_todo/layout/space_inside_block_braces.yml b/.rubocop_todo/layout/space_inside_block_braces.yml new file mode 100644 index 00000000000..fc838ccadd8 --- /dev/null +++ b/.rubocop_todo/layout/space_inside_block_braces.yml @@ -0,0 +1,770 @@ +--- +# Cop supports --auto-correct. +Layout/SpaceInsideBlockBraces: + # Offense count: 1508 + # Temporarily disabled due to too many offenses + Enabled: false + EnforcedStyle: space + Exclude: + - 'app/controllers/groups/boards_controller.rb' + - 'app/controllers/profiles/two_factor_auths_controller.rb' + - 'app/controllers/projects/boards_controller.rb' + - 'app/experiments/security_reports_mr_widget_prompt_experiment.rb' + - 'app/experiments/video_tutorials_continuous_onboarding_experiment.rb' + - 'app/graphql/types/concerns/find_closest.rb' + - 'app/helpers/favicon_helper.rb' + - 'app/helpers/time_zone_helper.rb' + - 'app/helpers/todos_helper.rb' + - 'app/models/authentication_event.rb' + - 'app/models/bulk_imports/entity.rb' + - 'app/models/ci/pipeline.rb' + - 'app/models/concerns/cache_markdown_field.rb' + - 'app/models/concerns/featurable.rb' + - 'app/models/integrations/bamboo.rb' + - 'app/models/integrations/buildkite.rb' + - 'app/models/integrations/teamcity.rb' + - 'app/models/network/graph.rb' + - 'app/models/operations/feature_flag.rb' + - 'app/models/packages/package.rb' + - 'app/models/preloaders/labels_preloader.rb' + - 'app/models/project.rb' + - 'app/models/release.rb' + - 'app/models/release_highlight.rb' + - 'app/services/authorized_project_update/project_recalculate_service.rb' + - 'app/services/notification_service.rb' + - 'config/initializers/wikicloth_redos_patch.rb' + - 'db/post_migrate/20210707210916_finalize_ci_stages_bigint_conversion.rb' + - 'db/post_migrate/20210802043253_finalize_push_event_payloads_bigint_conversion_3.rb' + - 'ee/app/finders/security/training_providers/base_url_finder.rb' + - 'ee/app/graphql/mutations/incident_management/oncall_rotation/base.rb' + - 'ee/app/helpers/ee/dashboard_helper.rb' + - 'ee/app/models/approvals/scan_finding_wrapped_rule_set.rb' + - 'ee/app/models/compliance_management/framework.rb' + - 'ee/app/models/dora/daily_metrics.rb' + - 'ee/app/models/ee/application_setting.rb' + - 'ee/app/models/ee/member.rb' + - 'ee/app/models/vulnerabilities/identifier.rb' + - 'ee/app/serializers/vulnerabilities/finding_entity.rb' + - 'ee/app/services/elastic/cluster_reindexing_service.rb' + - 'ee/lib/ee/banzai/filter/references/iteration_reference_filter.rb' + - 'ee/lib/ee/gitlab/auth/ldap/group.rb' + - 'ee/lib/ee/gitlab/background_migration/drop_invalid_remediations.rb' + - 'ee/lib/elastic/latest/git_class_proxy.rb' + - 'ee/lib/gitlab/auth/smartcard/san_extension.rb' + - 'ee/lib/pseudonymizer/dumper.rb' + - 'ee/lib/world.rb' + - 'ee/spec/controllers/autocomplete_controller_spec.rb' + - 'ee/spec/controllers/countries_controller_spec.rb' + - 'ee/spec/controllers/groups/epics_controller_spec.rb' + - 'ee/spec/controllers/projects/issues_controller_spec.rb' + - 'ee/spec/controllers/projects/pipelines_controller_spec.rb' + - 'ee/spec/controllers/subscriptions_controller_spec.rb' + - 'ee/spec/elastic_integration/global_search_spec.rb' + - 'ee/spec/factories/dast/profiles_pipelines.rb' + - 'ee/spec/factories/licenses.rb' + - 'ee/spec/features/billings/billing_plans_spec.rb' + - 'ee/spec/features/boards/board_filters_spec.rb' + - 'ee/spec/features/boards/scoped_issue_board_spec.rb' + - 'ee/spec/features/boards/swimlanes/epics_swimlanes_filtering_spec.rb' + - 'ee/spec/features/epics/todo_spec.rb' + - 'ee/spec/features/google_analytics_datalayer_spec.rb' + - 'ee/spec/features/groups/issues_spec.rb' + - 'ee/spec/features/issues/filtered_search/filter_issues_by_iteration_spec.rb' + - 'ee/spec/features/issues/form_spec.rb' + - 'ee/spec/features/issues/issue_sidebar_spec.rb' + - 'ee/spec/features/issues/user_edits_issue_spec.rb' + - 'ee/spec/features/merge_request/user_edits_multiple_reviewers_mr_spec.rb' + - 'ee/spec/features/merge_request/user_sees_closing_issues_message_spec.rb' + - 'ee/spec/features/merge_requests/user_resets_approvers_spec.rb' + - 'ee/spec/features/merge_requests/user_views_all_merge_requests_spec.rb' + - 'ee/spec/features/projects/integrations/user_activates_github_spec.rb' + - 'ee/spec/features/projects/push_rules_spec.rb' + - 'ee/spec/features/projects/security/dast_scanner_profiles_spec.rb' + - 'ee/spec/features/projects/security/dast_site_profiles_spec.rb' + - 'ee/spec/features/projects/settings/ee/service_desk_setting_spec.rb' + - 'ee/spec/finders/billed_users_finder_spec.rb' + - 'ee/spec/finders/clusters/environments_finder_spec.rb' + - 'ee/spec/finders/dast/profiles_finder_spec.rb' + - 'ee/spec/finders/ee/namespaces/projects_finder_spec.rb' + - 'ee/spec/finders/security/pipeline_vulnerabilities_finder_spec.rb' + - 'ee/spec/finders/security/training_providers/kontra_url_finder_spec.rb' + - 'ee/spec/finders/security/vulnerabilities_finder_spec.rb' + - 'ee/spec/finders/security/vulnerability_reads_finder_spec.rb' + - 'ee/spec/finders/status_page/incidents_finder_spec.rb' + - 'ee/spec/frontend/fixtures/epic.rb' + - 'ee/spec/frontend/fixtures/projects.rb' + - 'ee/spec/graphql/ee/resolvers/namespace_projects_resolver_spec.rb' + - 'ee/spec/graphql/mutations/boards/epics/create_spec.rb' + - 'ee/spec/graphql/mutations/compliance_management/frameworks/destroy_spec.rb' + - 'ee/spec/graphql/mutations/dast_site_validations/revoke_spec.rb' + - 'ee/spec/graphql/mutations/incident_management/escalation_policy/create_spec.rb' + - 'ee/spec/graphql/mutations/releases/update_spec.rb' + - 'ee/spec/graphql/mutations/vulnerabilities/destroy_external_issue_link_spec.rb' + - 'ee/spec/graphql/resolvers/iterations_resolver_spec.rb' + - 'ee/spec/helpers/ee/projects/pipeline_helper_spec.rb' + - 'ee/spec/helpers/ee/projects/security/dast_configuration_helper_spec.rb' + - 'ee/spec/helpers/ee/registrations_helper_spec.rb' + - 'ee/spec/helpers/ee/trial_helper_spec.rb' + - 'ee/spec/helpers/projects/on_demand_scans_helper_spec.rb' + - 'ee/spec/lib/analytics/group_activity_calculator_spec.rb' + - 'ee/spec/lib/ee/gitlab/alert_management/payload/generic_spec.rb' + - 'ee/spec/lib/ee/gitlab/background_migration/drop_invalid_remediations_spec.rb' + - 'ee/spec/lib/ee/gitlab/background_migration/migrate_job_artifact_registry_to_ssf_spec.rb' + - 'ee/spec/lib/ee/gitlab/ci/reports/security/reports_spec.rb' + - 'ee/spec/lib/ee/gitlab/import_export/group/tree_saver_spec.rb' + - 'ee/spec/lib/ee/gitlab/import_export/project/tree_restorer_spec.rb' + - 'ee/spec/lib/ee/gitlab/usage_data_counters/issue_activity_unique_counter_spec.rb' + - 'ee/spec/lib/ee/sidebars/groups/menus/issues_menu_spec.rb' + - 'ee/spec/lib/ee/sidebars/groups/menus/settings_menu_spec.rb' + - 'ee/spec/lib/ee/sidebars/projects/menus/ci_cd_menu_spec.rb' + - 'ee/spec/lib/ee/sidebars/projects/menus/issues_menu_spec.rb' + - 'ee/spec/lib/ee/sidebars/projects/menus/repository_menu_spec.rb' + - 'ee/spec/lib/gitlab/auth/group_saml/gma_membership_enforcer_spec.rb' + - 'ee/spec/lib/gitlab/auth/otp/session_enforcer_spec.rb' + - 'ee/spec/lib/gitlab/ci/parsers/security/container_scanning_spec.rb' + - 'ee/spec/lib/gitlab/ci/reports/license_scanning/dependency_spec.rb' + - 'ee/spec/lib/gitlab/ci/reports/security/finding_spec.rb' + - 'ee/spec/lib/gitlab/ci/templates/dependency_scanning_gitlab_ci_yaml_spec.rb' + - 'ee/spec/lib/gitlab/email/handler/create_note_handler_spec.rb' + - 'ee/spec/lib/gitlab/geo/git_ssh_proxy_spec.rb' + - 'ee/spec/lib/gitlab/geo/log_cursor/events/repository_renamed_event_spec.rb' + - 'ee/spec/lib/gitlab/git_access_spec.rb' + - 'ee/spec/lib/gitlab/graphql/loaders/bulk_epic_aggregate_loader_spec.rb' + - 'ee/spec/lib/gitlab/ip_address_state_spec.rb' + - 'ee/spec/lib/gitlab/search_context/builder_spec.rb' + - 'ee/spec/lib/gitlab/status_page/filter/image_filter_spec.rb' + - 'ee/spec/lib/gitlab/usage/metrics/instrumentations/approval_project_rules_with_user_metric_spec.rb' + - 'ee/spec/lib/pseudonymizer/pager_spec.rb' + - 'ee/spec/lib/pseudonymizer/uploader_spec.rb' + - 'ee/spec/mailers/credentials_inventory_mailer_spec.rb' + - 'ee/spec/migrations/geo/migrate_job_artifact_registry_spec.rb' + - 'ee/spec/models/analytics/devops_adoption/enabled_namespace_spec.rb' + - 'ee/spec/models/analytics/devops_adoption/snapshot_spec.rb' + - 'ee/spec/models/approval_project_rule_spec.rb' + - 'ee/spec/models/approval_state_spec.rb' + - 'ee/spec/models/approvals/scan_finding_wrapped_rule_set_spec.rb' + - 'ee/spec/models/ci/minutes/limit_spec.rb' + - 'ee/spec/models/compliance_management/framework_spec.rb' + - 'ee/spec/models/concerns/ee/clusters/agents/authorization_config_scopes_spec.rb' + - 'ee/spec/models/concerns/elastic/issue_spec.rb' + - 'ee/spec/models/dast/profile_schedule_spec.rb' + - 'ee/spec/models/ee/audit_event_spec.rb' + - 'ee/spec/models/ee/ci/build_dependencies_spec.rb' + - 'ee/spec/models/ee/iteration_spec.rb' + - 'ee/spec/models/ee/namespace/root_storage_size_spec.rb' + - 'ee/spec/models/ee/namespace_limit_spec.rb' + - 'ee/spec/models/environment_spec.rb' + - 'ee/spec/models/epic_spec.rb' + - 'ee/spec/models/gitlab/seat_link_data_spec.rb' + - 'ee/spec/models/gitlab_subscription_spec.rb' + - 'ee/spec/models/member_spec.rb' + - 'ee/spec/models/milestone_release_spec.rb' + - 'ee/spec/models/project_member_spec.rb' + - 'ee/spec/models/protected_environment_spec.rb' + - 'ee/spec/models/push_rule_spec.rb' + - 'ee/spec/models/requirements_management/test_report_spec.rb' + - 'ee/spec/models/security/orchestration_policy_rule_schedule_spec.rb' + - 'ee/spec/models/vulnerabilities/feedback_spec.rb' + - 'ee/spec/models/vulnerabilities/finding_spec.rb' + - 'ee/spec/presenters/epic_issue_presenter_spec.rb' + - 'ee/spec/requests/api/analytics/code_review_analytics_spec.rb' + - 'ee/spec/requests/api/analytics/group_activity_analytics_spec.rb' + - 'ee/spec/requests/api/ci/minutes_spec.rb' + - 'ee/spec/requests/api/epic_links_spec.rb' + - 'ee/spec/requests/api/graphql/boards/board_lists_query_spec.rb' + - 'ee/spec/requests/api/graphql/group/epic/epic_aggregate_query_spec.rb' + - 'ee/spec/requests/api/graphql/group/epic/epic_issues_spec.rb' + - 'ee/spec/requests/api/graphql/group_query_spec.rb' + - 'ee/spec/requests/api/graphql/iteration_spec.rb' + - 'ee/spec/requests/api/graphql/mutations/dast_site_validations/revoke_spec.rb' + - 'ee/spec/requests/api/graphql/mutations/epic_tree/reorder_spec.rb' + - 'ee/spec/requests/api/graphql/mutations/incident_management/oncall_rotation/update_spec.rb' + - 'ee/spec/requests/api/graphql/mutations/releases/create_spec.rb' + - 'ee/spec/requests/api/graphql/mutations/releases/update_spec.rb' + - 'ee/spec/requests/api/graphql/project/dast_profiles_spec.rb' + - 'ee/spec/requests/api/graphql/project/dast_site_validations_spec.rb' + - 'ee/spec/requests/api/graphql/project/issues_spec.rb' + - 'ee/spec/requests/api/graphql/projects/compliance_frameworks_spec.rb' + - 'ee/spec/requests/api/group_variables_spec.rb' + - 'ee/spec/requests/api/internal/base_spec.rb' + - 'ee/spec/requests/api/managed_licenses_spec.rb' + - 'ee/spec/requests/api/members_spec.rb' + - 'ee/spec/requests/api/projects_spec.rb' + - 'ee/spec/requests/api/protected_branches_spec.rb' + - 'ee/spec/requests/api/releases_spec.rb' + - 'ee/spec/requests/groups/contribution_analytics_spec.rb' + - 'ee/spec/requests/lfs_http_spec.rb' + - 'ee/spec/requests/projects/security/policies_controller_spec.rb' + - 'ee/spec/requests/survey_responses_controller_spec.rb' + - 'ee/spec/serializers/member_user_entity_spec.rb' + - 'ee/spec/serializers/merge_request_poll_widget_entity_spec.rb' + - 'ee/spec/serializers/vulnerabilities/finding_reports_comparer_entity_spec.rb' + - 'ee/spec/services/audit_events/register_runner_audit_event_service_spec.rb' + - 'ee/spec/services/audit_events/unregister_runner_audit_event_service_spec.rb' + - 'ee/spec/services/auto_merge/add_to_merge_train_when_pipeline_succeeds_service_spec.rb' + - 'ee/spec/services/auto_merge/merge_train_service_spec.rb' + - 'ee/spec/services/ci/runners/register_runner_service_spec.rb' + - 'ee/spec/services/ee/design_management/delete_designs_service_spec.rb' + - 'ee/spec/services/ee/design_management/save_designs_service_spec.rb' + - 'ee/spec/services/ee/issuable/bulk_update_service_spec.rb' + - 'ee/spec/services/ee/notes/quick_actions_service_spec.rb' + - 'ee/spec/services/ee/notification_service_spec.rb' + - 'ee/spec/services/ee/vulnerability_feedback_module/update_service_spec.rb' + - 'ee/spec/services/epic_issues/create_service_spec.rb' + - 'ee/spec/services/epics/create_service_spec.rb' + - 'ee/spec/services/epics/descendant_count_service_spec.rb' + - 'ee/spec/services/epics/transfer_service_spec.rb' + - 'ee/spec/services/geo/container_repository_sync_service_spec.rb' + - 'ee/spec/services/geo/framework_repository_sync_service_spec.rb' + - 'ee/spec/services/geo/hashed_storage_attachments_event_store_spec.rb' + - 'ee/spec/services/geo/repository_sync_service_spec.rb' + - 'ee/spec/services/geo/wiki_sync_service_spec.rb' + - 'ee/spec/services/gitlab_subscriptions/activate_service_spec.rb' + - 'ee/spec/services/gitlab_subscriptions/apply_trial_service_spec.rb' + - 'ee/spec/services/group_saml/sign_up_service_spec.rb' + - 'ee/spec/services/groups/epics_count_service_spec.rb' + - 'ee/spec/services/groups/memberships/export_service_spec.rb' + - 'ee/spec/services/iterations/cadences/create_iterations_in_advance_service_spec.rb' + - 'ee/spec/services/merge_trains/check_status_service_spec.rb' + - 'ee/spec/services/personal_access_tokens/groups/update_lifetime_service_spec.rb' + - 'ee/spec/services/projects/destroy_service_spec.rb' + - 'ee/spec/services/projects/update_mirror_service_spec.rb' + - 'ee/spec/services/quick_actions/interpret_service_spec.rb' + - 'ee/spec/services/requirements_management/create_requirement_service_spec.rb' + - 'ee/spec/services/requirements_management/update_requirement_service_spec.rb' + - 'ee/spec/services/resource_access_tokens/create_service_spec.rb' + - 'ee/spec/services/search/group_service_spec.rb' + - 'ee/spec/services/security/ingestion/tasks/ingest_findings_spec.rb' + - 'ee/spec/services/security/security_orchestration_policies/policy_commit_service_spec.rb' + - 'ee/spec/services/sitemap/create_service_spec.rb' + - 'ee/spec/services/software_license_policies/update_service_spec.rb' + - 'ee/spec/services/status_page/publish_attachments_service_spec.rb' + - 'ee/spec/services/system_notes/epics_service_spec.rb' + - 'ee/spec/services/vulnerability_external_issue_links/create_service_spec.rb' + - 'ee/spec/services/vulnerability_feedback/destroy_service_spec.rb' + - 'ee/spec/support/shared_examples/features/ultimate_trial_callout_shared_examples.rb' + - 'ee/spec/support/shared_examples/requests/api/project_approval_rules_api_shared_examples.rb' + - 'ee/spec/support/shared_examples/services/base_sync_service_shared_examples.rb' + - 'ee/spec/support/shared_examples/services/boards/base_service_shared_examples.rb' + - 'ee/spec/support/shared_examples/services/search_notes_shared_examples.rb' + - 'ee/spec/tasks/gitlab/elastic_rake_spec.rb' + - 'ee/spec/uploaders/every_gitlab_uploader_spec.rb' + - 'ee/spec/views/registrations/groups_projects/new.html.haml_spec.rb' + - 'ee/spec/views/shared/billings/_eoa_bronze_plan_banner.html.haml_spec.rb' + - 'ee/spec/views/shared/credentials_inventory/_expiry_date.html.haml_spec.rb' + - 'ee/spec/views/shared/credentials_inventory/personal_access_tokens/_personal_access_token.html.haml_spec.rb' + - 'ee/spec/views/shared/credentials_inventory/ssh_keys/_ssh_key.html.haml_spec.rb' + - 'ee/spec/workers/adjourned_project_deletion_worker_spec.rb' + - 'ee/spec/workers/adjourned_projects_deletion_cron_worker_spec.rb' + - 'ee/spec/workers/security/create_orchestration_policy_worker_spec.rb' + - 'ee/spec/workers/security/orchestration_policy_rule_schedule_worker_spec.rb' + - 'lib/api/commits.rb' + - 'lib/api/helpers/merge_requests_helpers.rb' + - 'lib/backup/manager.rb' + - 'lib/banzai/filter/references/label_reference_filter.rb' + - 'lib/banzai/filter/references/milestone_reference_filter.rb' + - 'lib/bitbucket/representation/base.rb' + - 'lib/bitbucket_server/representation/base.rb' + - 'lib/gitlab/background_migration/fix_projects_without_prometheus_service.rb' + - 'lib/gitlab/contributions_calendar.rb' + - 'lib/gitlab/database/migrations/test_background_runner.rb' + - 'lib/gitlab/database/postgres_hll/buckets.rb' + - 'lib/gitlab/elasticsearch/logs/lines.rb' + - 'lib/gitlab/email/message/in_product_marketing/helper.rb' + - 'lib/gitlab/issues/rebalancing/state.rb' + - 'lib/gitlab/profiler.rb' + - 'lib/kramdown/converter/commonmark.rb' + - 'lib/release_highlights/validator/entry.rb' + - 'lib/security/ci_configuration/sast_build_action.rb' + - 'lib/tasks/gitlab/db.rake' + - 'lib/tasks/gitlab/info.rake' + - 'lib/tasks/gitlab/praefect.rake' + - 'lib/tasks/gitlab/shell.rake' + - 'lib/tasks/gitlab/tw/codeowners.rake' + - 'qa/qa/service/praefect_manager.rb' + - 'qa/qa/specs/features/browser_ui/1_manage/project/project_access_token_spec.rb' + - 'qa/qa/specs/features/browser_ui/2_plan/issue/custom_issue_template_spec.rb' + - 'qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_via_template_spec.rb' + - 'qa/qa/specs/features/ee/browser_ui/11_fulfillment/license/cloud_activation_spec.rb' + - 'qa/qa/specs/features/ee/browser_ui/11_fulfillment/license/license_spec.rb' + - 'qa/qa/specs/features/ee/browser_ui/12_geo/geo_replication_npm_registry_spec.rb' + - 'qa/spec/scenario/test/integration/mattermost_spec.rb' + - 'qa/spec/support/page_error_checker_spec.rb' + - 'rubocop/cop/migration/add_limit_to_text_columns.rb' + - 'spec/config/settings_spec.rb' + - 'spec/controllers/admin/application_settings_controller_spec.rb' + - 'spec/controllers/application_controller_spec.rb' + - 'spec/controllers/groups/labels_controller_spec.rb' + - 'spec/controllers/groups/releases_controller_spec.rb' + - 'spec/controllers/groups/settings/ci_cd_controller_spec.rb' + - 'spec/controllers/import/manifest_controller_spec.rb' + - 'spec/controllers/projects/blame_controller_spec.rb' + - 'spec/controllers/projects/deploy_keys_controller_spec.rb' + - 'spec/controllers/projects/error_tracking/stack_traces_controller_spec.rb' + - 'spec/controllers/projects/feature_flags_controller_spec.rb' + - 'spec/controllers/projects/jobs_controller_spec.rb' + - 'spec/controllers/projects/labels_controller_spec.rb' + - 'spec/controllers/projects/notes_controller_spec.rb' + - 'spec/controllers/projects/releases_controller_spec.rb' + - 'spec/controllers/projects/tree_controller_spec.rb' + - 'spec/controllers/registrations/welcome_controller_spec.rb' + - 'spec/controllers/snippets/notes_controller_spec.rb' + - 'spec/dependencies/omniauth_saml_spec.rb' + - 'spec/experiments/application_experiment_spec.rb' + - 'spec/factories/ci/build_trace_chunks.rb' + - 'spec/factories/ci/job_artifacts.rb' + - 'spec/factories/ci/pipeline_artifacts.rb' + - 'spec/factories/commit_statuses.rb' + - 'spec/factories/emails.rb' + - 'spec/factories/external_pull_requests.rb' + - 'spec/factories/gitlab/database/postgres_index.rb' + - 'spec/factories/packages/dependencies.rb' + - 'spec/factories/packages/package_tags.rb' + - 'spec/factories/packages/packages.rb' + - 'spec/factories/prometheus_alert.rb' + - 'spec/factories/prometheus_metrics.rb' + - 'spec/features/admin/admin_mode/login_spec.rb' + - 'spec/features/admin/users/users_spec.rb' + - 'spec/features/boards/board_filters_spec.rb' + - 'spec/features/boards/reload_boards_on_browser_back_spec.rb' + - 'spec/features/dashboard/archived_projects_spec.rb' + - 'spec/features/error_tracking/user_filters_errors_by_status_spec.rb' + - 'spec/features/groups/issues_spec.rb' + - 'spec/features/groups_spec.rb' + - 'spec/features/issuables/user_sees_sidebar_spec.rb' + - 'spec/features/issues/gfm_autocomplete_spec.rb' + - 'spec/features/issues/todo_spec.rb' + - 'spec/features/issues/user_bulk_edits_issues_spec.rb' + - 'spec/features/issues/user_interacts_with_awards_spec.rb' + - 'spec/features/issues/user_uses_quick_actions_spec.rb' + - 'spec/features/merge_request/user_approves_spec.rb' + - 'spec/features/merge_request/user_customizes_merge_commit_message_spec.rb' + - 'spec/features/merge_request/user_edits_assignees_sidebar_spec.rb' + - 'spec/features/merge_request/user_sees_closing_issues_message_spec.rb' + - 'spec/features/merge_request/user_sees_deployment_widget_spec.rb' + - 'spec/features/merge_request/user_sees_diff_spec.rb' + - 'spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb' + - 'spec/features/merge_request/user_sees_versions_spec.rb' + - 'spec/features/merge_request/user_uses_quick_actions_spec.rb' + - 'spec/features/profiles/user_edit_profile_spec.rb' + - 'spec/features/projects/cluster_agents_spec.rb' + - 'spec/features/projects/commits/user_browses_commits_spec.rb' + - 'spec/features/projects/environments/environment_spec.rb' + - 'spec/features/projects/files/user_browses_files_spec.rb' + - 'spec/features/projects/pipelines/pipelines_spec.rb' + - 'spec/features/projects/settings/service_desk_setting_spec.rb' + - 'spec/features/projects/tree/tree_show_spec.rb' + - 'spec/features/refactor_blob_viewer_disabled/projects/files/user_browses_files_spec.rb' + - 'spec/features/users/login_spec.rb' + - 'spec/finders/ci/jobs_finder_spec.rb' + - 'spec/finders/ci/runners_finder_spec.rb' + - 'spec/finders/concerns/packages/finder_helper_spec.rb' + - 'spec/finders/container_repositories_finder_spec.rb' + - 'spec/finders/design_management/versions_finder_spec.rb' + - 'spec/finders/milestones_finder_spec.rb' + - 'spec/finders/packages/group_packages_finder_spec.rb' + - 'spec/finders/packages/npm/package_finder_spec.rb' + - 'spec/finders/projects_finder_spec.rb' + - 'spec/frontend/fixtures/api_merge_requests.rb' + - 'spec/frontend/fixtures/api_projects.rb' + - 'spec/frontend/fixtures/application_settings.rb' + - 'spec/frontend/fixtures/blob.rb' + - 'spec/frontend/fixtures/branches.rb' + - 'spec/frontend/fixtures/clusters.rb' + - 'spec/frontend/fixtures/deploy_keys.rb' + - 'spec/frontend/fixtures/groups.rb' + - 'spec/frontend/fixtures/issues.rb' + - 'spec/frontend/fixtures/jobs.rb' + - 'spec/frontend/fixtures/labels.rb' + - 'spec/frontend/fixtures/merge_requests.rb' + - 'spec/frontend/fixtures/merge_requests_diffs.rb' + - 'spec/frontend/fixtures/metrics_dashboard.rb' + - 'spec/frontend/fixtures/pipeline_schedules.rb' + - 'spec/frontend/fixtures/pipelines.rb' + - 'spec/frontend/fixtures/projects.rb' + - 'spec/frontend/fixtures/prometheus_service.rb' + - 'spec/frontend/fixtures/raw.rb' + - 'spec/frontend/fixtures/services.rb' + - 'spec/frontend/fixtures/snippet.rb' + - 'spec/frontend/fixtures/todos.rb' + - 'spec/graphql/mutations/merge_requests/set_labels_spec.rb' + - 'spec/graphql/mutations/releases/create_spec.rb' + - 'spec/graphql/mutations/releases/delete_spec.rb' + - 'spec/graphql/mutations/releases/update_spec.rb' + - 'spec/graphql/resolvers/ci/runner_jobs_resolver_spec.rb' + - 'spec/graphql/resolvers/group_members/notification_email_resolver_spec.rb' + - 'spec/graphql/resolvers/project_jobs_resolver_spec.rb' + - 'spec/graphql/resolvers/projects/grafana_integration_resolver_spec.rb' + - 'spec/graphql/resolvers/projects_resolver_spec.rb' + - 'spec/graphql/types/ci/job_token_scope_type_spec.rb' + - 'spec/graphql/types/issue_type_spec.rb' + - 'spec/graphql/types/user_type_spec.rb' + - 'spec/helpers/application_settings_helper_spec.rb' + - 'spec/helpers/blob_helper_spec.rb' + - 'spec/helpers/gitlab_script_tag_helper_spec.rb' + - 'spec/helpers/issuables_helper_spec.rb' + - 'spec/helpers/projects/pipeline_helper_spec.rb' + - 'spec/helpers/routing/pseudonymization_helper_spec.rb' + - 'spec/helpers/search_helper_spec.rb' + - 'spec/helpers/wiki_page_version_helper_spec.rb' + - 'spec/initializers/carrierwave_patch_spec.rb' + - 'spec/initializers/trusted_proxies_spec.rb' + - 'spec/lib/api/entities/ci/job_request/image_spec.rb' + - 'spec/lib/api/entities/ci/job_request/port_spec.rb' + - 'spec/lib/api/helpers/sse_helpers_spec.rb' + - 'spec/lib/api/helpers_spec.rb' + - 'spec/lib/banzai/cross_project_reference_spec.rb' + - 'spec/lib/banzai/filter/broadcast_message_placeholders_filter_spec.rb' + - 'spec/lib/banzai/filter/commit_trailers_filter_spec.rb' + - 'spec/lib/banzai/pipeline/plain_markdown_pipeline_spec.rb' + - 'spec/lib/banzai/renderer_spec.rb' + - 'spec/lib/bitbucket_server/connection_spec.rb' + - 'spec/lib/bulk_imports/common/pipelines/lfs_objects_pipeline_spec.rb' + - 'spec/lib/bulk_imports/common/pipelines/uploads_pipeline_spec.rb' + - 'spec/lib/bulk_imports/projects/pipelines/snippets_repository_pipeline_spec.rb' + - 'spec/lib/feature/definition_spec.rb' + - 'spec/lib/feature_spec.rb' + - 'spec/lib/gitlab/application_context_spec.rb' + - 'spec/lib/gitlab/asciidoc_spec.rb' + - 'spec/lib/gitlab/audit/ci_runner_token_author_spec.rb' + - 'spec/lib/gitlab/background_migration/copy_ci_builds_columns_to_security_scans_spec.rb' + - 'spec/lib/gitlab/batch_pop_queueing_spec.rb' + - 'spec/lib/gitlab/chat_name_token_spec.rb' + - 'spec/lib/gitlab/ci/ansi2html_spec.rb' + - 'spec/lib/gitlab/ci/ansi2json_spec.rb' + - 'spec/lib/gitlab/ci/build/prerequisite/kubernetes_namespace_spec.rb' + - 'spec/lib/gitlab/ci/config/entry/processable_spec.rb' + - 'spec/lib/gitlab/ci/config/entry/release_spec.rb' + - 'spec/lib/gitlab/ci/config/entry/tags_spec.rb' + - 'spec/lib/gitlab/ci/config/external/file/base_spec.rb' + - 'spec/lib/gitlab/ci/config/external/file/local_spec.rb' + - 'spec/lib/gitlab/ci/config/external/file/remote_spec.rb' + - 'spec/lib/gitlab/ci/config/normalizer_spec.rb' + - 'spec/lib/gitlab/ci/cron_parser_spec.rb' + - 'spec/lib/gitlab/ci/pipeline/chain/create_deployments_spec.rb' + - 'spec/lib/gitlab/ci/pipeline/chain/seed_block_spec.rb' + - 'spec/lib/gitlab/ci/pipeline/chain/seed_spec.rb' + - 'spec/lib/gitlab/ci/pipeline/chain/validate/external_spec.rb' + - 'spec/lib/gitlab/ci/pipeline/quota/deployments_spec.rb' + - 'spec/lib/gitlab/ci/reports/security/reports_spec.rb' + - 'spec/lib/gitlab/ci/reports/security/vulnerability_reports_comparer_spec.rb' + - 'spec/lib/gitlab/ci/reports/test_suite_spec.rb' + - 'spec/lib/gitlab/ci/status/build/canceled_spec.rb' + - 'spec/lib/gitlab/ci/status/build/created_spec.rb' + - 'spec/lib/gitlab/ci/status/build/manual_spec.rb' + - 'spec/lib/gitlab/ci/status/build/pending_spec.rb' + - 'spec/lib/gitlab/ci/status/build/skipped_spec.rb' + - 'spec/lib/gitlab/ci/status/processable/waiting_for_resource_spec.rb' + - 'spec/lib/gitlab/ci/templates/auto_devops_gitlab_ci_yaml_spec.rb' + - 'spec/lib/gitlab/ci/trace/remote_checksum_spec.rb' + - 'spec/lib/gitlab/ci/yaml_processor_spec.rb' + - 'spec/lib/gitlab/composer/cache_spec.rb' + - 'spec/lib/gitlab/data_builder/build_spec.rb' + - 'spec/lib/gitlab/data_builder/pipeline_spec.rb' + - 'spec/lib/gitlab/database/background_migration/batched_migration_spec.rb' + - 'spec/lib/gitlab/database/load_balancing/load_balancer_spec.rb' + - 'spec/lib/gitlab/database/load_balancing/sidekiq_server_middleware_spec.rb' + - 'spec/lib/gitlab/database/migration_helpers/v2_spec.rb' + - 'spec/lib/gitlab/database/migration_helpers_spec.rb' + - 'spec/lib/gitlab/database/migrations/lock_retry_mixin_spec.rb' + - 'spec/lib/gitlab/database/migrations/runner_spec.rb' + - 'spec/lib/gitlab/database/partitioning_spec.rb' + - 'spec/lib/gitlab/database/reindexing/grafana_notifier_spec.rb' + - 'spec/lib/gitlab/database/with_lock_retries_outside_transaction_spec.rb' + - 'spec/lib/gitlab/database/with_lock_retries_spec.rb' + - 'spec/lib/gitlab/database_importers/common_metrics/importer_spec.rb' + - 'spec/lib/gitlab/database_spec.rb' + - 'spec/lib/gitlab/elasticsearch/logs/lines_spec.rb' + - 'spec/lib/gitlab/email/handler/create_note_handler_spec.rb' + - 'spec/lib/gitlab/email/handler/service_desk_handler_spec.rb' + - 'spec/lib/gitlab/email/message/in_product_marketing/admin_verify_spec.rb' + - 'spec/lib/gitlab/email/message/in_product_marketing/create_spec.rb' + - 'spec/lib/gitlab/email/message/in_product_marketing/experience_spec.rb' + - 'spec/lib/gitlab/email/message/in_product_marketing/team_short_spec.rb' + - 'spec/lib/gitlab/email/message/in_product_marketing/team_spec.rb' + - 'spec/lib/gitlab/email/message/in_product_marketing/trial_short_spec.rb' + - 'spec/lib/gitlab/email/message/in_product_marketing/trial_spec.rb' + - 'spec/lib/gitlab/email/message/in_product_marketing/verify_spec.rb' + - 'spec/lib/gitlab/error_tracking/processor/sidekiq_processor_spec.rb' + - 'spec/lib/gitlab/exclusive_lease_helpers_spec.rb' + - 'spec/lib/gitlab/file_markdown_link_builder_spec.rb' + - 'spec/lib/gitlab/git/blob_spec.rb' + - 'spec/lib/gitlab/git/commit_spec.rb' + - 'spec/lib/gitlab/git/diff_collection_spec.rb' + - 'spec/lib/gitlab/git/raw_diff_change_spec.rb' + - 'spec/lib/gitlab/git/repository_spec.rb' + - 'spec/lib/gitlab/git/rugged_impl/use_rugged_spec.rb' + - 'spec/lib/gitlab/gitaly_client/commit_service_spec.rb' + - 'spec/lib/gitlab/github_import/client_spec.rb' + - 'spec/lib/gitlab/github_import/importer/pull_requests_importer_spec.rb' + - 'spec/lib/gitlab/gpg_spec.rb' + - 'spec/lib/gitlab/graphql/markdown_field_spec.rb' + - 'spec/lib/gitlab/graphql/pagination/keyset/connection_generic_keyset_spec.rb' + - 'spec/lib/gitlab/graphql/pagination/keyset/connection_spec.rb' + - 'spec/lib/gitlab/graphs/commits_spec.rb' + - 'spec/lib/gitlab/highlight_spec.rb' + - 'spec/lib/gitlab/import_export/import_test_coverage_spec.rb' + - 'spec/lib/gitlab/import_export/json/ndjson_writer_spec.rb' + - 'spec/lib/gitlab/import_export/project/tree_restorer_spec.rb' + - 'spec/lib/gitlab/import_export/version_checker_spec.rb' + - 'spec/lib/gitlab/jira/dvcs_spec.rb' + - 'spec/lib/gitlab/kubernetes/rollout_status_spec.rb' + - 'spec/lib/gitlab/metrics/background_transaction_spec.rb' + - 'spec/lib/gitlab/metrics/web_transaction_spec.rb' + - 'spec/lib/gitlab/middleware/compressed_json_spec.rb' + - 'spec/lib/gitlab/middleware/sidekiq_web_static_spec.rb' + - 'spec/lib/gitlab/otp_key_rotator_spec.rb' + - 'spec/lib/gitlab/pagination/keyset_spec.rb' + - 'spec/lib/gitlab/phabricator_import/conduit/response_spec.rb' + - 'spec/lib/gitlab/prometheus_client_spec.rb' + - 'spec/lib/gitlab/quick_actions/command_definition_spec.rb' + - 'spec/lib/gitlab/quick_actions/extractor_spec.rb' + - 'spec/lib/gitlab/rack_attack/instrumented_cache_store_spec.rb' + - 'spec/lib/gitlab/rack_attack/user_allowlist_spec.rb' + - 'spec/lib/gitlab/redis/hll_spec.rb' + - 'spec/lib/gitlab/reference_counter_spec.rb' + - 'spec/lib/gitlab/regex_spec.rb' + - 'spec/lib/gitlab/search/abuse_detection_spec.rb' + - 'spec/lib/gitlab/search_context/builder_spec.rb' + - 'spec/lib/gitlab/session_spec.rb' + - 'spec/lib/gitlab/sidekiq_daemon/memory_killer_spec.rb' + - 'spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb' + - 'spec/lib/gitlab/spamcheck/client_spec.rb' + - 'spec/lib/gitlab/suggestions/file_suggestion_spec.rb' + - 'spec/lib/gitlab/usage/metrics/name_suggestion_spec.rb' + - 'spec/lib/gitlab/usage/metrics/names_suggestions/generator_spec.rb' + - 'spec/lib/gitlab/utils/sanitize_node_link_spec.rb' + - 'spec/lib/gitlab/utils/usage_data_spec.rb' + - 'spec/lib/gitlab/utils_spec.rb' + - 'spec/lib/gitlab/verify/uploads_spec.rb' + - 'spec/lib/gitlab/version_info_spec.rb' + - 'spec/lib/json_web_token/rsa_token_spec.rb' + - 'spec/lib/marginalia_spec.rb' + - 'spec/lib/mattermost/session_spec.rb' + - 'spec/lib/microsoft_teams/notifier_spec.rb' + - 'spec/lib/sidebars/groups/menus/group_information_menu_spec.rb' + - 'spec/lib/sidebars/menu_spec.rb' + - 'spec/mailers/emails/service_desk_spec.rb' + - 'spec/migrations/20210812013042_remove_duplicate_project_authorizations_spec.rb' + - 'spec/migrations/20210910194952_update_report_type_for_existing_approval_project_rules_spec.rb' + - 'spec/migrations/confirm_support_bot_user_spec.rb' + - 'spec/migrations/reset_job_token_scope_enabled_again_spec.rb' + - 'spec/migrations/reset_job_token_scope_enabled_spec.rb' + - 'spec/migrations/reset_severity_levels_to_new_default_spec.rb' + - 'spec/migrations/schedule_copy_ci_builds_columns_to_security_scans2_spec.rb' + - 'spec/models/active_session_spec.rb' + - 'spec/models/aws/role_spec.rb' + - 'spec/models/ci/build_dependencies_spec.rb' + - 'spec/models/ci/build_runner_session_spec.rb' + - 'spec/models/ci/build_spec.rb' + - 'spec/models/ci/daily_build_group_report_result_spec.rb' + - 'spec/models/ci/job_artifact_spec.rb' + - 'spec/models/ci/pipeline_schedule_spec.rb' + - 'spec/models/ci/pipeline_spec.rb' + - 'spec/models/ci/runner_spec.rb' + - 'spec/models/clusters/applications/elastic_stack_spec.rb' + - 'spec/models/clusters/cluster_spec.rb' + - 'spec/models/commit_status_spec.rb' + - 'spec/models/concerns/chronic_duration_attribute_spec.rb' + - 'spec/models/concerns/counter_attribute_spec.rb' + - 'spec/models/concerns/nullify_if_blank_spec.rb' + - 'spec/models/concerns/reactive_caching_spec.rb' + - 'spec/models/concerns/token_authenticatable_spec.rb' + - 'spec/models/container_expiration_policy_spec.rb' + - 'spec/models/container_repository_spec.rb' + - 'spec/models/environment_spec.rb' + - 'spec/models/event_spec.rb' + - 'spec/models/group_spec.rb' + - 'spec/models/hooks/web_hook_log_spec.rb' + - 'spec/models/integrations/chat_message/wiki_page_message_spec.rb' + - 'spec/models/issue_spec.rb' + - 'spec/models/jira_import_state_spec.rb' + - 'spec/models/merge_request_spec.rb' + - 'spec/models/namespace/root_storage_statistics_spec.rb' + - 'spec/models/namespace_spec.rb' + - 'spec/models/note_spec.rb' + - 'spec/models/onboarding_progress_spec.rb' + - 'spec/models/packages/conan/metadatum_spec.rb' + - 'spec/models/packages/package_file_spec.rb' + - 'spec/models/packages/package_spec.rb' + - 'spec/models/postgresql/replication_slot_spec.rb' + - 'spec/models/preloaders/labels_preloader_spec.rb' + - 'spec/models/preloaders/user_max_access_level_in_groups_preloader_spec.rb' + - 'spec/models/project_spec.rb' + - 'spec/models/release_spec.rb' + - 'spec/models/releases/link_spec.rb' + - 'spec/models/remote_mirror_spec.rb' + - 'spec/models/repository_spec.rb' + - 'spec/models/snippet_input_action_collection_spec.rb' + - 'spec/models/snippet_spec.rb' + - 'spec/models/user_spec.rb' + - 'spec/models/users/calloutable_spec.rb' + - 'spec/models/wiki_page/meta_spec.rb' + - 'spec/policies/clusters/agent_policy_spec.rb' + - 'spec/policies/group_member_policy_spec.rb' + - 'spec/policies/issue_policy_spec.rb' + - 'spec/policies/project_policy_spec.rb' + - 'spec/policies/terraform/state_policy_spec.rb' + - 'spec/policies/terraform/state_version_policy_spec.rb' + - 'spec/presenters/packages/composer/packages_presenter_spec.rb' + - 'spec/presenters/packages/conan/package_presenter_spec.rb' + - 'spec/presenters/packages/nuget/packages_metadata_presenter_spec.rb' + - 'spec/presenters/packages/pypi/package_presenter_spec.rb' + - 'spec/presenters/project_presenter_spec.rb' + - 'spec/requests/api/branches_spec.rb' + - 'spec/requests/api/ci/jobs_spec.rb' + - 'spec/requests/api/ci/runner/jobs_request_post_spec.rb' + - 'spec/requests/api/ci/runner/jobs_trace_spec.rb' + - 'spec/requests/api/ci/secure_files_spec.rb' + - 'spec/requests/api/ci/triggers_spec.rb' + - 'spec/requests/api/ci/variables_spec.rb' + - 'spec/requests/api/commits_spec.rb' + - 'spec/requests/api/conan_instance_packages_spec.rb' + - 'spec/requests/api/conan_project_packages_spec.rb' + - 'spec/requests/api/dependency_proxy_spec.rb' + - 'spec/requests/api/go_proxy_spec.rb' + - 'spec/requests/api/graphql/boards/board_list_issues_query_spec.rb' + - 'spec/requests/api/graphql/boards/board_lists_query_spec.rb' + - 'spec/requests/api/graphql/group/dependency_proxy_manifests_spec.rb' + - 'spec/requests/api/graphql/mutations/award_emojis/add_spec.rb' + - 'spec/requests/api/graphql/mutations/award_emojis/toggle_spec.rb' + - 'spec/requests/api/graphql/mutations/releases/create_spec.rb' + - 'spec/requests/api/graphql/mutations/releases/update_spec.rb' + - 'spec/requests/api/graphql/mutations/snippets/create_spec.rb' + - 'spec/requests/api/graphql/namespace/root_storage_statistics_spec.rb' + - 'spec/requests/api/graphql/packages/conan_spec.rb' + - 'spec/requests/api/graphql/packages/helm_spec.rb' + - 'spec/requests/api/graphql/packages/package_spec.rb' + - 'spec/requests/api/graphql/project/base_service_spec.rb' + - 'spec/requests/api/graphql/project/jira_import_spec.rb' + - 'spec/requests/api/group_variables_spec.rb' + - 'spec/requests/api/groups_spec.rb' + - 'spec/requests/api/helpers_spec.rb' + - 'spec/requests/api/internal/base_spec.rb' + - 'spec/requests/api/markdown_spec.rb' + - 'spec/requests/api/maven_packages_spec.rb' + - 'spec/requests/api/metrics/dashboard/annotations_spec.rb' + - 'spec/requests/api/notes_spec.rb' + - 'spec/requests/api/npm_project_packages_spec.rb' + - 'spec/requests/api/nuget_group_packages_spec.rb' + - 'spec/requests/api/pages/pages_spec.rb' + - 'spec/requests/api/pages_domains_spec.rb' + - 'spec/requests/api/personal_access_tokens_spec.rb' + - 'spec/requests/api/project_hooks_spec.rb' + - 'spec/requests/api/project_templates_spec.rb' + - 'spec/requests/api/projects_spec.rb' + - 'spec/requests/api/pypi_packages_spec.rb' + - 'spec/requests/api/release/links_spec.rb' + - 'spec/requests/api/releases_spec.rb' + - 'spec/requests/api/snippets_spec.rb' + - 'spec/requests/api/unleash_spec.rb' + - 'spec/requests/git_http_spec.rb' + - 'spec/requests/groups/milestones_controller_spec.rb' + - 'spec/requests/lfs_http_spec.rb' + - 'spec/requests/oauth/tokens_controller_spec.rb' + - 'spec/rubocop/cop/migration/create_table_with_foreign_keys_spec.rb' + - 'spec/serializers/cluster_entity_spec.rb' + - 'spec/serializers/deploy_key_entity_spec.rb' + - 'spec/serializers/import/provider_repo_serializer_spec.rb' + - 'spec/services/auto_merge/base_service_spec.rb' + - 'spec/services/auto_merge_service_spec.rb' + - 'spec/services/ci/create_pipeline_service/evaluate_runner_tags_spec.rb' + - 'spec/services/ci/parse_dotenv_artifact_service_spec.rb' + - 'spec/services/ci/pipeline_processing/atomic_processing_service/status_collection_spec.rb' + - 'spec/services/ci/process_build_service_spec.rb' + - 'spec/services/ci/runners/register_runner_service_spec.rb' + - 'spec/services/ci/runners/update_runner_service_spec.rb' + - 'spec/services/ci/stuck_builds/drop_pending_service_spec.rb' + - 'spec/services/ci/stuck_builds/drop_scheduled_service_spec.rb' + - 'spec/services/clusters/integrations/create_service_spec.rb' + - 'spec/services/clusters/kubernetes/create_or_update_service_account_service_spec.rb' + - 'spec/services/deployments/create_for_build_service_spec.rb' + - 'spec/services/git/branch_push_service_spec.rb' + - 'spec/services/groups/destroy_service_spec.rb' + - 'spec/services/groups/merge_requests_count_service_spec.rb' + - 'spec/services/groups/update_service_spec.rb' + - 'spec/services/groups/update_statistics_service_spec.rb' + - 'spec/services/import/validate_remote_git_endpoint_service_spec.rb' + - 'spec/services/issues/referenced_merge_requests_service_spec.rb' + - 'spec/services/jira_import/start_import_service_spec.rb' + - 'spec/services/lfs/push_service_spec.rb' + - 'spec/services/members/invite_service_spec.rb' + - 'spec/services/merge_requests/push_options_handler_service_spec.rb' + - 'spec/services/merge_requests/refresh_service_spec.rb' + - 'spec/services/merge_requests/update_service_spec.rb' + - 'spec/services/milestones/transfer_service_spec.rb' + - 'spec/services/notes/copy_service_spec.rb' + - 'spec/services/notification_service_spec.rb' + - 'spec/services/packages/composer/create_package_service_spec.rb' + - 'spec/services/packages/create_dependency_service_spec.rb' + - 'spec/services/packages/debian/extract_deb_metadata_service_spec.rb' + - 'spec/services/packages/debian/parse_debian822_service_spec.rb' + - 'spec/services/packages/debian/sign_distribution_service_spec.rb' + - 'spec/services/packages/helm/process_file_service_spec.rb' + - 'spec/services/packages/npm/create_package_service_spec.rb' + - 'spec/services/packages/rubygems/dependency_resolver_service_spec.rb' + - 'spec/services/pages/delete_service_spec.rb' + - 'spec/services/projects/container_repository/third_party/delete_tags_service_spec.rb' + - 'spec/services/projects/enable_deploy_key_service_spec.rb' + - 'spec/services/projects/lfs_pointers/lfs_download_link_list_service_spec.rb' + - 'spec/services/projects/lfs_pointers/lfs_download_service_spec.rb' + - 'spec/services/projects/lfs_pointers/lfs_object_download_list_service_spec.rb' + - 'spec/services/projects/participants_service_spec.rb' + - 'spec/services/projects/update_statistics_service_spec.rb' + - 'spec/services/quick_actions/interpret_service_spec.rb' + - 'spec/services/releases/destroy_service_spec.rb' + - 'spec/services/releases/update_service_spec.rb' + - 'spec/services/resource_access_tokens/create_service_spec.rb' + - 'spec/services/search/group_service_spec.rb' + - 'spec/services/snippets/update_service_spec.rb' + - 'spec/services/suggestions/apply_service_spec.rb' + - 'spec/services/system_notes/merge_requests_service_spec.rb' + - 'spec/services/terraform/remote_state_handler_spec.rb' + - 'spec/services/todo_service_spec.rb' + - 'spec/services/todos/destroy/design_service_spec.rb' + - 'spec/services/todos/destroy/entity_leave_service_spec.rb' + - 'spec/services/web_hook_service_spec.rb' + - 'spec/support/helpers/cycle_analytics_helpers.rb' + - 'spec/support/redis/redis_shared_examples.rb' + - 'spec/support/shared_contexts/features/integrations/integrations_shared_context.rb' + - 'spec/support/shared_contexts/graphql/requests/packages_shared_context.rb' + - 'spec/support/shared_contexts/markdown_golden_master_shared_examples.rb' + - 'spec/support/shared_contexts/requests/api/conan_packages_shared_context.rb' + - 'spec/support/shared_examples/controllers/error_tracking_shared_examples.rb' + - 'spec/support/shared_examples/controllers/snippets_sort_order_shared_examples.rb' + - 'spec/support/shared_examples/features/board_sidebar_labels_examples.rb' + - 'spec/support/shared_examples/features/snippets_shared_examples.rb' + - 'spec/support/shared_examples/features/wiki/user_views_asciidoc_page_with_includes_shared_examples.rb' + - 'spec/support/shared_examples/lib/gitlab/ci/ci_trace_shared_examples.rb' + - 'spec/support/shared_examples/lib/gitlab/sql/set_operator_shared_examples.rb' + - 'spec/support/shared_examples/models/cluster_application_core_shared_examples.rb' + - 'spec/support/shared_examples/models/concerns/analytics/cycle_analytics/stage_event_model_examples.rb' + - 'spec/support/shared_examples/models/concerns/has_repository_shared_examples.rb' + - 'spec/support/shared_examples/models/concerns/incident_management/escalatable_shared_examples.rb' + - 'spec/support/shared_examples/models/label_note_shared_examples.rb' + - 'spec/support/shared_examples/models/packages/debian/distribution_shared_examples.rb' + - 'spec/support/shared_examples/models/project_latest_successful_build_for_shared_examples.rb' + - 'spec/support/shared_examples/requests/api/graphql/group_and_project_boards_query_shared_examples.rb' + - 'spec/support/shared_examples/requests/api/issues/merge_requests_count_shared_examples.rb' + - 'spec/support/shared_examples/requests/api/labels_api_shared_examples.rb' + - 'spec/support/shared_examples/requests/api/repository_storage_moves_shared_examples.rb' + - 'spec/support/shared_examples/requests/lfs_http_shared_examples.rb' + - 'spec/support/shared_examples/services/alert_management/alert_processing/alert_firing_shared_examples.rb' + - 'spec/support/shared_examples/services/boards/issues_move_service_shared_examples.rb' + - 'spec/support/shared_examples/services/gitlab_projects_import_service_shared_examples.rb' + - 'spec/support/shared_examples/services/merge_request_shared_examples.rb' + - 'spec/support/shared_examples/uploaders/object_storage_shared_examples.rb' + - 'spec/tasks/gitlab/snippets_rake_spec.rb' + - 'spec/uploaders/packages/debian/distribution_release_file_uploader_spec.rb' + - 'spec/validators/addressable_url_validator_spec.rb' + - 'spec/views/help/instance_configuration.html.haml_spec.rb' + - 'spec/views/layouts/_header_search.html.haml_spec.rb' + - 'spec/views/layouts/_published_experiments.html.haml_spec.rb' + - 'spec/views/shared/runners/_runner_details.html.haml_spec.rb' + - 'spec/workers/bulk_imports/export_request_worker_spec.rb' + - 'spec/workers/clusters/cleanup/project_namespace_worker_spec.rb' + - 'spec/workers/packages/helm/extraction_worker_spec.rb' + - 'spec/workers/pages_worker_spec.rb' + - 'spec/workers/purge_dependency_proxy_cache_worker_spec.rb' + - 'spec/workers/releases/manage_evidence_worker_spec.rb' + - 'spec/workers/repository_remove_remote_worker_spec.rb' diff --git a/.rubocop_todo/lint/binary_operator_with_identical_operands.yml b/.rubocop_todo/lint/binary_operator_with_identical_operands.yml new file mode 100644 index 00000000000..90c3a76d3b1 --- /dev/null +++ b/.rubocop_todo/lint/binary_operator_with_identical_operands.yml @@ -0,0 +1,15 @@ +--- +Lint/BinaryOperatorWithIdenticalOperands: + Exclude: + - 'ee/spec/lib/ee/gitlab/application_context_spec.rb' + - 'spec/helpers/visibility_level_helper_spec.rb' + - 'spec/lib/gitlab/conan_token_spec.rb' + - 'spec/lib/gitlab/git/conflict/parser_spec.rb' + - 'spec/lib/gitlab/graphql/lazy_spec.rb' + - 'spec/models/ci/build_trace_chunk_spec.rb' + - 'spec/models/clusters/platforms/kubernetes_spec.rb' + - 'spec/models/concerns/where_composite_spec.rb' + - 'spec/models/metrics/dashboard/annotation_spec.rb' + - 'spec/models/repository_spec.rb' + - 'spec/models/ssh_host_key_spec.rb' + - 'spec/tooling/danger/sidekiq_queues_spec.rb' diff --git a/app/assets/javascripts/boards/components/board_content.vue b/app/assets/javascripts/boards/components/board_content.vue index 27ea2e7a608..1d6a71aca47 100644 --- a/app/assets/javascripts/boards/components/board_content.vue +++ b/app/assets/javascripts/boards/components/board_content.vue @@ -4,7 +4,7 @@ import { sortBy } from 'lodash'; import Draggable from 'vuedraggable'; import { mapState, mapGetters, mapActions } from 'vuex'; import BoardAddNewColumn from 'ee_else_ce/boards/components/board_add_new_column.vue'; -import defaultSortableConfig from '~/sortable/sortable_config'; +import { defaultSortableOptions } from '~/sortable/constants'; import { DraggableItemTypes } from '../constants'; import BoardColumn from './board_column.vue'; @@ -43,7 +43,7 @@ export default { }, draggableOptions() { const options = { - ...defaultSortableConfig, + ...defaultSortableOptions, disabled: this.disabled, draggable: '.is-draggable', fallbackOnBody: false, diff --git a/app/assets/javascripts/boards/components/board_list.vue b/app/assets/javascripts/boards/components/board_list.vue index 858cd368b12..47f25f34d0c 100644 --- a/app/assets/javascripts/boards/components/board_list.vue +++ b/app/assets/javascripts/boards/components/board_list.vue @@ -2,9 +2,9 @@ import { GlLoadingIcon, GlIntersectionObserver } from '@gitlab/ui'; import Draggable from 'vuedraggable'; import { mapActions, mapGetters, mapState } from 'vuex'; -import { sortableStart, sortableEnd } from '~/boards/mixins/sortable_default_options'; import { sprintf, __ } from '~/locale'; -import defaultSortableConfig from '~/sortable/sortable_config'; +import { defaultSortableOptions } from '~/sortable/constants'; +import { sortableStart, sortableEnd } from '~/sortable/utils'; import Tracking from '~/tracking'; import listQuery from 'ee_else_ce/boards/graphql/board_lists_deferred.query.graphql'; import { toggleFormEventPrefix, DraggableItemTypes } from '../constants'; @@ -121,7 +121,7 @@ export default { }, treeRootOptions() { const options = { - ...defaultSortableConfig, + ...defaultSortableOptions, fallbackOnBody: false, group: 'board-list', tag: 'ul', diff --git a/app/assets/javascripts/boards/components/issuable_title.vue b/app/assets/javascripts/boards/components/issuable_title.vue deleted file mode 100644 index 40627a9fab8..00000000000 --- a/app/assets/javascripts/boards/components/issuable_title.vue +++ /dev/null @@ -1,21 +0,0 @@ -<script> -export default { - props: { - title: { - type: String, - required: true, - }, - refPath: { - type: String, - required: true, - }, - }, -}; -</script> - -<template> - <div data-testid="issue-title"> - <p class="gl-font-weight-bold">{{ title }}</p> - <p class="gl-mb-0">{{ refPath }}</p> - </div> -</template> diff --git a/app/assets/javascripts/diffs/components/commit_item.vue b/app/assets/javascripts/diffs/components/commit_item.vue index 8d0f6079f8f..8f8712365be 100644 --- a/app/assets/javascripts/diffs/components/commit_item.vue +++ b/app/assets/javascripts/diffs/components/commit_item.vue @@ -130,7 +130,7 @@ export default { :link-href="authorUrl" :img-src="authorAvatar" :img-alt="authorName" - :img-size="40" + :img-size="32" class="avatar-cell d-none d-sm-block" /> </div> diff --git a/app/assets/javascripts/integrations/edit/components/integration_form.vue b/app/assets/javascripts/integrations/edit/components/integration_form.vue index 516e48ed531..661299920c7 100644 --- a/app/assets/javascripts/integrations/edit/components/integration_form.vue +++ b/app/assets/javascripts/integrations/edit/components/integration_form.vue @@ -167,6 +167,9 @@ export default { this.integrationActive = integrationActive; }, }, + descriptionHtmlConfig: { + ADD_ATTR: ['target'], // allow external links, can be removed after https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1427 is implemented + }, helpHtmlConfig: { ADD_ATTR: ['target'], // allow external links, can be removed after https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1427 is implemented ADD_TAGS: ['use'], // to support icon SVGs @@ -212,7 +215,7 @@ export default { <div class="row"> <div class="col-lg-4"> <h4 class="gl-mt-0">{{ section.title }}</h4> - <p v-safe-html="section.description"></p> + <p v-safe-html:[$options.descriptionHtmlConfig]="section.description"></p> </div> <div class="col-lg-8"> diff --git a/app/assets/javascripts/integrations/edit/components/jira_issues_fields.vue b/app/assets/javascripts/integrations/edit/components/jira_issues_fields.vue index 4503bb8e3c8..f00339c92fa 100644 --- a/app/assets/javascripts/integrations/edit/components/jira_issues_fields.vue +++ b/app/assets/javascripts/integrations/edit/components/jira_issues_fields.vue @@ -1,5 +1,5 @@ <script> -import { GlFormGroup, GlFormCheckbox, GlFormInput, GlSprintf, GlLink } from '@gitlab/ui'; +import { GlFormGroup, GlFormCheckbox, GlFormInput } from '@gitlab/ui'; import { mapGetters } from 'vuex'; import { s__, __ } from '~/locale'; import JiraUpgradeCta from './jira_upgrade_cta.vue'; @@ -10,8 +10,6 @@ export default { GlFormGroup, GlFormCheckbox, GlFormInput, - GlSprintf, - GlLink, JiraUpgradeCta, JiraIssueCreationVulnerabilities: () => import('ee_component/integrations/edit/components/jira_issue_creation_vulnerabilities.vue'), @@ -47,21 +45,11 @@ export default { required: false, default: null, }, - gitlabIssuesEnabled: { - type: Boolean, - required: false, - default: true, - }, upgradePlanPath: { type: String, required: false, default: '', }, - editProjectPath: { - type: String, - required: false, - default: '', - }, isValidated: { type: Boolean, required: false, @@ -91,9 +79,6 @@ export default { projectKeyLabel: s__('JiraService|Jira project key'), projectKeyPlaceholder: s__('JiraService|For example, AB'), requiredFieldFeedback: __('This field is required.'), - issueTrackerConflictWarning: s__( - 'JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used.', - ), }, }; </script> @@ -112,12 +97,34 @@ export default { {{ $options.i18n.enableCheckboxHelp }} </template> </gl-form-checkbox> - <template v-if="enableJiraIssues"> + + <div v-if="enableJiraIssues" class="gl-pl-6 gl-mt-3"> + <gl-form-group + :label="$options.i18n.projectKeyLabel" + label-for="service_project_key" + :invalid-feedback="$options.i18n.requiredFieldFeedback" + :state="validProjectKey" + class="gl-max-w-26" + data-testid="project-key-form-group" + > + <gl-form-input + id="service_project_key" + v-model="projectKey" + name="service[project_key]" + data-qa-selector="service_jira_project_key_field" + :placeholder="$options.i18n.projectKeyPlaceholder" + :required="enableJiraIssues" + :state="validProjectKey" + :readonly="isInheriting" + /> + </gl-form-group> + <jira-issue-creation-vulnerabilities :project-key="projectKey" :initial-is-enabled="initialEnableJiraVulnerabilities" :initial-issue-type-id="initialVulnerabilitiesIssuetype" :show-full-feature="showJiraVulnerabilitiesIntegration" + class="gl-mt-6" data-testid="jira-for-vulnerabilities" @request-jira-issue-types="$emit('request-jira-issue-types')" /> @@ -128,43 +135,14 @@ export default { show-ultimate-message :upgrade-plan-path="upgradePlanPath" /> - </template> + </div> </template> + <jira-upgrade-cta v-else - class="gl-mt-2" data-testid="premium-upgrade-cta" show-premium-message :upgrade-plan-path="upgradePlanPath" /> - - <template v-if="showJiraIssuesIntegration"> - <gl-form-group - :label="$options.i18n.projectKeyLabel" - label-for="service_project_key" - :invalid-feedback="$options.i18n.requiredFieldFeedback" - :state="validProjectKey" - data-testid="project-key-form-group" - > - <gl-form-input - id="service_project_key" - v-model="projectKey" - name="service[project_key]" - data-qa-selector="service_jira_project_key_field" - :placeholder="$options.i18n.projectKeyPlaceholder" - :required="enableJiraIssues" - :state="validProjectKey" - :disabled="!enableJiraIssues" - :readonly="isInheriting" - /> - </gl-form-group> - <p v-if="gitlabIssuesEnabled" data-testid="conflict-warning-text"> - <gl-sprintf :message="$options.i18n.issueTrackerConflictWarning"> - <template #link="{ content }"> - <gl-link :href="editProjectPath" target="_blank">{{ content }}</gl-link> - </template> - </gl-sprintf> - </p> - </template> </div> </template> diff --git a/app/assets/javascripts/integrations/edit/index.js b/app/assets/javascripts/integrations/edit/index.js index 4860b288b0f..9a9aae36657 100644 --- a/app/assets/javascripts/integrations/edit/index.js +++ b/app/assets/javascripts/integrations/edit/index.js @@ -22,7 +22,6 @@ function parseDatasetToProps(data) { commentDetail, projectKey, upgradePlanPath, - editProjectPath, learnMorePath, triggerEvents, sections, @@ -52,7 +51,6 @@ function parseDatasetToProps(data) { showJiraVulnerabilitiesIntegration, enableJiraIssues, enableJiraVulnerabilities, - gitlabIssuesEnabled, } = parseBooleanInData(booleanAttributes); return { @@ -81,9 +79,7 @@ function parseDatasetToProps(data) { initialEnableJiraVulnerabilities: enableJiraVulnerabilities, initialVulnerabilitiesIssuetype: vulnerabilitiesIssuetype, initialProjectKey: projectKey, - gitlabIssuesEnabled, upgradePlanPath, - editProjectPath, }, learnMorePath, triggerEvents: JSON.parse(triggerEvents), diff --git a/app/assets/javascripts/issues/manual_ordering.js b/app/assets/javascripts/issues/manual_ordering.js index 8fb891f62f7..bc1cffef943 100644 --- a/app/assets/javascripts/issues/manual_ordering.js +++ b/app/assets/javascripts/issues/manual_ordering.js @@ -1,11 +1,8 @@ import Sortable from 'sortablejs'; -import { - getBoardSortableDefaultOptions, - sortableStart, -} from '~/boards/mixins/sortable_default_options'; import createFlash from '~/flash'; import axios from '~/lib/utils/axios_utils'; import { s__ } from '~/locale'; +import { getSortableDefaultOptions, sortableStart } from '~/sortable/utils'; const updateIssue = (url, { move_before_id, move_after_id }) => axios @@ -28,7 +25,7 @@ const initManualOrdering = () => { Sortable.create( issueList, - getBoardSortableDefaultOptions({ + getSortableDefaultOptions({ scroll: true, fallbackTolerance: 1, dataIdAttr: 'data-id', diff --git a/app/assets/javascripts/related_issues/components/related_issues_list.vue b/app/assets/javascripts/related_issues/components/related_issues_list.vue index 174049b15fe..9ed895e90fb 100644 --- a/app/assets/javascripts/related_issues/components/related_issues_list.vue +++ b/app/assets/javascripts/related_issues/components/related_issues_list.vue @@ -1,8 +1,8 @@ <script> import { GlLoadingIcon } from '@gitlab/ui'; import Sortable from 'sortablejs'; -import sortableConfig from '~/sortable/sortable_config'; import RelatedIssuableItem from '~/issuable/components/related_issuable_item.vue'; +import { defaultSortableOptions } from '~/sortable/constants'; export default { name: 'RelatedIssuesList', @@ -53,7 +53,7 @@ export default { mounted() { if (this.canReorder) { this.sortable = Sortable.create(this.$refs.list, { - ...sortableConfig, + ...defaultSortableOptions, onStart: this.addDraggingCursor, onEnd: this.reordered, }); diff --git a/app/assets/javascripts/sortable/constants.js b/app/assets/javascripts/sortable/constants.js new file mode 100644 index 00000000000..7fddac00ab2 --- /dev/null +++ b/app/assets/javascripts/sortable/constants.js @@ -0,0 +1,19 @@ +/** + * Default config options for sortablejs. + * @type {object} + * + * @example + * import Sortable from 'sortablejs'; + * + * const sortable = Sortable.create(el, { + * ...defaultSortableOptions, + * }); + */ +export const defaultSortableOptions = { + animation: 200, + forceFallback: true, + fallbackClass: 'is-dragging', + fallbackOnBody: true, + ghostClass: 'is-ghost', + fallbackTolerance: 1, +}; diff --git a/app/assets/javascripts/sortable/sortable_config.js b/app/assets/javascripts/sortable/sortable_config.js deleted file mode 100644 index a4c4cb7f101..00000000000 --- a/app/assets/javascripts/sortable/sortable_config.js +++ /dev/null @@ -1,8 +0,0 @@ -export default { - animation: 200, - forceFallback: true, - fallbackClass: 'is-dragging', - fallbackOnBody: true, - ghostClass: 'is-ghost', - fallbackTolerance: 1, -}; diff --git a/app/assets/javascripts/boards/mixins/sortable_default_options.js b/app/assets/javascripts/sortable/utils.js index 1bb0ee5b7e3..c2c8fb03b58 100644 --- a/app/assets/javascripts/boards/mixins/sortable_default_options.js +++ b/app/assets/javascripts/sortable/utils.js @@ -1,6 +1,6 @@ /* global DocumentTouch */ -import sortableConfig from '~/sortable/sortable_config'; +import { defaultSortableOptions } from './constants'; export function sortableStart() { document.body.classList.add('is-dragging'); @@ -10,12 +10,12 @@ export function sortableEnd() { document.body.classList.remove('is-dragging'); } -export function getBoardSortableDefaultOptions(obj) { +export function getSortableDefaultOptions(options) { const touchEnabled = 'ontouchstart' in window || (window.DocumentTouch && document instanceof DocumentTouch); const defaultSortOptions = { - ...sortableConfig, + ...defaultSortableOptions, filter: '.no-drag', delay: touchEnabled ? 100 : 0, scrollSensitivity: touchEnabled ? 60 : 100, @@ -24,8 +24,8 @@ export function getBoardSortableDefaultOptions(obj) { onEnd: sortableEnd, }; - Object.keys(obj).forEach((key) => { - defaultSortOptions[key] = obj[key]; - }); - return defaultSortOptions; + return { + ...defaultSortOptions, + ...options, + }; } diff --git a/app/assets/javascripts/vue_shared/components/markdown/field.vue b/app/assets/javascripts/vue_shared/components/markdown/field.vue index e1020ce656b..179ac2fc57f 100644 --- a/app/assets/javascripts/vue_shared/components/markdown/field.vue +++ b/app/assets/javascripts/vue_shared/components/markdown/field.vue @@ -376,6 +376,7 @@ export default { <div v-if="referencedCommands && previewMarkdown && !markdownPreviewLoading" class="referenced-commands" + data-testid="referenced-commands" v-html="referencedCommands /* eslint-disable-line vue/no-v-html */" ></div> <div v-if="shouldShowReferencedUsers" class="referenced-users"> diff --git a/app/assets/stylesheets/bootstrap_migration.scss b/app/assets/stylesheets/bootstrap_migration.scss index 27ddff181c5..598ef70297c 100644 --- a/app/assets/stylesheets/bootstrap_migration.scss +++ b/app/assets/stylesheets/bootstrap_migration.scss @@ -1,318 +1,6 @@ -$text-color: $gl-text-color; - -$brand-primary: $blue-500; -$brand-success: $green-500; -$brand-info: $blue-500; -$brand-warning: $orange-500; -$brand-danger: $red-500; - -$border-radius-base: $gl-border-radius-base; - -$modal-body-bg: $white; -$input-border: $border-color; - -$padding-base-vertical: $gl-vert-padding; -$padding-base-horizontal: $gl-padding; - -/* - * Scss to help with bootstrap 3 to 4 migration - */ -body, -.form-control, -.search form { - // Override default font size used in non-csslab UI - // Use rem to keep default font-size at 14px on body so 1rem still - // fits 8px grid, but also allow users to change browser font size - font-size: 0.875rem; -} - -legend { - border-bottom: 1px solid $border-color; - margin-bottom: 20px; -} - -button, -html [type='button'], -[type='reset'], -[type='submit'], -[role='button'] { - // Override bootstrap reboot - /* stylelint-disable-next-line property-no-vendor-prefix */ - -webkit-appearance: inherit; - cursor: pointer; -} - -h1, -.h1, -h2, -.h2, -h3, -.h3 { - margin-top: 20px; - margin-bottom: 10px; -} - -h4, -.h4, -h5, -.h5, -h6, -.h6 { - margin-top: 10px; - margin-bottom: 10px; -} - -/* Our adjustments to hx & .hx above add unnecessary margins to modal-title - and page-title in modals, so we set them to 0 in order to have properly - formatted modal headers. */ -.modal-header { - .modal-title, - .page-title { - margin-top: 0; - margin-bottom: 0; - } -} - -h5, -.h5 { - font-size: $gl-font-size; -} - -input[type='file'] { - // Bootstrap 4 file input height is taller by default - // which makes them look ugly - line-height: 1; -} - -b, -strong { - font-weight: bold; -} - -a { - color: $blue-600; -} - -hr { - overflow: hidden; -} - -.form-group.row .col-form-label { - // Bootstrap 4 aligns labels to the left - // for horizontal forms - @include media-breakpoint-up(md) { - text-align: right; - } -} - -code { - padding: 2px 4px; - color: $code-color; - background-color: $gray-50; - border-radius: $border-radius-default; - - .code > &, - .build-log & { - background-color: inherit; - padding: unset; - } -} - -table { - // Remove any table border lines - border-spacing: 0; -} - -@each $breakpoint in map-keys($grid-breakpoints) { - @include media-breakpoint-up($breakpoint) { - $infix: breakpoint-infix($breakpoint, $grid-breakpoints); - - .d#{$infix}-table-header-group { - display: table-header-group !important; - } - } -} - -.text-secondary { - // Override Bootstrap's light secondary color - // We have to use !important because bootstrap has that set as well - color: $gl-text-color-secondary !important; -} - -.bg-success, -.bg-primary, -.bg-info, -.bg-danger, -.bg-warning { - .card-header { - color: $white; - } -} - -// Polyfill deprecated selectors - -.hidden { - display: none !important; - visibility: hidden !important; -} - -.hide { - display: none; -} - -.dropdown-toggle::after, -.dropright .dropdown-menu-toggle::after { - // Remove bootstrap's dropdown caret - display: none; -} - -// Add to .label so that old system notes that are saved to the db -// will still receive the correct styling -.badge:not(.gl-badge), -.label { - padding: 4px 5px; - font-size: 12px; - font-style: normal; - font-weight: $gl-font-weight-normal; - display: inline-block; - - &.badge-gray { - background-color: $label-gray-bg; - color: $gl-text-color; - text-shadow: none; - } - - &.badge-inverse { - background-color: $label-inverse-bg; - } -} - -.divider { - // copied rules from node_modules/bootstrap/scss/_dropdown.scss:116 - // this might be safe to just remove instead - // most places that use divider add overrides to undo these things - // there is also a probably-unintentional use in deprecated_dropdown_divider.scss - // so we would end up with .gl-dropdown .dropdown-divider - height: 0; - margin: 4px 0; - overflow: hidden; - border-top: 1px solid $border-color; -} - -.info-well { - background: $gray-10; - color: $gl-text-color; - border: 1px solid $border-color; - border-radius: 4px; - margin-bottom: 16px; - - .well-segment { - padding: 16px; - - &:not(:last-of-type) { - border-bottom: 1px solid $well-inner-border; - } - - p, - ol, - ul, - .form-group { - &:last-of-type { - margin-bottom: 0; - } - } - } - - .badge.badge-gray { - background-color: $well-expand-item; - } -} - -.card { - &.card-without-border, - &.bg-light { - border: 0 !important; - } -} - -.nav-tabs { - // Override bootstrap's default border - border-bottom: 0; - - .nav-link { - border-top: 0; - border-left: 0; - border-right: 0; - } - - .nav-item { - margin-bottom: 0; - } -} - -pre code { - white-space: pre-wrap; -} - -.alert { - border-radius: 0; -} - -.alert-success { - background-color: $green-500; - border-color: $green-500; -} - -.alert-info { - background-color: $blue-500; - border-color: $blue-500; -} - -.alert-warning { - background-color: $orange-500; - border-color: $orange-500; -} - -.alert-danger { - background-color: $red-500; - border-color: $red-500; -} - -.alert-success, -.alert-info, -.alert-warning, -.alert-danger { - color: $white; - - h4, - .alert-link { - color: $white; - } -} - -input[type=color].form-control { - height: $input-height; -} - -.toggle-sidebar-button { - .collapse-text, - .icon-chevron-double-lg-left, - .icon-chevron-double-lg-right { - color: $gl-text-color-secondary; - } -} - -.project-templates-buttons { - .btn { - vertical-align: unset; - } -} - -/* - Bootstrap 4.1.2 introduced a new default vertical alignment which breaks our icons, - so we need to reset the vertical alignment to the default value. See: - - https://gitlab.com/gitlab-org/gitlab-foss/issues/51362 - */ -svg { - vertical-align: baseline; -} +// --- +// Scss to help with bootstrap 3 to 4 migration +// --- +@import 'bootstrap_migration_variables'; +@import 'bootstrap_migration_reset'; +@import 'bootstrap_migration_components'; diff --git a/app/assets/stylesheets/bootstrap_migration_components.scss b/app/assets/stylesheets/bootstrap_migration_components.scss new file mode 100644 index 00000000000..b6cecbe5806 --- /dev/null +++ b/app/assets/stylesheets/bootstrap_migration_components.scss @@ -0,0 +1,216 @@ +// --- +// Scss to help with bootstrap 3 to 4 migration of bootstrap components +// --- +.form-control, +.search form { + // Override default font size used in non-csslab UI + // Use rem to keep default font-size at 14px on body so 1rem still + // fits 8px grid, but also allow users to change browser font size + font-size: 0.875rem; +} + +/* Our adjustments to hx & .hx above add unnecessary margins to modal-title + and page-title in modals, so we set them to 0 in order to have properly + formatted modal headers. */ +.modal-header { + .modal-title, + .page-title { + margin-top: 0; + margin-bottom: 0; + } +} + +input[type='file'] { + // Bootstrap 4 file input height is taller by default + // which makes them look ugly + line-height: 1; +} + +.form-group.row .col-form-label { + // Bootstrap 4 aligns labels to the left + // for horizontal forms + @include media-breakpoint-up(md) { + text-align: right; + } +} + +@each $breakpoint in map-keys($grid-breakpoints) { + @include media-breakpoint-up($breakpoint) { + $infix: breakpoint-infix($breakpoint, $grid-breakpoints); + + .d#{$infix}-table-header-group { + display: table-header-group !important; + } + } +} + +.text-secondary { + // Override Bootstrap's light secondary color + // We have to use !important because bootstrap has that set as well + color: $gl-text-color-secondary !important; +} + +.bg-success, +.bg-primary, +.bg-info, +.bg-danger, +.bg-warning { + .card-header { + color: $white; + } +} + +// Polyfill deprecated selectors + +.hidden { + display: none !important; + visibility: hidden !important; +} + +.hide { + display: none; +} + +.dropdown-toggle::after, +.dropright .dropdown-menu-toggle::after { + // Remove bootstrap's dropdown caret + display: none; +} + +// Add to .label so that old system notes that are saved to the db +// will still receive the correct styling +.badge:not(.gl-badge), +.label { + padding: 4px 5px; + font-size: 12px; + font-style: normal; + font-weight: $gl-font-weight-normal; + display: inline-block; + + &.badge-gray { + background-color: $label-gray-bg; + color: $gl-text-color; + text-shadow: none; + } + + &.badge-inverse { + background-color: $label-inverse-bg; + } +} + +.divider { + // copied rules from node_modules/bootstrap/scss/_dropdown.scss:116 + // this might be safe to just remove instead + // most places that use divider add overrides to undo these things + // there is also a probably-unintentional use in deprecated_dropdown_divider.scss + // so we would end up with .gl-dropdown .dropdown-divider + height: 0; + margin: 4px 0; + overflow: hidden; + border-top: 1px solid $border-color; +} + +.info-well { + background: $gray-10; + color: $gl-text-color; + border: 1px solid $border-color; + border-radius: 4px; + margin-bottom: 16px; + + .well-segment { + padding: 16px; + + &:not(:last-of-type) { + border-bottom: 1px solid $well-inner-border; + } + + p, + ol, + ul, + .form-group { + &:last-of-type { + margin-bottom: 0; + } + } + } + + .badge.badge-gray { + background-color: $well-expand-item; + } +} + +.card { + &.card-without-border, + &.bg-light { + border: 0 !important; + } +} + +.nav-tabs { + // Override bootstrap's default border + border-bottom: 0; + + .nav-link { + border-top: 0; + border-left: 0; + border-right: 0; + } + + .nav-item { + margin-bottom: 0; + } +} + +.alert { + border-radius: 0; +} + +.alert-success { + background-color: $green-500; + border-color: $green-500; +} + +.alert-info { + background-color: $blue-500; + border-color: $blue-500; +} + +.alert-warning { + background-color: $orange-500; + border-color: $orange-500; +} + +.alert-danger { + background-color: $red-500; + border-color: $red-500; +} + +.alert-success, +.alert-info, +.alert-warning, +.alert-danger { + color: $white; + + h4, + .alert-link { + color: $white; + } +} + +input[type=color].form-control { + height: $input-height; +} + +.toggle-sidebar-button { + .collapse-text, + .icon-chevron-double-lg-left, + .icon-chevron-double-lg-right { + color: $gl-text-color-secondary; + } +} + +.project-templates-buttons { + .btn { + vertical-align: unset; + } +} diff --git a/app/assets/stylesheets/bootstrap_migration_reset.scss b/app/assets/stylesheets/bootstrap_migration_reset.scss new file mode 100644 index 00000000000..ad315c4ada1 --- /dev/null +++ b/app/assets/stylesheets/bootstrap_migration_reset.scss @@ -0,0 +1,94 @@ +// --- +// Scss to help with bootstrap 3 to 4 migration of core elements +// --- +body { + // Override default font size used in non-csslab UI + // Use rem to keep default font-size at 14px on body so 1rem still + // fits 8px grid, but also allow users to change browser font size + font-size: 0.875rem; +} + +legend { + border-bottom: 1px solid $border-color; + margin-bottom: 20px; +} + +button, +html [type='button'], +[type='reset'], +[type='submit'], +[role='button'] { + // Override bootstrap reboot + /* stylelint-disable-next-line property-no-vendor-prefix */ + -webkit-appearance: inherit; + cursor: pointer; +} + +h1, +.h1, +h2, +.h2, +h3, +.h3 { + margin-top: 20px; + margin-bottom: 10px; +} + +h4, +.h4, +h5, +.h5, +h6, +.h6 { + margin-top: 10px; + margin-bottom: 10px; +} + +h5, +.h5 { + font-size: $gl-font-size; +} + +b, +strong { + font-weight: bold; +} + +a { + color: $blue-600; +} + +hr { + overflow: hidden; +} + +code { + padding: 2px 4px; + color: $code-color; + background-color: $gray-50; + border-radius: $border-radius-default; + + .code > &, + .build-log & { + background-color: inherit; + padding: unset; + } +} + +table { + // Remove any table border lines + border-spacing: 0; +} + +pre code { + white-space: pre-wrap; +} + +/* + Bootstrap 4.1.2 introduced a new default vertical alignment which breaks our icons, + so we need to reset the vertical alignment to the default value. See: + - https://gitlab.com/gitlab-org/gitlab-foss/issues/51362 + */ +svg { + vertical-align: baseline; +} diff --git a/app/assets/stylesheets/bootstrap_migration_variables.scss b/app/assets/stylesheets/bootstrap_migration_variables.scss new file mode 100644 index 00000000000..f3888de4ed8 --- /dev/null +++ b/app/assets/stylesheets/bootstrap_migration_variables.scss @@ -0,0 +1,15 @@ +$text-color: $gl-text-color; + +$brand-primary: $blue-500; +$brand-success: $green-500; +$brand-info: $blue-500; +$brand-warning: $orange-500; +$brand-danger: $red-500; + +$border-radius-base: $gl-border-radius-base; + +$modal-body-bg: $white; +$input-border: $border-color; + +$padding-base-vertical: $gl-vert-padding; +$padding-base-horizontal: $gl-padding; diff --git a/app/assets/stylesheets/notify_base.scss b/app/assets/stylesheets/notify_base.scss index 8c6f9a27077..0ca1398c609 100644 --- a/app/assets/stylesheets/notify_base.scss +++ b/app/assets/stylesheets/notify_base.scss @@ -1,5 +1,6 @@ -@import 'framework/mixins'; @import 'framework/variables'; +@import 'framework/variables_overrides'; +@import 'framework/mixins'; img { max-width: 100%; diff --git a/app/assets/stylesheets/notify_enhanced.scss b/app/assets/stylesheets/notify_enhanced.scss index 5aa0fd3cd00..a366498ea03 100644 --- a/app/assets/stylesheets/notify_enhanced.scss +++ b/app/assets/stylesheets/notify_enhanced.scss @@ -2,20 +2,30 @@ // keep parts that affect elements that can appear in emails; // omit Bootstrap Reboot since it adds unnecessary styles to every element. @import 'notify_base'; + +// bootstrap variables, mixins, functions @import 'bootstrap/scss/functions'; @import 'bootstrap/scss/variables'; @import 'bootstrap/scss/mixins'; + +// bootstrap styles @import 'bootstrap/scss/code'; + +// @gitlab/ui variables, mixins, functions @import '@gitlab/ui/src/scss/variables'; @import '@gitlab/ui/src/scss/utility-mixins/index'; -@import '@gitlab/ui/src/scss/components'; -@import 'bootstrap_migration'; -@import 'framework/common'; + +// @gitlab/ui styles +@import '@gitlab/ui/src/components/base/icon/icon'; +@import '@gitlab/ui/src/components/base/label/label'; + +// gitlab styles +@import 'bootstrap_migration_variables'; +@import 'bootstrap_migration_reset'; @import 'framework/gfm'; @import 'framework/kbd'; @import 'framework/tables'; @import 'framework/typography'; -@import 'framework/emojis'; body { font-family: $regular-font; diff --git a/app/assets/stylesheets/startup/startup-dark.scss b/app/assets/stylesheets/startup/startup-dark.scss index 1b76f41a7be..a3b21caa69d 100644 --- a/app/assets/stylesheets/startup/startup-dark.scss +++ b/app/assets/stylesheets/startup/startup-dark.scss @@ -543,9 +543,7 @@ a.gl-badge.badge-warning:active { padding-right: 2rem; padding-left: 1.75rem; } -body, -.form-control, -.search form { +body { font-size: 0.875rem; } button, @@ -563,6 +561,13 @@ strong { a { color: #63a6e9; } +svg { + vertical-align: baseline; +} +.form-control, +.search form { + font-size: 0.875rem; +} .hidden { display: none !important; visibility: hidden !important; @@ -587,9 +592,6 @@ a { .toggle-sidebar-button .icon-chevron-double-lg-left { color: #999; } -svg { - vertical-align: baseline; -} html { overflow-y: scroll; } diff --git a/app/assets/stylesheets/startup/startup-general.scss b/app/assets/stylesheets/startup/startup-general.scss index 6d66e207bdc..c0a7dbc5deb 100644 --- a/app/assets/stylesheets/startup/startup-general.scss +++ b/app/assets/stylesheets/startup/startup-general.scss @@ -529,9 +529,7 @@ a.gl-badge.badge-warning:active { padding-right: 2rem; padding-left: 1.75rem; } -body, -.form-control, -.search form { +body { font-size: 0.875rem; } button, @@ -549,6 +547,13 @@ strong { a { color: #1068bf; } +svg { + vertical-align: baseline; +} +.form-control, +.search form { + font-size: 0.875rem; +} .hidden { display: none !important; visibility: hidden !important; @@ -573,9 +578,6 @@ a { .toggle-sidebar-button .icon-chevron-double-lg-left { color: #666; } -svg { - vertical-align: baseline; -} html { overflow-y: scroll; } diff --git a/app/assets/stylesheets/startup/startup-signin.scss b/app/assets/stylesheets/startup/startup-signin.scss index 213d1c013a0..00913fa1fdc 100644 --- a/app/assets/stylesheets/startup/startup-signin.scss +++ b/app/assets/stylesheets/startup/startup-signin.scss @@ -369,8 +369,7 @@ fieldset:disabled a.btn { outline: none; background-color: #0b5cad; } -body, -.form-control { +body { font-size: 0.875rem; } [type="submit"] { @@ -387,6 +386,12 @@ a { hr { overflow: hidden; } +svg { + vertical-align: baseline; +} +.form-control { + font-size: 0.875rem; +} .hidden { display: none !important; visibility: hidden !important; @@ -394,9 +399,6 @@ hr { .hide { display: none; } -svg { - vertical-align: baseline; -} html { overflow-y: scroll; } diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb index ec1f8ca5f00..98eca3785e7 100644 --- a/app/helpers/issuables_helper.rb +++ b/app/helpers/issuables_helper.rb @@ -233,7 +233,7 @@ module IssuablesHelper canUpdate: can?(current_user, :"update_#{issuable.to_ability_name}", issuable), canDestroy: can?(current_user, :"destroy_#{issuable.to_ability_name}", issuable), issuableRef: issuable.to_reference, - markdownPreviewPath: preview_markdown_path(parent), + markdownPreviewPath: preview_markdown_path(parent, target_type: issuable.model_name, target_id: issuable.iid), markdownDocsPath: help_page_path('user/markdown'), lockVersion: issuable.lock_version, issuableTemplateNamesPath: template_names_path(parent, issuable), diff --git a/app/models/integrations/jira.rb b/app/models/integrations/jira.rb index 74ece57000f..b20efa55529 100644 --- a/app/models/integrations/jira.rb +++ b/app/models/integrations/jira.rb @@ -143,7 +143,7 @@ module Integrations end def help - jira_doc_link_start = '<a href="%{url}">'.html_safe % { url: help_page_url('integration/jira/index.html') } + jira_doc_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('integration/jira/index') } s_("JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}") % { jira_doc_link_start: jira_doc_link_start, link_end: '</a>'.html_safe } end @@ -160,8 +160,6 @@ module Integrations end def sections - jira_issues_link_start = '<a href="%{url}">'.html_safe % { url: help_page_url('integration/jira/issues.html') } - sections = [ { type: SECTION_TYPE_CONNECTION, @@ -180,7 +178,7 @@ module Integrations sections.push({ type: SECTION_TYPE_JIRA_ISSUES, title: _('Issues'), - description: s_('JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues. %{jira_issues_link_start}Learn more.%{link_end}') % { jira_issues_link_start: jira_issues_link_start, link_end: '</a>'.html_safe } + description: jira_issues_section_description }) end @@ -610,6 +608,19 @@ module Integrations data_fields.deployment_server! end end + + def jira_issues_section_description + jira_issues_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('integration/jira/issues') } + description = s_('JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues. %{jira_issues_link_start}Learn more.%{link_end}') % { jira_issues_link_start: jira_issues_link_start, link_end: '</a>'.html_safe } + + if project&.issues_enabled? + gitlab_issues_link_start = '<a href="%{url}">'.html_safe % { url: edit_project_path(project, anchor: 'js-shared-permissions') } + description += '<br><br>'.html_safe + description += s_("JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{gitlab_issues_link_start}disabling GitLab issues%{link_end} if they won't otherwise be used.") % { gitlab_issues_link_start: gitlab_issues_link_start, link_end: '</a>'.html_safe } + end + + description + end end end diff --git a/app/services/bulk_imports/relation_export_service.rb b/app/services/bulk_imports/relation_export_service.rb index 14f073120c5..c43f0d8cb4f 100644 --- a/app/services/bulk_imports/relation_export_service.rb +++ b/app/services/bulk_imports/relation_export_service.rb @@ -4,6 +4,8 @@ module BulkImports class RelationExportService include Gitlab::ImportExport::CommandLineUtil + EXISTING_EXPORT_TTL = 3.minutes + def initialize(user, portable, relation, jid) @user = user @portable = portable @@ -31,6 +33,9 @@ module BulkImports validate_user_permissions! export = portable.bulk_import_exports.safe_find_or_create_by!(relation: relation) + + return export if export.finished? && export.updated_at > EXISTING_EXPORT_TTL.ago + export.update!(status_event: 'start', jid: jid) yield export diff --git a/app/views/admin/groups/index.html.haml b/app/views/admin/groups/index.html.haml index 17dccae44b5..2ea5890be2c 100644 --- a/app/views/admin/groups/index.html.haml +++ b/app/views/admin/groups/index.html.haml @@ -5,9 +5,8 @@ = form_tag admin_groups_path, method: :get, class: 'js-search-form' do |f| = hidden_field_tag :sort, @sort .search-holder - - project_name = params[:name].present? ? params[:name] : nil .search-field-holder - = search_field_tag :name, project_name, class: "form-control search-text-input js-search-input", autofocus: true, spellcheck: false, placeholder: 'Search by name', data: { qa_selector: 'group_search_field' } + = search_field_tag :name, params[:name].presence, class: "form-control search-text-input js-search-input", autofocus: true, spellcheck: false, placeholder: 'Search by name', data: { qa_selector: 'group_search_field' } = sprite_icon('search', css_class: 'search-icon') = render "shared/groups/dropdown", options_hash: admin_groups_sort_options_hash = link_to new_admin_group_path, class: "gl-button btn btn-confirm" do diff --git a/app/views/projects/services/_form.html.haml b/app/views/projects/services/_form.html.haml index 9ae7acab925..d1d9a220068 100644 --- a/app/views/projects/services/_form.html.haml +++ b/app/views/projects/services/_form.html.haml @@ -11,7 +11,7 @@ .gl-alert-body = s_('ExternalIssueIntegration|Only one issue tracker integration can be active at a time. Please disable the active tracker first and try again.') -%h3.page-title +%h2.gl-mb-4 = integration.title - if integration.operating? = sprite_icon('check', css_class: 'gl-text-green-500') diff --git a/app/views/shared/integrations/edit.html.haml b/app/views/shared/integrations/edit.html.haml index f2a31400698..0ae0eea59d8 100644 --- a/app/views/shared/integrations/edit.html.haml +++ b/app/views/shared/integrations/edit.html.haml @@ -3,7 +3,7 @@ - page_title @integration.title, _('Integrations') - @content_class = 'limit-container-width' unless fluid_layout -%h3.page-title +%h2.gl-mb-4 = @integration.title = render 'shared/integrations/tabs', integration: @integration, active_tab: 'edit' do diff --git a/app/workers/bulk_imports/relation_export_worker.rb b/app/workers/bulk_imports/relation_export_worker.rb index 9324b79cc75..dcac841b3b2 100644 --- a/app/workers/bulk_imports/relation_export_worker.rb +++ b/app/workers/bulk_imports/relation_export_worker.rb @@ -3,12 +3,12 @@ module BulkImports class RelationExportWorker include ApplicationWorker - - data_consistency :always include ExceptionBacktrace idempotent! + deduplicate :until_executed loggable_arguments 2, 3 + data_consistency :always feature_category :importers sidekiq_options status_expiration: StuckExportJobsWorker::EXPORT_JOBS_EXPIRATION diff --git a/data/deprecations/14-10-manual-iteration-management.yml b/data/deprecations/14-10-manual-iteration-management.yml new file mode 100644 index 00000000000..f677f4fe668 --- /dev/null +++ b/data/deprecations/14-10-manual-iteration-management.yml @@ -0,0 +1,34 @@ +- name: "Manual iteration management" # The name of the feature to be deprecated + announcement_milestone: "14.10" # The milestone when this feature was first announced as deprecated. + announcement_date: "2022-04-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post. + removal_milestone: "16.0" # The milestone when this feature is planned to be removed + removal_date: "2023-04-22" # The date of the milestone release when this feature is planned to be removed. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post. + breaking_change: true # If this deprecation is a breaking change, set this value to true + reporter: mcelicalderonG # GitLab username of the person reporting the deprecation + body: | # Do not modify this line, instead modify the lines below. + Manual iteration management is deprecated and only automatic iteration cadences will be supported in the future. + + Creating and deleting iterations will be fully removed in 16.0. Updating all iteration fields except for + `description` will also be removed. + + On the GraphQL API the following mutations will be removed: + + 1. `iterationCreate` + 1. `iterationDelete` + + The update `updateIteration` mutation will only allow updating the iteration's `description`. The following + arguments will be removed: + + 1. `title` + 1. `dueDate` + 1. `startDate` + + For more information about iteration cadences, you can refer to + [the documentation of the feature](https://docs.gitlab.com/ee/user/group/iterations/#iteration-cadences). +# The following items are not published on the docs page, but may be used in the future. + stage: Plan + tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate] + issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/356069 + documentation_url: # (optional) This is a link to the current documentation page + image_url: # (optional) This is a link to a thumbnail image depicting the feature + video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg diff --git a/doc/administration/package_information/postgresql_versions.md b/doc/administration/package_information/postgresql_versions.md index e707cb70187..c80437221c4 100644 --- a/doc/administration/package_information/postgresql_versions.md +++ b/doc/administration/package_information/postgresql_versions.md @@ -26,8 +26,8 @@ Read more about update policies and warnings in the PostgreSQL | GitLab version | PostgreSQL versions | Default version for fresh installs | Default version for upgrades | Notes | | -------------- | --------------------- | ---------------------------------- | ---------------------------- | ----- | -| 14.1 | 12.6, 13.3 | 12.6 | 12.6 | PostgreSQL 13 available for fresh installations if not using [Geo](../geo/index.md#requirements-for-running-geo) or [Patroni](../postgresql/index.md#postgresql-replication-and-failover-with-omnibus-gitlab). -| 14.0 | 12.6 | 12.6 | 12.6 | HA installations with repmgr are no longer supported and will be prevented from upgrading to Omnibus GitLab 14.0 | +| 14.1 | 12.7, 13.3 | 12.7 | 12.7 | PostgreSQL 13 available for fresh installations if not using [Geo](../geo/index.md#requirements-for-running-geo) or [Patroni](../postgresql/index.md#postgresql-replication-and-failover-with-omnibus-gitlab). +| 14.0 | 12.7 | 12.7 | 12.7 | HA installations with repmgr are no longer supported and will be prevented from upgrading to Omnibus GitLab 14.0 | | 13.8 | 11.9, 12.4 | 12.4 | 12.4 | Package upgrades automatically performed PostgreSQL upgrade for nodes that are not part of a Geo or HA cluster.). | | 13.7 | 11.9, 12.4 | 12.4 | 11.9 | For upgrades users can manually upgrade to 12.4 following the [upgrade docs](https://docs.gitlab.com/omnibus/settings/database.html#gitlab-133-and-later). | | 13.4 | 11.9, 12.4 | 11.9 | 11.9 | Package upgrades aborted if users not running PostgreSQL 11 already | diff --git a/doc/administration/package_information/supported_os.md b/doc/administration/package_information/supported_os.md index cda5f5a5928..16038b9ebf5 100644 --- a/doc/administration/package_information/supported_os.md +++ b/doc/administration/package_information/supported_os.md @@ -28,10 +28,10 @@ The following lists the currently supported OSs and their possible EOL dates. | Ubuntu 18.04 | GitLab CE / GitLab EE 10.7.0 | amd64 | April 2023 | <https://wiki.ubuntu.com/Releases> | | Ubuntu 20.04 | GitLab CE / GitLab EE 13.2.0 | amd64, arm64 | April 2025 | <https://wiki.ubuntu.com/Releases> | | Amazon Linux 2 | GitLab CE / GitLab EE 14.9.0 | amd64, arm64 | June 2023 | <https://aws.amazon.com/amazon-linux-2/faqs/> | -| Raspbian Buster | GitLab CE 12.2.0 | armhf | 2022 | <https://wiki.debian.org/DebianReleases#Production_Releases> | +| Raspberry Pi OS (Buster) (formerly known as Raspbian Buster) | GitLab CE 12.2.0 | armhf | 2024 | <https://www.raspberrypi.com/news/new-old-functionality-with-raspberry-pi-os-legacy/> | NOTE: -CentOS 8 will be EOL on December 31, 2021. In GitLab 14.5 and later, +CentOS 8 was EOL on December 31, 2021. In GitLab 14.5 and later, [CentOS builds work in AlmaLinux](https://gitlab.com/gitlab-org/distribution/team-tasks/-/issues/954#note_730198505). We will officially support all distributions that are binary compatible with Red Hat Enterprise Linux. This gives users a path forward for their CentOS 8 builds at its end of life. @@ -78,7 +78,7 @@ release for them can be found below: | Ubuntu 14.04 | [April 2019](https://ubuntu.com/info/release-end-of-life) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce_11.10&dist=ubuntu%2Ftrusty) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee_11.10&dist=ubuntu%2Ftrusty) 11.10 | | OpenSUSE 42.3 | [July 2019](https://en.opensuse.org/Lifetime#Discontinued_distributions) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce-12.1&dist=opensuse%2F42.3) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee-12.1&dist=opensuse%2F42.3) 12.1 | | OpenSUSE 15.0 | [December 2019](https://en.opensuse.org/Lifetime#Discontinued_distributions) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce-12.5&dist=opensuse%2F15.0) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee-12.5&dist=opensuse%2F15.0) 12.5 | -| Raspbian Stretch | [June 2020](https://downloads.raspberrypi.org/raspbian/images/raspbian-2019-04-09/) | [GitLab CE](https://packages.gitlab.com/app/gitlab/raspberry-pi2/search?q=gitlab-ce_13.2&dist=raspbian%2Fstretch) 13.3 | +| Raspbian Stretch | [June 2020](https://downloads.raspberrypi.org/raspbian/images/raspbian-2019-04-09/) | [GitLab CE](https://packages.gitlab.com/app/gitlab/raspberry-pi2/search?q=gitlab-ce_13.3&dist=raspbian%2Fstretch) 13.3 | | Debian Jessie | [June 2020](https://www.debian.org/News/2020/20200709) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce_13.2&dist=debian%2Fjessie) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee_13.2&dist=debian%2Fjessie) 13.3 | | CentOS 6 | [November 2020](https://wiki.centos.org/About/Product) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=13.6&filter=all&filter=all&dist=el%2F6) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=13.6&filter=all&filter=all&dist=el%2F6) 13.6 | | OpenSUSE 15.1 | [November 2020](https://en.opensuse.org/Lifetime#Discontinued_distributions) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce-13.12&dist=opensuse%2F15.1) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee-13.12&dist=opensuse%2F15.1) 13.12 | diff --git a/doc/api/runners.md b/doc/api/runners.md index c450efe8c3f..304f2494f70 100644 --- a/doc/api/runners.md +++ b/doc/api/runners.md @@ -448,7 +448,7 @@ Example response: ## List project's runners -List all runners available in the project, including from ancestor groups and [any allowed shared runners](../ci/runners/runners_scope.md#enable-shared-runners). +List all runners available in the project, including from ancestor groups and [any allowed shared runners](../ci/runners/runners_scope.md#enable-shared-runners-for-a-project). ```plaintext GET /projects/:id/runners @@ -566,7 +566,7 @@ curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://git ## List group's runners -List all runners available in the group as well as its ancestor groups, including [any allowed shared runners](../ci/runners/runners_scope.md#enable-shared-runners). +List all runners available in the group as well as its ancestor groups, including [any allowed shared runners](../ci/runners/runners_scope.md#enable-shared-runners-for-a-group). ```plaintext GET /groups/:id/runners diff --git a/doc/ci/runners/runners_scope.md b/doc/ci/runners/runners_scope.md index fb5395076b0..6082a17d001 100644 --- a/doc/ci/runners/runners_scope.md +++ b/doc/ci/runners/runners_scope.md @@ -37,22 +37,31 @@ If you are using GitLab.com: - The shared runners consume the [CI/CD minutes](../pipelines/cicd_minutes.md) included with your account. -### Enable shared runners +### Enable shared runners for a project On GitLab.com, [shared runners](index.md) are enabled in all projects by default. -On self-managed instances of GitLab, an administrator must [install](https://docs.gitlab.com/runner/install/index.html) -and [register](https://docs.gitlab.com/runner/register/index.html) them. +On self-managed instances of GitLab, an administrator can +[enable them for all new projects](../../user/admin_area/settings/continuous_integration.md#enable-shared-runners-for-new-projects). -You can also enable shared runners for individual projects. +For existing projects, an administrator must +[install](https://docs.gitlab.com/runner/install/index.html) and +[register](https://docs.gitlab.com/runner/register/index.html) them. -To enable shared runners: +To enable shared runners for a project: 1. Go to the project's **Settings > CI/CD** and expand the **Runners** section. 1. Select **Enable shared runners for this project**. -### Disable shared runners +### Enable shared runners for a group + +To enable shared runners for a group: + +1. Go to the group's **Settings > CI/CD** and expand the **Runners** section. +1. Select **Enable shared runners for this group**. + +### Disable shared runners for a project You can disable shared runners for individual projects or for groups. You must have the Owner role for the project @@ -68,6 +77,8 @@ Shared runners are automatically disabled for a project: - If the shared runners setting for the parent group is disabled, and - If overriding this setting is not permitted at the project level. +### Disable shared runners for a group + To disable shared runners for a group: 1. Go to the group's **Settings > CI/CD** and expand the **Runners** section. @@ -78,7 +89,7 @@ To disable shared runners for a group: NOTE: To re-enable the shared runners for a group, turn on the **Enable shared runners for this group** toggle. -Then, an owner or maintainer must explicitly change this setting +Then, a user with the Owner or Maintainer role must explicitly change this setting for each project subgroup or project. ### How shared runners pick jobs diff --git a/doc/development/documentation/feature_flags.md b/doc/development/documentation/feature_flags.md index 1e4698ff867..fb58851e93f 100644 --- a/doc/development/documentation/feature_flags.md +++ b/doc/development/documentation/feature_flags.md @@ -19,8 +19,29 @@ must be documented. For context, see the When you document feature flags, you must: -- [Add a note at the start of the topic](#use-a-note-to-describe-the-state-of-the-feature-flag). - [Add version history text](#add-version-history-text). +- [Add a note at the start of the topic](#use-a-note-to-describe-the-state-of-the-feature-flag). + +## Add version history text + +When the state of a flag changes (for example, disabled by default to enabled by default), add the change to the version history. + +Possible version history entries are: + +```markdown +> - [Introduced](issue-link) in GitLab X.X [with a flag](../../administration/feature_flags.md) named <flag name>. Disabled by default. +> - [Enabled on GitLab.com](issue-link) in GitLab X.X. +> - [Enabled on GitLab.com](issue-link) in GitLab X.X. Available to GitLab.com administrators only. +> - [Enabled on self-managed](issue-link) in GitLab X.X. +> - [Generally available](issue-link) in GitLab X.Y. [Feature flag <flag name>](issue-link) removed. +``` + +You can combine entries if they happened in the same release: + +```markdown +> - Introduced in GitLab 14.2 [with a flag](../../administration/feature_flags.md) named `ci_include_rules`. Disabled by default. +> - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/337507) in GitLab 14.3. +``` ## Use a note to describe the state of the feature flag @@ -30,7 +51,8 @@ The note has three parts, and follows this structure: ```markdown FLAG: -<Self-managed GitLab availability information.> <GitLab.com availability information.> +<Self-managed GitLab availability information.> +<GitLab.com availability information.> <This feature is not ready for production use.> ``` @@ -61,27 +83,6 @@ If needed, you can add this sentence: `The feature is not ready for production use.` -## Add version history text - -When the state of a flag changes (for example, disabled by default to enabled by default), add the change to the version history. - -Possible version history entries are: - -```markdown -> - [Introduced](issue-link) in GitLab X.X [with a flag](../../administration/feature_flags.md) named <flag name>. Disabled by default. -> - [Enabled on GitLab.com](issue-link) in GitLab X.X. -> - [Enabled on GitLab.com](issue-link) in GitLab X.X. Available to GitLab.com administrators only. -> - [Enabled on self-managed](issue-link) in GitLab X.X. -> - [Generally available](issue-link) in GitLab X.Y. [Feature flag <flag name>](issue-link) removed. -``` - -You can combine entries if they happened in the same release: - -```markdown -> - Introduced in GitLab 14.2 [with a flag](../../administration/feature_flags.md) named `ci_include_rules`. Disabled by default. -> - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/337507) in GitLab 14.3. -``` - ## Feature flag documentation examples The following examples show the progression of a feature flag. diff --git a/doc/development/service_ping/implement.md b/doc/development/service_ping/implement.md index 25e841e113b..ca4a0158051 100644 --- a/doc/development/service_ping/implement.md +++ b/doc/development/service_ping/implement.md @@ -760,7 +760,7 @@ To set up Service Ping locally, you must: 1. Clone and start [Versions Application](https://gitlab.com/gitlab-services/version-gitlab-com). Make sure you run `docker-compose up` to start a PostgreSQL and Redis instance. 1. Point GitLab to the Versions Application endpoint instead of the default endpoint: - 1. Open [service_ping/submit_service.rb](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/services/service_ping/submit_service.rb#L5) in your local and modified `PRODUCTION_URL`. + 1. Open [service_ping/submit_service.rb](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/services/service_ping/submit_service.rb#L5) locally and modify `STAGING_BASE_URL`. 1. Set it to the local Versions Application URL: `http://localhost:3000/usage_data`. ### Test local setup diff --git a/doc/update/deprecations.md b/doc/update/deprecations.md index 752e05a8cd4..0bbaf677a75 100644 --- a/doc/update/deprecations.md +++ b/doc/update/deprecations.md @@ -42,6 +42,38 @@ Each deprecation has a **planned removal milestone** and indicates whether it is Most of the deprecations are **planned for removal in 15.0**, and many of them are **breaking changes**. +## 14.10 + +### Manual iteration management + +WARNING: +This feature will be changed or removed in 16.0 +as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#breaking-changes). +Before updating GitLab, review the details carefully to determine if you need to make any +changes to your code, settings, or workflow. + +Manual iteration management is deprecated and only automatic iteration cadences will be supported in the future. + +Creating and deleting iterations will be fully removed in 16.0. Updating all iteration fields except for +`description` will also be removed. + +On the GraphQL API the following mutations will be removed: + + 1. `iterationCreate` + 1. `iterationDelete` + +The update `updateIteration` mutation will only allow updating the iteration's `description`. The following +arguments will be removed: + + 1. `title` + 1. `dueDate` + 1. `startDate` + +For more information about iteration cadences, you can refer to +[the documentation of the feature](https://docs.gitlab.com/ee/user/group/iterations/#iteration-cadences). + +**Planned removal milestone: 16.0 (2023-04-22)** + ## 14.9 ### Background upload for object storage diff --git a/doc/user/admin_area/settings/continuous_integration.md b/doc/user/admin_area/settings/continuous_integration.md index 0330d89aedc..7d968ff5e86 100644 --- a/doc/user/admin_area/settings/continuous_integration.md +++ b/doc/user/admin_area/settings/continuous_integration.md @@ -28,7 +28,18 @@ From now on, every existing project and newly created ones that don't have a If you want to disable it for a specific project, you can do so in [its settings](../../../topics/autodevops/index.md#enable-or-disable-auto-devops). -## Shared runner details +## Enable shared runners for new projects + +You can set all new projects to have the instance's shared runners available by default. + +1. On the top bar, select **Menu > Admin**. +1. On the left sidebar, select **Settings > CI/CD**. +1. Expand **Continuous Integration and Deployment**. +1. Select the **Enable shared runners for new projects** checkbox. + +Any time a new project is created, the shared runners are available. + +## Add a message for shared runners To display details about the instance's shared runners in all projects' runner settings: @@ -36,16 +47,17 @@ runner settings: 1. On the top bar, select **Menu > Admin**. 1. On the left sidebar, select **Settings > CI/CD**. 1. Expand **Continuous Integration and Deployment**. -1. Enter your shared runner details in the **Shared runner details** field. +1. Enter text, including Markdown if you want, in the **Shared runner details** field. For example: + + ![Shared runner details input](img/continuous_integration_shared_runner_details_input_v14_10.png) -You can use [Markdown](../../markdown.md) for improved formatting. To see the rendered -details: +To view the rendered details: 1. On the top bar, select **Menu > Project** and select any group or project. 1. On the left sidebar, select **Settings > CI/CD**. 1. Expand **Runners**. -![Shared runner details example](img/continuous_integration_shared_runner_details_v14_0.png) +![Shared runner details example](img/continuous_integration_shared_runner_details_v14_10.png) ## Maximum artifacts size diff --git a/doc/user/admin_area/settings/img/continuous_integration_shared_runner_details_input_v14_10.png b/doc/user/admin_area/settings/img/continuous_integration_shared_runner_details_input_v14_10.png Binary files differnew file mode 100644 index 00000000000..08451f36962 --- /dev/null +++ b/doc/user/admin_area/settings/img/continuous_integration_shared_runner_details_input_v14_10.png diff --git a/doc/user/admin_area/settings/img/continuous_integration_shared_runner_details_v14_0.png b/doc/user/admin_area/settings/img/continuous_integration_shared_runner_details_v14_0.png Binary files differdeleted file mode 100644 index d8bc3deccd4..00000000000 --- a/doc/user/admin_area/settings/img/continuous_integration_shared_runner_details_v14_0.png +++ /dev/null diff --git a/doc/user/admin_area/settings/img/continuous_integration_shared_runner_details_v14_10.png b/doc/user/admin_area/settings/img/continuous_integration_shared_runner_details_v14_10.png Binary files differnew file mode 100644 index 00000000000..64bd9cf6911 --- /dev/null +++ b/doc/user/admin_area/settings/img/continuous_integration_shared_runner_details_v14_10.png diff --git a/doc/user/group/iterations/index.md b/doc/user/group/iterations/index.md index 999d4b15cb0..8453c5cf4bd 100644 --- a/doc/user/group/iterations/index.md +++ b/doc/user/group/iterations/index.md @@ -45,7 +45,7 @@ From there you can create a new iteration or select an iteration to get a more d WARNING: Manual iteration management is in its end-of-life process. Creating an iteration is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/356069) -for use in GitLab 14.10, and is planned for removal in GitLab 15.6. +for use in GitLab 14.10, and is planned for removal in GitLab 16.0. Prerequisites: @@ -66,7 +66,7 @@ To create an iteration: WARNING: Editing all attributes, with the exception of `description` is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/356069) -for use in GitLab 14.10, and is planned for removal in GitLab 15.6. +for use in GitLab 14.10, and is planned for removal in GitLab 16.0. In the future only editing an iteration's `description` will be allowed. Prerequisites: @@ -82,7 +82,7 @@ To edit an iteration, select the three-dot menu (**{ellipsis_v}**) > **Edit**. WARNING: Manual iteration management is in its end-of-life process. Deleting an iteration is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/356069) -for use in GitLab 14.10, and is planned for removal in GitLab 15.6. +for use in GitLab 14.10, and is planned for removal in GitLab 16.0. Prerequisites: diff --git a/doc/user/markdown.md b/doc/user/markdown.md index 5d7c480143a..a98a032078d 100644 --- a/doc/user/markdown.md +++ b/doc/user/markdown.md @@ -525,6 +525,7 @@ GitLab Flavored Markdown recognizes the following: | merge request | `!123` | `namespace/project!123` | `project!123` | | snippet | `$123` | `namespace/project$123` | `project$123` | | [epic](group/epics/index.md) | `&123` | `group1/subgroup&123` | | +| [iteration](group/iterations/index.md) | `*iteration:"iteration title"`| | | | [vulnerability](application_security/vulnerabilities/index.md) <sup>1</sup> | `[vulnerability:123]` | `[vulnerability:namespace/project/123]` | `[vulnerability:project/123]` | | feature flag | `[feature_flag:123]` | `[feature_flag:namespace/project/123]` | `[feature_flag:project/123]` | | label by ID | `~123` | `namespace/project~123` | `project~123` | diff --git a/doc/user/project/settings/import_export.md b/doc/user/project/settings/import_export.md index 4fe12320f77..30261ed5082 100644 --- a/doc/user/project/settings/import_export.md +++ b/doc/user/project/settings/import_export.md @@ -238,7 +238,7 @@ and the exports between them are compatible. ### Project fails to import due to mismatch -If the [shared runners enablement](../../../ci/runners/runners_scope.md#enable-shared-runners) +If the [shared runners enablement](../../../ci/runners/runners_scope.md#enable-shared-runners-for-a-project) does not match between the exported project, and the project import, the project fails to import. Review [issue 276930](https://gitlab.com/gitlab-org/gitlab/-/issues/276930), and either: diff --git a/doc/user/shortcuts.md b/doc/user/shortcuts.md index e807f251da1..e5285d63cf4 100644 --- a/doc/user/shortcuts.md +++ b/doc/user/shortcuts.md @@ -101,6 +101,12 @@ These shortcuts are available when viewing issues and [merge requests](project/m | <kbd>b</kbd> | Copy source branch name (merge requests only). | | <kbd>.</kbd> | Open the [Web IDE](project/web_ide/index.md). | +Merge requests additionally support the following shortcuts: + +| macOS shortcut | Windows shortcut | Description | +|---------------------------------|---------------------|-------------| +| <kbd>Command</kbd> + <kbd>p</kbd> | <kbd>Control</kbd> + <kbd>p</kbd> | Search for, and then jump to a file for review. | + ### Project files These shortcuts are available when browsing the files in a project (go to diff --git a/locale/gitlab.pot b/locale/gitlab.pot index ed6931385af..cba3c316a32 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -21400,7 +21400,7 @@ msgstr "" msgid "JiraService|Define the type of Jira issue to create from a vulnerability." msgstr "" -msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used." +msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{gitlab_issues_link_start}disabling GitLab issues%{link_end} if they won't otherwise be used." msgstr "" msgid "JiraService|Enable Jira issue creation from vulnerabilities" @@ -21451,9 +21451,6 @@ msgstr "" msgid "JiraService|Jira comments are created when an issue is referenced in a merge request." msgstr "" -msgid "JiraService|Jira issue type" -msgstr "" - msgid "JiraService|Jira issues" msgstr "" diff --git a/qa/qa/specs/features/browser_ui/6_release/pipeline/multi-project_pipelines_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/multi-project_pipelines_spec.rb index 76c2cdadfd9..9c852f836c8 100644 --- a/qa/qa/specs/features/browser_ui/6_release/pipeline/multi-project_pipelines_spec.rb +++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/multi-project_pipelines_spec.rb @@ -43,7 +43,10 @@ module QA [upstream_project, downstream_project].each(&:remove_via_api!) end - it 'creates a multi-project pipeline', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348032' do + it( + 'creates a multi-project pipeline', + testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/358064' + ) do Page::Project::Pipeline::Show.perform do |show| expect(show).to have_passed expect(show).not_to have_job(downstream_job_name) diff --git a/qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_dependent_relationship_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/parent_child_pipelines_dependent_relationship_spec.rb index 6841d4d19ba..2cab467249f 100644 --- a/qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_dependent_relationship_spec.rb +++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/parent_child_pipelines_dependent_relationship_spec.rb @@ -25,7 +25,10 @@ module QA runner.remove_via_api! end - it 'parent pipelines passes if child passes', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348092' do + it( + 'parent pipelines passes if child passes', + testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/358062' + ) do add_ci_files(success_child_ci_file) Flow::Pipeline.visit_latest_pipeline @@ -35,7 +38,10 @@ module QA end end - it 'parent pipeline fails if child fails', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348091' do + it( + 'parent pipeline fails if child fails', + testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/358063' + ) do add_ci_files(fail_child_ci_file) Flow::Pipeline.visit_latest_pipeline diff --git a/qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_independent_relationship_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/parent_child_pipelines_independent_relationship_spec.rb index fe46590c8f2..51212b8e54a 100644 --- a/qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_independent_relationship_spec.rb +++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/parent_child_pipelines_independent_relationship_spec.rb @@ -25,7 +25,10 @@ module QA runner.remove_via_api! end - it 'parent pipelines passes if child passes', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348093' do + it( + 'parent pipelines passes if child passes', + testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/358059' + ) do add_ci_files(success_child_ci_file) Flow::Pipeline.visit_latest_pipeline @@ -35,7 +38,10 @@ module QA end end - it 'parent pipeline passes even if child fails', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348094' do + it( + 'parent pipeline passes even if child fails', + testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/358060' + ) do add_ci_files(fail_child_ci_file) Flow::Pipeline.visit_latest_pipeline diff --git a/qa/spec/spec_helper.rb b/qa/spec/spec_helper.rb index f5d39e1cdd5..b81c41bb79c 100644 --- a/qa/spec/spec_helper.rb +++ b/qa/spec/spec_helper.rb @@ -79,7 +79,11 @@ RSpec.configure do |config| # If any tests failed, leave the resources behind to help troubleshoot, otherwise remove them. # Do not remove the shared resource on live environments begin - QA::Resource::ReusableCollection.remove_all_via_api! if !suite.reporter.failed_examples.present? && !QA::Runtime::Env.running_on_dot_com? + next if suite.reporter.failed_examples.present? + next unless QA::Runtime::Scenario.attributes.include?(:gitlab_address) + next if QA::Runtime::Env.running_on_dot_com? + + QA::Resource::ReusableCollection.remove_all_via_api! rescue QA::Resource::Errors::InternalServerError => e # Temporarily prevent this error from failing jobs while the cause is investigated # See https://gitlab.com/gitlab-org/gitlab/-/issues/354387 diff --git a/spec/features/admin/admin_runners_spec.rb b/spec/features/admin/admin_runners_spec.rb index 0837664dcc3..96e1f558255 100644 --- a/spec/features/admin/admin_runners_spec.rb +++ b/spec/features/admin/admin_runners_spec.rb @@ -4,7 +4,6 @@ require 'spec_helper' RSpec.describe "Admin Runners" do include StubENV - include Spec::Support::Helpers::ModalHelpers before do stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false') @@ -15,7 +14,7 @@ RSpec.describe "Admin Runners" do wait_for_requests end - describe "Runners page", :js do + describe "Admin Runners page", :js do let_it_be(:user) { create(:user) } let_it_be(:group) { create(:group) } let_it_be(:namespace) { create(:namespace) } @@ -486,63 +485,14 @@ RSpec.describe "Admin Runners" do end end - describe 'runners registration' do - let!(:token) { Gitlab::CurrentSettings.runners_registration_token } - + describe "runners registration" do before do visit admin_runners_path - - click_on 'Register an instance runner' end - describe 'show registration instructions' do - before do - click_on 'Show runner installation and registration instructions' - - wait_for_requests - end - - it 'opens runner installation modal' do - expect(page).to have_text "Install a runner" - - expect(page).to have_text "Environment" - expect(page).to have_text "Architecture" - expect(page).to have_text "Download and install binary" - end - - it 'dismisses runner installation modal' do - within_modal do - click_button('Close', match: :first) - end - - expect(page).not_to have_text "Install a runner" - end - end - - it 'has a registration token' do - click_on 'Click to reveal' - expect(page.find('[data-testid="token-value"]')).to have_content(token) - end - - describe 'reset registration token' do - let(:page_token) { find('[data-testid="token-value"]').text } - - before do - click_on 'Reset registration token' - - within_modal do - click_button('Reset token', match: :first) - end - - wait_for_requests - end - - it 'changes registration token' do - click_on 'Register an instance runner' - - click_on 'Click to reveal' - expect(page_token).not_to eq token - end + it_behaves_like "shows and resets runner registration token" do + let(:dropdown_text) { 'Register an instance runner' } + let(:registration_token) { Gitlab::CurrentSettings.runners_registration_token } end end end diff --git a/spec/features/groups/group_runners_spec.rb b/spec/features/groups/group_runners_spec.rb new file mode 100644 index 00000000000..beb465cd3a5 --- /dev/null +++ b/spec/features/groups/group_runners_spec.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe "Group Runners" do + let_it_be(:group_owner) { create(:user) } + let_it_be(:group) { create(:group) } + + let!(:group_registration_token) { group.runners_token } + + before do + group.add_owner(group_owner) + sign_in(group_owner) + end + + describe "Group runners page", :js do + describe "runners registration" do + before do + visit group_runners_path(group) + end + + it_behaves_like "shows and resets runner registration token" do + let(:dropdown_text) { 'Register a group runner' } + let(:registration_token) { group_registration_token } + end + end + end +end diff --git a/spec/features/issues/user_creates_issue_spec.rb b/spec/features/issues/user_creates_issue_spec.rb index 446f13dc4d0..8a5e33ba18c 100644 --- a/spec/features/issues/user_creates_issue_spec.rb +++ b/spec/features/issues/user_creates_issue_spec.rb @@ -71,6 +71,12 @@ RSpec.describe "User creates issue" do expect(preview).to have_css("gl-emoji") expect(textarea).not_to be_visible + + click_button("Write") + fill_in("Description", with: "/confidential") + click_button("Preview") + + expect(form).to have_content('Makes this issue confidential.') end end end diff --git a/spec/features/issues/user_edits_issue_spec.rb b/spec/features/issues/user_edits_issue_spec.rb index 8c906e6a27c..3b440002cb5 100644 --- a/spec/features/issues/user_edits_issue_spec.rb +++ b/spec/features/issues/user_edits_issue_spec.rb @@ -35,6 +35,12 @@ RSpec.describe "Issues > User edits issue", :js do end expect(form).to have_button("Write") + + click_button("Write") + fill_in("Description", with: "/confidential") + click_button("Preview") + + expect(form).to have_content('Makes this issue confidential.') end it 'allows user to select unassigned' do diff --git a/spec/frontend/api_spec.js b/spec/frontend/api_spec.js index 0dceb92db94..9f273ce5ba3 100644 --- a/spec/frontend/api_spec.js +++ b/spec/frontend/api_spec.js @@ -158,33 +158,32 @@ describe('Api', () => { }); describe('group', () => { - it('fetches a group', (done) => { + it('fetches a group', () => { const groupId = '123456'; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/groups/${groupId}`; mock.onGet(expectedUrl).reply(httpStatus.OK, { name: 'test', }); - Api.group(groupId, (response) => { - expect(response.name).toBe('test'); - done(); + return new Promise((resolve) => { + Api.group(groupId, (response) => { + expect(response.name).toBe('test'); + resolve(); + }); }); }); }); describe('groupMembers', () => { - it('fetches group members', (done) => { + it('fetches group members', () => { const groupId = '54321'; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/groups/${groupId}/members`; const expectedData = [{ id: 7 }]; mock.onGet(expectedUrl).reply(httpStatus.OK, expectedData); - Api.groupMembers(groupId) - .then(({ data }) => { - expect(data).toEqual(expectedData); - }) - .then(done) - .catch(done.fail); + return Api.groupMembers(groupId).then(({ data }) => { + expect(data).toEqual(expectedData); + }); }); }); @@ -233,7 +232,7 @@ describe('Api', () => { }); describe('groupMilestones', () => { - it('fetches group milestones', (done) => { + it('fetches group milestones', () => { const groupId = '16'; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/groups/${groupId}/milestones`; const expectedData = [ @@ -253,17 +252,14 @@ describe('Api', () => { ]; mock.onGet(expectedUrl).reply(httpStatus.OK, expectedData); - Api.groupMilestones(groupId) - .then(({ data }) => { - expect(data).toEqual(expectedData); - }) - .then(done) - .catch(done.fail); + return Api.groupMilestones(groupId).then(({ data }) => { + expect(data).toEqual(expectedData); + }); }); }); describe('groups', () => { - it('fetches groups', (done) => { + it('fetches groups', () => { const query = 'dummy query'; const options = { unused: 'option' }; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/groups.json`; @@ -273,16 +269,18 @@ describe('Api', () => { }, ]); - Api.groups(query, options, (response) => { - expect(response.length).toBe(1); - expect(response[0].name).toBe('test'); - done(); + return new Promise((resolve) => { + Api.groups(query, options, (response) => { + expect(response.length).toBe(1); + expect(response[0].name).toBe('test'); + resolve(); + }); }); }); }); describe('groupLabels', () => { - it('fetches group labels', (done) => { + it('fetches group labels', () => { const options = { params: { search: 'foo' } }; const expectedGroup = 'gitlab-org'; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/groups/${expectedGroup}/labels`; @@ -293,18 +291,15 @@ describe('Api', () => { }, ]); - Api.groupLabels(expectedGroup, options) - .then((res) => { - expect(res.length).toBe(1); - expect(res[0].name).toBe('Foo Label'); - }) - .then(done) - .catch(done.fail); + return Api.groupLabels(expectedGroup, options).then((res) => { + expect(res.length).toBe(1); + expect(res[0].name).toBe('Foo Label'); + }); }); }); describe('namespaces', () => { - it('fetches namespaces', (done) => { + it('fetches namespaces', () => { const query = 'dummy query'; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/namespaces.json`; mock.onGet(expectedUrl).reply(httpStatus.OK, [ @@ -313,16 +308,18 @@ describe('Api', () => { }, ]); - Api.namespaces(query, (response) => { - expect(response.length).toBe(1); - expect(response[0].name).toBe('test'); - done(); + return new Promise((resolve) => { + Api.namespaces(query, (response) => { + expect(response.length).toBe(1); + expect(response[0].name).toBe('test'); + resolve(); + }); }); }); }); describe('projects', () => { - it('fetches projects with membership when logged in', (done) => { + it('fetches projects with membership when logged in', () => { const query = 'dummy query'; const options = { unused: 'option' }; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects.json`; @@ -333,14 +330,16 @@ describe('Api', () => { }, ]); - Api.projects(query, options, (response) => { - expect(response.length).toBe(1); - expect(response[0].name).toBe('test'); - done(); + return new Promise((resolve) => { + Api.projects(query, options, (response) => { + expect(response.length).toBe(1); + expect(response[0].name).toBe('test'); + resolve(); + }); }); }); - it('fetches projects without membership when not logged in', (done) => { + it('fetches projects without membership when not logged in', () => { const query = 'dummy query'; const options = { unused: 'option' }; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects.json`; @@ -350,31 +349,30 @@ describe('Api', () => { }, ]); - Api.projects(query, options, (response) => { - expect(response.length).toBe(1); - expect(response[0].name).toBe('test'); - done(); + return new Promise((resolve) => { + Api.projects(query, options, (response) => { + expect(response.length).toBe(1); + expect(response[0].name).toBe('test'); + resolve(); + }); }); }); }); describe('updateProject', () => { - it('update a project with the given payload', (done) => { + it('update a project with the given payload', () => { const projectPath = 'foo'; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/${projectPath}`; mock.onPut(expectedUrl).reply(httpStatus.OK, { foo: 'bar' }); - Api.updateProject(projectPath, { foo: 'bar' }) - .then(({ data }) => { - expect(data.foo).toBe('bar'); - done(); - }) - .catch(done.fail); + return Api.updateProject(projectPath, { foo: 'bar' }).then(({ data }) => { + expect(data.foo).toBe('bar'); + }); }); }); describe('projectUsers', () => { - it('fetches all users of a particular project', (done) => { + it('fetches all users of a particular project', () => { const query = 'dummy query'; const options = { unused: 'option' }; const projectPath = 'gitlab-org%2Fgitlab-ce'; @@ -385,13 +383,10 @@ describe('Api', () => { }, ]); - Api.projectUsers('gitlab-org/gitlab-ce', query, options) - .then((response) => { - expect(response.length).toBe(1); - expect(response[0].name).toBe('test'); - }) - .then(done) - .catch(done.fail); + return Api.projectUsers('gitlab-org/gitlab-ce', query, options).then((response) => { + expect(response.length).toBe(1); + expect(response[0].name).toBe('test'); + }); }); }); @@ -399,38 +394,32 @@ describe('Api', () => { const projectPath = 'abc'; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/${projectPath}/merge_requests`; - it('fetches all merge requests for a project', (done) => { + it('fetches all merge requests for a project', () => { const mockData = [{ source_branch: 'foo' }, { source_branch: 'bar' }]; mock.onGet(expectedUrl).reply(httpStatus.OK, mockData); - Api.projectMergeRequests(projectPath) - .then(({ data }) => { - expect(data.length).toEqual(2); - expect(data[0].source_branch).toBe('foo'); - expect(data[1].source_branch).toBe('bar'); - }) - .then(done) - .catch(done.fail); + return Api.projectMergeRequests(projectPath).then(({ data }) => { + expect(data.length).toEqual(2); + expect(data[0].source_branch).toBe('foo'); + expect(data[1].source_branch).toBe('bar'); + }); }); - it('fetches merge requests filtered with passed params', (done) => { + it('fetches merge requests filtered with passed params', () => { const params = { source_branch: 'bar', }; const mockData = [{ source_branch: 'bar' }]; mock.onGet(expectedUrl, { params }).reply(httpStatus.OK, mockData); - Api.projectMergeRequests(projectPath, params) - .then(({ data }) => { - expect(data.length).toEqual(1); - expect(data[0].source_branch).toBe('bar'); - }) - .then(done) - .catch(done.fail); + return Api.projectMergeRequests(projectPath, params).then(({ data }) => { + expect(data.length).toEqual(1); + expect(data[0].source_branch).toBe('bar'); + }); }); }); describe('projectMergeRequest', () => { - it('fetches a merge request', (done) => { + it('fetches a merge request', () => { const projectPath = 'abc'; const mergeRequestId = '123456'; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/${projectPath}/merge_requests/${mergeRequestId}`; @@ -438,17 +427,14 @@ describe('Api', () => { title: 'test', }); - Api.projectMergeRequest(projectPath, mergeRequestId) - .then(({ data }) => { - expect(data.title).toBe('test'); - }) - .then(done) - .catch(done.fail); + return Api.projectMergeRequest(projectPath, mergeRequestId).then(({ data }) => { + expect(data.title).toBe('test'); + }); }); }); describe('projectMergeRequestChanges', () => { - it('fetches the changes of a merge request', (done) => { + it('fetches the changes of a merge request', () => { const projectPath = 'abc'; const mergeRequestId = '123456'; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/${projectPath}/merge_requests/${mergeRequestId}/changes`; @@ -456,17 +442,14 @@ describe('Api', () => { title: 'test', }); - Api.projectMergeRequestChanges(projectPath, mergeRequestId) - .then(({ data }) => { - expect(data.title).toBe('test'); - }) - .then(done) - .catch(done.fail); + return Api.projectMergeRequestChanges(projectPath, mergeRequestId).then(({ data }) => { + expect(data.title).toBe('test'); + }); }); }); describe('projectMergeRequestVersions', () => { - it('fetches the versions of a merge request', (done) => { + it('fetches the versions of a merge request', () => { const projectPath = 'abc'; const mergeRequestId = '123456'; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/${projectPath}/merge_requests/${mergeRequestId}/versions`; @@ -476,30 +459,24 @@ describe('Api', () => { }, ]); - Api.projectMergeRequestVersions(projectPath, mergeRequestId) - .then(({ data }) => { - expect(data.length).toBe(1); - expect(data[0].id).toBe(123); - }) - .then(done) - .catch(done.fail); + return Api.projectMergeRequestVersions(projectPath, mergeRequestId).then(({ data }) => { + expect(data.length).toBe(1); + expect(data[0].id).toBe(123); + }); }); }); describe('projectRunners', () => { - it('fetches the runners of a project', (done) => { + it('fetches the runners of a project', () => { const projectPath = 7; const params = { scope: 'active' }; const mockData = [{ id: 4 }]; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/${projectPath}/runners`; mock.onGet(expectedUrl, { params }).reply(httpStatus.OK, mockData); - Api.projectRunners(projectPath, { params }) - .then(({ data }) => { - expect(data).toEqual(mockData); - }) - .then(done) - .catch(done.fail); + return Api.projectRunners(projectPath, { params }).then(({ data }) => { + expect(data).toEqual(mockData); + }); }); }); @@ -528,7 +505,7 @@ describe('Api', () => { }); describe('projectMilestones', () => { - it('fetches project milestones', (done) => { + it('fetches project milestones', () => { const projectId = 1; const options = { state: 'active' }; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/1/milestones`; @@ -540,13 +517,10 @@ describe('Api', () => { }, ]); - Api.projectMilestones(projectId, options) - .then(({ data }) => { - expect(data.length).toBe(1); - expect(data[0].title).toBe('milestone1'); - }) - .then(done) - .catch(done.fail); + return Api.projectMilestones(projectId, options).then(({ data }) => { + expect(data.length).toBe(1); + expect(data[0].title).toBe('milestone1'); + }); }); }); @@ -614,7 +588,7 @@ describe('Api', () => { }); describe('newLabel', () => { - it('creates a new project label', (done) => { + it('creates a new project label', () => { const namespace = 'some namespace'; const project = 'some project'; const labelData = { some: 'data' }; @@ -633,13 +607,15 @@ describe('Api', () => { ]; }); - Api.newLabel(namespace, project, labelData, (response) => { - expect(response.name).toBe('test'); - done(); + return new Promise((resolve) => { + Api.newLabel(namespace, project, labelData, (response) => { + expect(response.name).toBe('test'); + resolve(); + }); }); }); - it('creates a new group label', (done) => { + it('creates a new group label', () => { const namespace = 'group/subgroup'; const labelData = { name: 'Foo', color: '#000000' }; const expectedUrl = Api.buildUrl(Api.groupLabelsPath).replace(':namespace_path', namespace); @@ -654,15 +630,17 @@ describe('Api', () => { ]; }); - Api.newLabel(namespace, undefined, labelData, (response) => { - expect(response.name).toBe('Foo'); - done(); + return new Promise((resolve) => { + Api.newLabel(namespace, undefined, labelData, (response) => { + expect(response.name).toBe('Foo'); + resolve(); + }); }); }); }); describe('groupProjects', () => { - it('fetches group projects', (done) => { + it('fetches group projects', () => { const groupId = '123456'; const query = 'dummy query'; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/groups/${groupId}/projects.json`; @@ -672,10 +650,12 @@ describe('Api', () => { }, ]); - Api.groupProjects(groupId, query, {}, (response) => { - expect(response.length).toBe(1); - expect(response[0].name).toBe('test'); - done(); + return new Promise((resolve) => { + Api.groupProjects(groupId, query, {}, (response) => { + expect(response.length).toBe(1); + expect(response[0].name).toBe('test'); + resolve(); + }); }); }); @@ -764,12 +744,14 @@ describe('Api', () => { templateKey, )}`; - it('fetches an issue template', (done) => { + it('fetches an issue template', () => { mock.onGet(expectedUrl).reply(httpStatus.OK, 'test'); - Api.issueTemplate(namespace, project, templateKey, templateType, (error, response) => { - expect(response).toBe('test'); - done(); + return new Promise((resolve) => { + Api.issueTemplate(namespace, project, templateKey, templateType, (_, response) => { + expect(response).toBe('test'); + resolve(); + }); }); }); @@ -777,8 +759,11 @@ describe('Api', () => { it('rejects the Promise', () => { mock.onGet(expectedUrl).replyOnce(httpStatus.INTERNAL_SERVER_ERROR); - Api.issueTemplate(namespace, project, templateKey, templateType, () => { - expect(mock.history.get).toHaveLength(1); + return new Promise((resolve) => { + Api.issueTemplate(namespace, project, templateKey, templateType, () => { + expect(mock.history.get).toHaveLength(1); + resolve(); + }); }); }); }); @@ -790,19 +775,21 @@ describe('Api', () => { const templateType = 'template type'; const expectedUrl = `${dummyUrlRoot}/${namespace}/${project}/templates/${templateType}`; - it('fetches all templates by type', (done) => { + it('fetches all templates by type', () => { const expectedData = [ { key: 'Template1', name: 'Template 1', content: 'This is template 1!' }, ]; mock.onGet(expectedUrl).reply(httpStatus.OK, expectedData); - Api.issueTemplates(namespace, project, templateType, (error, response) => { - expect(response.length).toBe(1); - const { key, name, content } = response[0]; - expect(key).toBe('Template1'); - expect(name).toBe('Template 1'); - expect(content).toBe('This is template 1!'); - done(); + return new Promise((resolve) => { + Api.issueTemplates(namespace, project, templateType, (_, response) => { + expect(response.length).toBe(1); + const { key, name, content } = response[0]; + expect(key).toBe('Template1'); + expect(name).toBe('Template 1'); + expect(content).toBe('This is template 1!'); + resolve(); + }); }); }); @@ -818,34 +805,44 @@ describe('Api', () => { }); describe('projectTemplates', () => { - it('fetches a list of templates', (done) => { + it('fetches a list of templates', () => { const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/gitlab-org%2Fgitlab-ce/templates/licenses`; mock.onGet(expectedUrl).reply(httpStatus.OK, 'test'); - Api.projectTemplates('gitlab-org/gitlab-ce', 'licenses', {}, (response) => { - expect(response).toBe('test'); - done(); + return new Promise((resolve) => { + Api.projectTemplates('gitlab-org/gitlab-ce', 'licenses', {}, (response) => { + expect(response).toBe('test'); + resolve(); + }); }); }); }); describe('projectTemplate', () => { - it('fetches a single template', (done) => { + it('fetches a single template', () => { const data = { unused: 'option' }; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/gitlab-org%2Fgitlab-ce/templates/licenses/test%20license`; mock.onGet(expectedUrl).reply(httpStatus.OK, 'test'); - Api.projectTemplate('gitlab-org/gitlab-ce', 'licenses', 'test license', data, (response) => { - expect(response).toBe('test'); - done(); + return new Promise((resolve) => { + Api.projectTemplate( + 'gitlab-org/gitlab-ce', + 'licenses', + 'test license', + data, + (response) => { + expect(response).toBe('test'); + resolve(); + }, + ); }); }); }); describe('users', () => { - it('fetches users', (done) => { + it('fetches users', () => { const query = 'dummy query'; const options = { unused: 'option' }; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/users.json`; @@ -855,68 +852,56 @@ describe('Api', () => { }, ]); - Api.users(query, options) - .then(({ data }) => { - expect(data.length).toBe(1); - expect(data[0].name).toBe('test'); - }) - .then(done) - .catch(done.fail); + return Api.users(query, options).then(({ data }) => { + expect(data.length).toBe(1); + expect(data[0].name).toBe('test'); + }); }); }); describe('user', () => { - it('fetches single user', (done) => { + it('fetches single user', () => { const userId = '123456'; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/users/${userId}`; mock.onGet(expectedUrl).reply(httpStatus.OK, { name: 'testuser', }); - Api.user(userId) - .then(({ data }) => { - expect(data.name).toBe('testuser'); - }) - .then(done) - .catch(done.fail); + return Api.user(userId).then(({ data }) => { + expect(data.name).toBe('testuser'); + }); }); }); describe('user counts', () => { - it('fetches single user counts', (done) => { + it('fetches single user counts', () => { const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/user_counts`; mock.onGet(expectedUrl).reply(httpStatus.OK, { merge_requests: 4, }); - Api.userCounts() - .then(({ data }) => { - expect(data.merge_requests).toBe(4); - }) - .then(done) - .catch(done.fail); + return Api.userCounts().then(({ data }) => { + expect(data.merge_requests).toBe(4); + }); }); }); describe('user status', () => { - it('fetches single user status', (done) => { + it('fetches single user status', () => { const userId = '123456'; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/users/${userId}/status`; mock.onGet(expectedUrl).reply(httpStatus.OK, { message: 'testmessage', }); - Api.userStatus(userId) - .then(({ data }) => { - expect(data.message).toBe('testmessage'); - }) - .then(done) - .catch(done.fail); + return Api.userStatus(userId).then(({ data }) => { + expect(data.message).toBe('testmessage'); + }); }); }); describe('user projects', () => { - it('fetches all projects that belong to a particular user', (done) => { + it('fetches all projects that belong to a particular user', () => { const query = 'dummy query'; const options = { unused: 'option' }; const userId = '123456'; @@ -927,16 +912,18 @@ describe('Api', () => { }, ]); - Api.userProjects(userId, query, options, (response) => { - expect(response.length).toBe(1); - expect(response[0].name).toBe('test'); - done(); + return new Promise((resolve) => { + Api.userProjects(userId, query, options, (response) => { + expect(response.length).toBe(1); + expect(response[0].name).toBe('test'); + resolve(); + }); }); }); }); describe('commitPipelines', () => { - it('fetches pipelines for a given commit', (done) => { + it('fetches pipelines for a given commit', () => { const projectId = 'example/foobar'; const commitSha = 'abc123def'; const expectedUrl = `${dummyUrlRoot}/${projectId}/commit/${commitSha}/pipelines`; @@ -946,13 +933,10 @@ describe('Api', () => { }, ]); - Api.commitPipelines(projectId, commitSha) - .then(({ data }) => { - expect(data.length).toBe(1); - expect(data[0].name).toBe('test'); - }) - .then(done) - .catch(done.fail); + return Api.commitPipelines(projectId, commitSha).then(({ data }) => { + expect(data.length).toBe(1); + expect(data[0].name).toBe('test'); + }); }); }); @@ -977,7 +961,7 @@ describe('Api', () => { }); describe('createBranch', () => { - it('creates new branch', (done) => { + it('creates new branch', () => { const ref = 'main'; const branch = 'new-branch-name'; const dummyProjectPath = 'gitlab-org/gitlab-ce'; @@ -991,18 +975,15 @@ describe('Api', () => { name: branch, }); - Api.createBranch(dummyProjectPath, { ref, branch }) - .then(({ data }) => { - expect(data.name).toBe(branch); - expect(axios.post).toHaveBeenCalledWith(expectedUrl, { ref, branch }); - }) - .then(done) - .catch(done.fail); + return Api.createBranch(dummyProjectPath, { ref, branch }).then(({ data }) => { + expect(data.name).toBe(branch); + expect(axios.post).toHaveBeenCalledWith(expectedUrl, { ref, branch }); + }); }); }); describe('projectForks', () => { - it('gets forked projects', (done) => { + it('gets forked projects', () => { const dummyProjectPath = 'gitlab-org/gitlab-ce'; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/${encodeURIComponent( dummyProjectPath, @@ -1012,20 +993,17 @@ describe('Api', () => { mock.onGet(expectedUrl).replyOnce(httpStatus.OK, ['fork']); - Api.projectForks(dummyProjectPath, { visibility: 'private' }) - .then(({ data }) => { - expect(data).toEqual(['fork']); - expect(axios.get).toHaveBeenCalledWith(expectedUrl, { - params: { visibility: 'private' }, - }); - }) - .then(done) - .catch(done.fail); + return Api.projectForks(dummyProjectPath, { visibility: 'private' }).then(({ data }) => { + expect(data).toEqual(['fork']); + expect(axios.get).toHaveBeenCalledWith(expectedUrl, { + params: { visibility: 'private' }, + }); + }); }); }); describe('createContextCommits', () => { - it('creates a new context commit', (done) => { + it('creates a new context commit', () => { const projectPath = 'abc'; const mergeRequestId = '123456'; const commitsData = ['abcdefg']; @@ -1044,17 +1022,16 @@ describe('Api', () => { }, ]); - Api.createContextCommits(projectPath, mergeRequestId, expectedData) - .then(({ data }) => { + return Api.createContextCommits(projectPath, mergeRequestId, expectedData).then( + ({ data }) => { expect(data[0].title).toBe('Dummy commit'); - }) - .then(done) - .catch(done.fail); + }, + ); }); }); describe('allContextCommits', () => { - it('gets all context commits', (done) => { + it('gets all context commits', () => { const projectPath = 'abc'; const mergeRequestId = '123456'; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/${projectPath}/merge_requests/${mergeRequestId}/context_commits`; @@ -1065,17 +1042,14 @@ describe('Api', () => { .onGet(expectedUrl) .replyOnce(200, [{ id: 'abcdef', short_id: 'abcdefghi', title: 'Dummy commit title' }]); - Api.allContextCommits(projectPath, mergeRequestId) - .then(({ data }) => { - expect(data[0].title).toBe('Dummy commit title'); - }) - .then(done) - .catch(done.fail); + return Api.allContextCommits(projectPath, mergeRequestId).then(({ data }) => { + expect(data[0].title).toBe('Dummy commit title'); + }); }); }); describe('removeContextCommits', () => { - it('removes context commits', (done) => { + it('removes context commits', () => { const projectPath = 'abc'; const mergeRequestId = '123456'; const commitsData = ['abcdefg']; @@ -1088,12 +1062,9 @@ describe('Api', () => { mock.onDelete(expectedUrl).replyOnce(204); - Api.removeContextCommits(projectPath, mergeRequestId, expectedData) - .then(() => { - expect(axios.delete).toHaveBeenCalledWith(expectedUrl, { data: expectedData }); - }) - .then(done) - .catch(done.fail); + return Api.removeContextCommits(projectPath, mergeRequestId, expectedData).then(() => { + expect(axios.delete).toHaveBeenCalledWith(expectedUrl, { data: expectedData }); + }); }); }); @@ -1336,41 +1307,37 @@ describe('Api', () => { }); describe('updateIssue', () => { - it('update an issue with the given payload', (done) => { + it('update an issue with the given payload', () => { const projectId = 8; const issue = 1; const expectedArray = [1, 2, 3]; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/${projectId}/issues/${issue}`; mock.onPut(expectedUrl).reply(httpStatus.OK, { assigneeIds: expectedArray }); - Api.updateIssue(projectId, issue, { assigneeIds: expectedArray }) - .then(({ data }) => { - expect(data.assigneeIds).toEqual(expectedArray); - done(); - }) - .catch(done.fail); + return Api.updateIssue(projectId, issue, { assigneeIds: expectedArray }).then(({ data }) => { + expect(data.assigneeIds).toEqual(expectedArray); + }); }); }); describe('updateMergeRequest', () => { - it('update an issue with the given payload', (done) => { + it('update an issue with the given payload', () => { const projectId = 8; const mergeRequest = 1; const expectedArray = [1, 2, 3]; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/${projectId}/merge_requests/${mergeRequest}`; mock.onPut(expectedUrl).reply(httpStatus.OK, { assigneeIds: expectedArray }); - Api.updateMergeRequest(projectId, mergeRequest, { assigneeIds: expectedArray }) - .then(({ data }) => { + return Api.updateMergeRequest(projectId, mergeRequest, { assigneeIds: expectedArray }).then( + ({ data }) => { expect(data.assigneeIds).toEqual(expectedArray); - done(); - }) - .catch(done.fail); + }, + ); }); }); describe('tags', () => { - it('fetches all tags of a particular project', (done) => { + it('fetches all tags of a particular project', () => { const query = 'dummy query'; const options = { unused: 'option' }; const projectId = 8; @@ -1381,13 +1348,10 @@ describe('Api', () => { }, ]); - Api.tags(projectId, query, options) - .then(({ data }) => { - expect(data.length).toBe(1); - expect(data[0].name).toBe('test'); - }) - .then(done) - .catch(done.fail); + return Api.tags(projectId, query, options).then(({ data }) => { + expect(data.length).toBe(1); + expect(data[0].name).toBe('test'); + }); }); }); diff --git a/spec/frontend/boards/components/issuable_title_spec.js b/spec/frontend/boards/components/issuable_title_spec.js deleted file mode 100644 index 4b7f491b998..00000000000 --- a/spec/frontend/boards/components/issuable_title_spec.js +++ /dev/null @@ -1,33 +0,0 @@ -import { shallowMount } from '@vue/test-utils'; -import IssuableTitle from '~/boards/components/issuable_title.vue'; - -describe('IssuableTitle', () => { - let wrapper; - const defaultProps = { - title: 'One', - refPath: 'path', - }; - const createComponent = () => { - wrapper = shallowMount(IssuableTitle, { - propsData: { ...defaultProps }, - }); - }; - const findIssueContent = () => wrapper.find('[data-testid="issue-title"]'); - - beforeEach(() => { - createComponent(); - }); - - afterEach(() => { - wrapper.destroy(); - wrapper = null; - }); - - it('renders a title of an issue in the sidebar', () => { - expect(findIssueContent().text()).toContain('One'); - }); - - it('renders a referencePath of an issue in the sidebar', () => { - expect(findIssueContent().text()).toContain('path'); - }); -}); diff --git a/spec/frontend/diffs/components/commit_item_spec.js b/spec/frontend/diffs/components/commit_item_spec.js index b3d0781fde5..fbcc5ecefb3 100644 --- a/spec/frontend/diffs/components/commit_item_spec.js +++ b/spec/frontend/diffs/components/commit_item_spec.js @@ -80,7 +80,7 @@ describe('diffs/components/commit_item', () => { const imgElement = avatarElement.find('img'); expect(avatarElement.attributes('href')).toBe(commit.author.web_url); - expect(imgElement.classes()).toContain('s40'); + expect(imgElement.classes()).toContain('s32'); expect(imgElement.attributes('alt')).toBe(commit.author.name); expect(imgElement.attributes('src')).toBe(commit.author.avatar_url); }); diff --git a/spec/frontend/integrations/edit/components/jira_issues_fields_spec.js b/spec/frontend/integrations/edit/components/jira_issues_fields_spec.js index 33fd08a5959..94e370a485f 100644 --- a/spec/frontend/integrations/edit/components/jira_issues_fields_spec.js +++ b/spec/frontend/integrations/edit/components/jira_issues_fields_spec.js @@ -10,7 +10,6 @@ describe('JiraIssuesFields', () => { let wrapper; const defaultProps = { - editProjectPath: '/edit', showJiraIssuesIntegration: true, showJiraVulnerabilitiesIntegration: true, upgradePlanPath: 'https://gitlab.com', @@ -46,7 +45,6 @@ describe('JiraIssuesFields', () => { const findPremiumUpgradeCTA = () => wrapper.findByTestId('premium-upgrade-cta'); const findUltimateUpgradeCTA = () => wrapper.findByTestId('ultimate-upgrade-cta'); const findJiraForVulnerabilities = () => wrapper.findByTestId('jira-for-vulnerabilities'); - const findConflictWarning = () => wrapper.findByTestId('conflict-warning-text'); const setEnableCheckbox = async (isEnabled = true) => findEnableCheckbox().vm.$emit('input', isEnabled); @@ -75,10 +73,9 @@ describe('JiraIssuesFields', () => { }); if (showJiraIssuesIntegration) { - it('renders checkbox and input field', () => { + it('renders enable checkbox', () => { expect(findEnableCheckbox().exists()).toBe(true); expect(findEnableCheckboxDisabled()).toBeUndefined(); - expect(findProjectKey().exists()).toBe(true); }); it('does not render the Premium CTA', () => { @@ -98,9 +95,8 @@ describe('JiraIssuesFields', () => { }); } } else { - it('does not render checkbox and input field', () => { + it('does not render enable checkbox', () => { expect(findEnableCheckbox().exists()).toBe(false); - expect(findProjectKey().exists()).toBe(false); }); it('renders the Premium CTA', () => { @@ -122,12 +118,8 @@ describe('JiraIssuesFields', () => { createComponent({ props: { initialProjectKey: '' } }); }); - it('renders disabled project_key input', () => { - const projectKey = findProjectKey(); - - expect(projectKey.exists()).toBe(true); - expect(projectKey.attributes('disabled')).toBe('disabled'); - expect(projectKey.attributes('required')).toBeUndefined(); + it('does not render project_key input', () => { + expect(findProjectKey().exists()).toBe(false); }); // As per https://vuejs.org/v2/guide/forms.html#Checkbox-1, @@ -137,45 +129,23 @@ describe('JiraIssuesFields', () => { }); describe('when isInheriting = true', () => { - it('disables checkbox and sets input as readonly', () => { + it('disables checkbox', () => { createComponent({ isInheriting: true }); expect(findEnableCheckboxDisabled()).toBe('disabled'); - expect(findProjectKey().attributes('readonly')).toBe('readonly'); }); }); describe('on enable issues', () => { - it('enables project_key input as required', async () => { + it('renders project_key input as required', async () => { await setEnableCheckbox(true); - expect(findProjectKey().attributes('disabled')).toBeUndefined(); + expect(findProjectKey().exists()).toBe(true); expect(findProjectKey().attributes('required')).toBe('required'); }); }); }); - it('contains link to editProjectPath', () => { - createComponent(); - - expect(wrapper.find(`a[href="${defaultProps.editProjectPath}"]`).exists()).toBe(true); - }); - - describe('GitLab issues warning', () => { - it.each` - gitlabIssuesEnabled | scenario - ${true} | ${'displays conflict warning'} - ${false} | ${'does not display conflict warning'} - `( - '$scenario when `gitlabIssuesEnabled` is `$gitlabIssuesEnabled`', - ({ gitlabIssuesEnabled }) => { - createComponent({ props: { gitlabIssuesEnabled } }); - - expect(findConflictWarning().exists()).toBe(gitlabIssuesEnabled); - }, - ); - }); - describe('Vulnerabilities creation', () => { beforeEach(() => { createComponent(); diff --git a/spec/frontend/vue_shared/components/markdown/field_spec.js b/spec/frontend/vue_shared/components/markdown/field_spec.js index b5daa389fc6..cf98630c654 100644 --- a/spec/frontend/vue_shared/components/markdown/field_spec.js +++ b/spec/frontend/vue_shared/components/markdown/field_spec.js @@ -101,6 +101,21 @@ describe('Markdown field component', () => { expect(subject.find('.zen-backdrop textarea').element).not.toBeNull(); }); + it('renders referenced commands on markdown preview', async () => { + axiosMock + .onPost(markdownPreviewPath) + .reply(200, { references: { users: [], commands: 'test command' } }); + + previewLink = getPreviewLink(); + previewLink.vm.$emit('click', { target: {} }); + + await axios.waitFor(markdownPreviewPath); + const referencedCommands = subject.find('[data-testid="referenced-commands"]'); + + expect(referencedCommands.exists()).toBe(true); + expect(referencedCommands.text()).toContain('test command'); + }); + describe('markdown preview', () => { beforeEach(() => { axiosMock.onPost(markdownPreviewPath).reply(200, { body: previewHTML }); diff --git a/spec/helpers/issuables_helper_spec.rb b/spec/helpers/issuables_helper_spec.rb index ed50a4daae8..ee5b0145d13 100644 --- a/spec/helpers/issuables_helper_spec.rb +++ b/spec/helpers/issuables_helper_spec.rb @@ -288,7 +288,7 @@ RSpec.describe IssuablesHelper do canUpdate: true, canDestroy: true, issuableRef: "##{issue.iid}", - markdownPreviewPath: "/#{@project.full_path}/preview_markdown", + markdownPreviewPath: "/#{@project.full_path}/preview_markdown?target_id=#{issue.iid}&target_type=Issue", markdownDocsPath: '/help/user/markdown', lockVersion: issue.lock_version, projectPath: @project.path, diff --git a/spec/services/bulk_imports/relation_export_service_spec.rb b/spec/services/bulk_imports/relation_export_service_spec.rb index 27a6ca60515..f0f85217d2e 100644 --- a/spec/services/bulk_imports/relation_export_service_spec.rb +++ b/spec/services/bulk_imports/relation_export_service_spec.rb @@ -88,6 +88,18 @@ RSpec.describe BulkImports::RelationExportService do subject.execute end + + context 'when export is recently finished' do + it 'returns recently finished export instead of re-exporting' do + updated_at = 5.seconds.ago + export.update!(status: 1, updated_at: updated_at) + + expect { subject.execute }.not_to change { export.updated_at } + + expect(export.status).to eq(1) + expect(export.updated_at).to eq(updated_at) + end + end end context 'when exception occurs during export' do diff --git a/spec/support/shared_examples/features/runners_shared_examples.rb b/spec/support/shared_examples/features/runners_shared_examples.rb new file mode 100644 index 00000000000..133f3ff5fb6 --- /dev/null +++ b/spec/support/shared_examples/features/runners_shared_examples.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +RSpec.shared_examples 'shows and resets runner registration token' do + include Spec::Support::Helpers::ModalHelpers + + before do + click_on dropdown_text + end + + describe 'shows registration instructions' do + before do + click_on 'Show runner installation and registration instructions' + + wait_for_requests + end + + it 'opens runner installation modal', :aggregate_failures do + within_modal do + expect(page).to have_text "Install a runner" + expect(page).to have_text "Environment" + expect(page).to have_text "Architecture" + expect(page).to have_text "Download and install binary" + end + end + + it 'dismisses runner installation modal' do + within_modal do + click_button('Close', match: :first) + end + + expect(page).not_to have_text "Install a runner" + end + end + + it 'has a registration token' do + click_on 'Click to reveal' + expect(page.find('[data-testid="token-value"]')).to have_content(registration_token) + end + + describe 'reset registration token' do + let!(:old_registration_token) { find('[data-testid="token-value"]').text } + + before do + click_on 'Reset registration token' + + within_modal do + click_button('Reset token', match: :first) + end + + wait_for_requests + end + + it 'changes registration token' do + expect(find('.gl-toast')).to have_content('New registration token generated!') + + click_on dropdown_text + click_on 'Click to reveal' + + expect(old_registration_token).not_to eq registration_token + end + end +end |