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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-02-17 15:11:17 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-02-17 15:11:17 +0300
commit4f8983ade80c0d71d4c8e6cc0d686c9cecf5e7d4 (patch)
tree3c51e09d9315acb8930c3c5383fb6384a3a841aa
parente191aabc8fd068233ac7b21e6f1299e2c371faba (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.gitlab/CODEOWNERS4
-rw-r--r--.gitlab/ci/build-images.gitlab-ci.yml27
-rw-r--r--.gitlab/ci/qa.gitlab-ci.yml17
-rw-r--r--.gitlab/ci/rules.gitlab-ci.yml32
-rw-r--r--.gitlab/ci/test-on-gdk/main.gitlab-ci.yml81
-rw-r--r--.rubocop_todo/rspec/missing_feature_category.yml84
-rw-r--r--GITALY_SERVER_VERSION2
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.checksum6
-rw-r--r--Gemfile.lock10
-rw-r--r--app/assets/javascripts/boards/components/boards_selector.vue14
-rw-r--r--app/assets/javascripts/diffs/components/diff_row.vue108
-rw-r--r--app/assets/javascripts/diffs/components/diff_row_utils.js54
-rw-r--r--app/assets/javascripts/diffs/components/diff_view.vue21
-rw-r--r--app/assets/javascripts/gpg_badges.js2
-rw-r--r--app/assets/javascripts/issuable/components/issuable_by_email.vue5
-rw-r--r--app/assets/javascripts/issues/show/components/fields/type.vue3
-rw-r--r--app/assets/javascripts/notes/components/note_actions.vue5
-rw-r--r--app/assets/javascripts/notes/stores/actions.js6
-rw-r--r--app/assets/javascripts/related_issues/components/related_issues_list.vue3
-rw-r--r--app/assets/javascripts/related_issues/index.js3
-rw-r--r--app/assets/javascripts/repository/components/preview/index.vue9
-rw-r--r--app/assets/javascripts/sidebar/components/assignees/assignee_avatar.vue4
-rw-r--r--app/assets/javascripts/sidebar/components/assignees/assignee_avatar_link.vue4
-rw-r--r--app/assets/javascripts/sidebar/components/assignees/assignees.vue3
-rw-r--r--app/assets/javascripts/sidebar/components/assignees/collapsed_assignee.vue3
-rw-r--r--app/assets/javascripts/sidebar/components/assignees/collapsed_assignee_list.vue3
-rw-r--r--app/assets/javascripts/sidebar/components/assignees/issuable_assignees.vue3
-rw-r--r--app/assets/javascripts/sidebar/components/assignees/sidebar_assignees.vue5
-rw-r--r--app/assets/javascripts/sidebar/components/assignees/uncollapsed_assignee_list.vue4
-rw-r--r--app/assets/javascripts/sidebar/components/lock/issuable_lock_form.vue4
-rw-r--r--app/assets/javascripts/sidebar/components/reviewers/reviewer_avatar_link.vue3
-rw-r--r--app/assets/javascripts/sidebar/components/reviewers/reviewers.vue3
-rw-r--r--app/assets/javascripts/sidebar/components/reviewers/sidebar_reviewers.vue3
-rw-r--r--app/assets/javascripts/sidebar/components/reviewers/uncollapsed_reviewer_list.vue3
-rw-r--r--app/assets/javascripts/sidebar/components/time_tracking/create_timelog_form.vue3
-rw-r--r--app/assets/javascripts/sidebar/components/time_tracking/report.vue3
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/widget/widget.vue4
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/extensions/issues.js7
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/extensions/terraform/index.js2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/extensions/test_report/index.js2
-rw-r--r--app/assets/stylesheets/framework/diffs.scss32
-rw-r--r--app/assets/stylesheets/highlight/common.scss11
-rw-r--r--app/assets/stylesheets/highlight/themes/dark.scss29
-rw-r--r--app/assets/stylesheets/highlight/themes/monokai.scss27
-rw-r--r--app/assets/stylesheets/highlight/themes/none.scss27
-rw-r--r--app/assets/stylesheets/highlight/themes/solarized-dark.scss27
-rw-r--r--app/assets/stylesheets/highlight/themes/solarized-light.scss16
-rw-r--r--app/assets/stylesheets/highlight/themes/white.scss2
-rw-r--r--app/assets/stylesheets/highlight/white_base.scss24
-rw-r--r--app/assets/stylesheets/pages/commits.scss23
-rw-r--r--app/assets/stylesheets/pages/notes.scss1
-rw-r--r--app/assets/stylesheets/startup/startup-dark.scss2
-rw-r--r--app/controllers/projects/environments_controller.rb3
-rw-r--r--app/graphql/types/project_type.rb18
-rw-r--r--app/helpers/commits_helper.rb4
-rw-r--r--app/helpers/issuables_helper.rb2
-rw-r--r--app/models/concerns/noteable.rb4
-rw-r--r--app/models/note.rb3
-rw-r--r--app/views/projects/commit/_ajax_signature.html.haml2
-rw-r--r--app/views/projects/commit/_multiple_signatures_signature_badge.html.haml2
-rw-r--r--app/views/projects/commit/_other_user_signature_badge.html.haml2
-rw-r--r--app/views/projects/commit/_revoked_key_signature_badge.html.haml2
-rw-r--r--app/views/projects/commit/_same_user_different_email_signature_badge.html.haml2
-rw-r--r--app/views/projects/commit/_signature_badge.html.haml10
-rw-r--r--app/views/projects/commit/_unverified_signature_badge.html.haml2
-rw-r--r--app/views/projects/commit/_verified_signature_badge.html.haml2
-rw-r--r--app/views/projects/commit/x509/_unverified_signature_badge.html.haml2
-rw-r--r--app/views/projects/commit/x509/_verified_signature_badge.html.haml2
-rw-r--r--app/views/shared/issuable/_sidebar.html.haml2
-rw-r--r--config/feature_flags/development/stop_stale_environments.yml8
-rw-r--r--db/migrate/20230131004948_initialize_conversion_of_notes_id_to_bigint.rb16
-rw-r--r--db/post_migrate/20230131005411_backfill_notes_id_for_bigint_conversion.rb16
-rw-r--r--db/post_migrate/20230214122717_fix_partition_ids_for_ci_job_variables.rb23
-rw-r--r--db/post_migrate/20230216054348_prepare_async_foreign_key_validation_for_ci_job_artifacts.rb15
-rw-r--r--db/schema_migrations/202301310049481
-rw-r--r--db/schema_migrations/202301310054111
-rw-r--r--db/schema_migrations/202302141227171
-rw-r--r--db/schema_migrations/202302160543481
-rw-r--r--db/structure.sql14
-rw-r--r--doc/api/graphql/reference/index.md20
-rw-r--r--doc/integration/partner_marketplace.md64
-rw-r--r--doc/operations/img/copy-group-id.pngbin0 -> 112686 bytes
-rw-r--r--doc/operations/img/create-gitlab-application.pngbin0 -> 521206 bytes
-rw-r--r--doc/operations/img/listing_groups.pngbin0 -> 40621 bytes
-rw-r--r--doc/operations/quickstart-guide.md229
-rw-r--r--locale/gitlab.pot6
-rw-r--r--qa/gdk/Dockerfile50
-rw-r--r--qa/gdk/gdk.yml26
-rwxr-xr-xqa/gdk/launch40
-rw-r--r--qa/qa.rb5
-rw-r--r--qa/qa/page/main/login.rb46
-rw-r--r--qa/qa/specs/knapsack_runner.rb2
-rw-r--r--qa/qa/specs/spec_helper.rb1
-rw-r--r--qa/tasks/ci.rake5
-rw-r--r--qa/tasks/knapsack.rake2
-rw-r--r--spec/controllers/admin/clusters_controller_spec.rb2
-rw-r--r--spec/controllers/admin/instance_review_controller_spec.rb2
-rw-r--r--spec/controllers/autocomplete_controller_spec.rb10
-rw-r--r--spec/controllers/dashboard/projects_controller_spec.rb2
-rw-r--r--spec/controllers/explore/projects_controller_spec.rb2
-rw-r--r--spec/controllers/groups/children_controller_spec.rb2
-rw-r--r--spec/controllers/groups/clusters_controller_spec.rb2
-rw-r--r--spec/controllers/groups/labels_controller_spec.rb2
-rw-r--r--spec/controllers/projects/branches_controller_spec.rb2
-rw-r--r--spec/controllers/projects/clusters_controller_spec.rb2
-rw-r--r--spec/controllers/projects/commits_controller_spec.rb2
-rw-r--r--spec/controllers/projects/environments_controller_spec.rb26
-rw-r--r--spec/controllers/projects/forks_controller_spec.rb2
-rw-r--r--spec/controllers/projects/issues_controller_spec.rb2
-rw-r--r--spec/controllers/projects/labels_controller_spec.rb2
-rw-r--r--spec/controllers/projects/merge_requests/creations_controller_spec.rb2
-rw-r--r--spec/controllers/projects/merge_requests/diffs_controller_spec.rb2
-rw-r--r--spec/controllers/projects/settings/ci_cd_controller_spec.rb2
-rw-r--r--spec/controllers/projects_controller_spec.rb2
-rw-r--r--spec/features/profiles/keys_spec.rb4
-rw-r--r--spec/features/projects/blobs/blob_show_spec.rb8
-rw-r--r--spec/features/projects/tree/tree_show_spec.rb12
-rw-r--r--spec/features/projects_spec.rb8
-rw-r--r--spec/features/signed_commits_spec.rb26
-rw-r--r--spec/finders/releases/group_releases_finder_spec.rb2
-rw-r--r--spec/frontend/boards/board_card_inner_spec.js11
-rw-r--r--spec/frontend/diffs/components/commit_item_spec.js6
-rw-r--r--spec/frontend/diffs/components/diff_row_utils_spec.js525
-rw-r--r--spec/frontend/gpg_badges_spec.js8
-rw-r--r--spec/frontend/repository/components/last_commit_spec.js8
-rw-r--r--spec/frontend/repository/components/preview/index_spec.js24
-rw-r--r--spec/frontend/vue_merge_request_widget/components/states/mr_widget_commits_header_spec.js23
-rw-r--r--spec/frontend/vue_merge_request_widget/components/widget/widget_spec.js2
-rw-r--r--spec/frontend/vue_merge_request_widget/test_extensions.js2
-rw-r--r--spec/frontend/vue_shared/components/dropdown_keyboard_navigation_spec.js19
-rw-r--r--spec/graphql/types/project_type_spec.rb53
-rw-r--r--spec/helpers/merge_requests_helper_spec.rb2
-rw-r--r--spec/initializers/load_balancing_spec.rb2
-rw-r--r--spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/trace/archive_spec.rb2
-rw-r--r--spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb2
-rw-r--r--spec/lib/gitlab/database/load_balancing_spec.rb2
-rw-r--r--spec/lib/gitlab/database/migrations/timeout_helpers_spec.rb2
-rw-r--r--spec/lib/gitlab/database/reflection_spec.rb2
-rw-r--r--spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb2
-rw-r--r--spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb3
-rw-r--r--spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb3
-rw-r--r--spec/lib/gitlab/database/transaction/observer_spec.rb2
-rw-r--r--spec/lib/gitlab/database/with_lock_retries_outside_transaction_spec.rb2
-rw-r--r--spec/lib/gitlab/database/with_lock_retries_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/subscribers/load_balancing_spec.rb2
-rw-r--r--spec/migrations/20221122132812_schedule_prune_stale_project_export_jobs_spec.rb2
-rw-r--r--spec/migrations/20221205151917_schedule_backfill_environment_tier_spec.rb2
-rw-r--r--spec/migrations/20230214122717_fix_partition_ids_for_ci_job_variables_spec.rb51
-rw-r--r--spec/models/concerns/pg_full_text_searchable_spec.rb2
-rw-r--r--spec/models/container_repository_spec.rb2
-rw-r--r--spec/models/member_spec.rb2
-rw-r--r--spec/models/merge_request/cleanup_schedule_spec.rb2
-rw-r--r--spec/services/groups/destroy_service_spec.rb2
-rw-r--r--spec/services/issues/move_service_spec.rb2
-rw-r--r--spec/services/merge_requests/close_service_spec.rb2
-rw-r--r--spec/services/merge_requests/create_from_issue_service_spec.rb2
-rw-r--r--spec/services/merge_requests/create_service_spec.rb2
-rw-r--r--spec/services/merge_requests/link_lfs_objects_service_spec.rb2
-rw-r--r--spec/services/merge_requests/pushed_branches_service_spec.rb2
-rw-r--r--spec/services/merge_requests/rebase_service_spec.rb2
-rw-r--r--spec/services/merge_requests/retarget_chain_service_spec.rb2
-rw-r--r--spec/services/pages/migrate_from_legacy_storage_service_spec.rb2
-rw-r--r--spec/services/projects/destroy_service_spec.rb2
-rw-r--r--spec/support/models/ci/partitioning_testing/schema_helpers.rb19
-rw-r--r--spec/views/projects/commit/show.html.haml_spec.rb2
-rw-r--r--spec/views/projects/commits/_commit.html.haml_spec.rb2
-rw-r--r--spec/views/projects/merge_requests/_commits.html.haml_spec.rb2
-rw-r--r--spec/views/projects/merge_requests/creations/_new_submit.html.haml_spec.rb2
-rw-r--r--spec/workers/ci/external_pull_requests/create_pipeline_worker_spec.rb2
172 files changed, 1635 insertions, 765 deletions
diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS
index 588a46df00c..02258c366c5 100644
--- a/.gitlab/CODEOWNERS
+++ b/.gitlab/CODEOWNERS
@@ -1419,3 +1419,7 @@ ee/lib/ee/api/entities/project.rb @gitlab-org/manage/manage-workspace/backend-ap
/ee/app/assets/javascripts/usage_quotas/components/ @fulfillment-group/utilization-group/fe
/ee/app/assets/javascripts/usage_quotas/seats/ @fulfillment-group/utilization-group/fe
/ee/app/assets/javascripts/usage_quotas/storage/ @fulfillment-group/utilization-group/fe
+
+[Manage::Foundations]
+/lib/sidebars/ @gitlab/ @gitlab-org/manage/foundations/engineering
+/ee/lib/sidebars/ @gitlab-org/manage/foundations/engineering \ No newline at end of file
diff --git a/.gitlab/ci/build-images.gitlab-ci.yml b/.gitlab/ci/build-images.gitlab-ci.yml
index 9177913de18..4ee15ccb311 100644
--- a/.gitlab/ci/build-images.gitlab-ci.yml
+++ b/.gitlab/ci/build-images.gitlab-ci.yml
@@ -29,6 +29,33 @@ build-qa-image as-if-foss:
- .as-if-foss
- .build-images:rules:build-qa-image-as-if-foss
+# Prepares an image with GDK configured based on code in master. This saves some time in MRs because some installation
+# and complilation will have already been performed.
+build-qa-on-gdk-master-image:
+ extends:
+ - .base-image-build-buildx
+ - .build-images:rules:build-qa-on-gdk-master-image
+ tags:
+ - e2e
+ stage: build-images
+ needs: []
+ variables:
+ QA_GDK_IMAGE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-qa-gdk"
+ before_script:
+ - !reference [.use-buildx, before_script]
+ - sysctl -n -w fs.inotify.max_user_watches=524288
+ script:
+ - |
+ docker buildx build \
+ --cache-to=type=inline \
+ --cache-from ${QA_GDK_IMAGE}:master \
+ --platform=${ARCH:-amd64} \
+ --add-host gdk.test:127.0.0.1 \
+ --tag ${QA_GDK_IMAGE}:master \
+ --file="qa/gdk/Dockerfile" \
+ --push \
+ ${CI_PROJECT_DIR}
+
build-assets-image:
extends:
- .base-image-build
diff --git a/.gitlab/ci/qa.gitlab-ci.yml b/.gitlab/ci/qa.gitlab-ci.yml
index 0ca20e95c47..a72e6fc0137 100644
--- a/.gitlab/ci/qa.gitlab-ci.yml
+++ b/.gitlab/ci/qa.gitlab-ci.yml
@@ -97,3 +97,20 @@ e2e:package-and-test:
include:
- artifact: package-and-test-pipeline.yml
job: e2e-test-pipeline-generate
+
+e2e:test-on-gdk:
+ extends:
+ - .qa:rules:e2e:test-on-gdk
+ stage: qa
+ needs:
+ # In scheduled master pipelines we wait for the image to be built.
+ # In MRs we assume the last scheduled master pipeline built the image already.
+ - job: build-qa-on-gdk-master-image
+ optional: true
+ allow_failure: true
+ trigger:
+ strategy: depend
+ forward:
+ yaml_variables: true
+ pipeline_variables: true
+ include: .gitlab/ci/test-on-gdk/main.gitlab-ci.yml
diff --git a/.gitlab/ci/rules.gitlab-ci.yml b/.gitlab/ci/rules.gitlab-ci.yml
index 53adc2936f3..d1e29084a5a 100644
--- a/.gitlab/ci/rules.gitlab-ci.yml
+++ b/.gitlab/ci/rules.gitlab-ci.yml
@@ -742,6 +742,19 @@
rules:
- !reference [".build-images:rules:build-qa-image-merge-requests", "rules"]
+# We want to rebuild the master image when the full e2e test pipeline runs. Currently this happens on a 2 hour schedule.
+.build-images:rules:build-qa-on-gdk-master-image:
+ rules:
+ - if: '$QA_RUN_TESTS_ON_GDK !~ /true|yes|1/i'
+ when: never
+ - <<: *if-not-canonical-namespace
+ when: never
+ - <<: *if-not-ee
+ when: never
+ - <<: *if-dot-com-gitlab-org-schedule
+ variables:
+ ARCH: amd64,arm64
+
.build-images:rules:build-assets-image:
rules:
- <<: *if-not-canonical-namespace
@@ -1144,7 +1157,7 @@
allow_failure: true
- <<: *if-ruby2-branch
-.qa:rules:package-and-test:
+.qa:rules:package-and-test-mrs:
rules:
- <<: *if-not-canonical-namespace
when: never
@@ -1184,6 +1197,13 @@
changes: *code-patterns
when: manual
allow_failure: true
+ - <<: *if-force-ci
+ when: manual
+ allow_failure: true
+
+.qa:rules:package-and-test:
+ rules:
+ - !reference [".qa:rules:package-and-test-mrs", rules]
- <<: *if-dot-com-gitlab-org-schedule
allow_failure: true
variables:
@@ -1192,9 +1212,12 @@
KNAPSACK_GENERATE_REPORT: "true"
QA_SAVE_TEST_METRICS: "true"
QA_EXPORT_TEST_METRICS: "false" # on main runs, metrics are exported to separate bucket via rake task for better consistency
- - <<: *if-force-ci
- when: manual
- allow_failure: true
+
+.qa:rules:e2e:test-on-gdk:
+ rules:
+ - if: '$QA_RUN_TESTS_ON_GDK !~ /true|yes|1/i'
+ when: never
+ - !reference [".qa:rules:package-and-test", rules]
###############
# Rails rules #
@@ -2218,6 +2241,7 @@
- <<: *if-not-ee
when: never
- <<: *if-dot-com-ee-schedule-default-branch-maintenance
+ when: always
- <<: *if-default-branch-refs
changes:
- ".gitlab/ci/test-metadata.gitlab-ci.yml"
diff --git a/.gitlab/ci/test-on-gdk/main.gitlab-ci.yml b/.gitlab/ci/test-on-gdk/main.gitlab-ci.yml
new file mode 100644
index 00000000000..a04d81fb342
--- /dev/null
+++ b/.gitlab/ci/test-on-gdk/main.gitlab-ci.yml
@@ -0,0 +1,81 @@
+default:
+ interruptible: true
+
+include:
+ - local: .gitlab/ci/package-and-test/rules.gitlab-ci.yml
+
+dont-interrupt-me:
+ extends: .rules:dont-interrupt
+ stage: test
+ interruptible: false
+ script:
+ - echo "This jobs makes sure this pipeline won't be interrupted! See https://docs.gitlab.com/ee/ci/yaml/#interruptible."
+
+.run-tests:
+ stage: test
+ image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images/debian-bullseye-ruby-${RUBY_VERSION}:bundler-2.3-chrome-${CHROME_VERSION}-docker-${DOCKER_VERSION}
+ services:
+ - docker:${DOCKER_VERSION}-dind
+ tags:
+ - e2e
+ before_script:
+ - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
+ - sysctl -n -w fs.inotify.max_user_watches=524288
+ variables:
+ DOCKER_DRIVER: overlay2
+ DOCKER_HOST: tcp://docker:2375
+ QA_GDK_IMAGE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-qa-gdk:master"
+ QA_GENERATE_ALLURE_REPORT: "false"
+ QA_CAN_TEST_PRAEFECT: "false"
+ QA_INTERCEPT_REQUESTS: "false"
+ QA_RUN_TYPE: e2e-test-on-gdk
+ TEST_LICENSE_MODE: $QA_TEST_LICENSE_MODE
+ EE_LICENSE: $QA_EE_LICENSE
+ GITHUB_ACCESS_TOKEN: $QA_GITHUB_ACCESS_TOKEN
+ GITLAB_QA_ADMIN_ACCESS_TOKEN: $QA_ADMIN_ACCESS_TOKEN
+ QA_KNAPSACK_REPORTS: qa-smoke,ee-instance-parallel
+ timeout: 2 hours
+ artifacts:
+ when: always
+ paths:
+ - test_output
+ - logs
+ expire_in: 7 days
+ script:
+ - echo -e "\e[0Ksection_start:`date +%s`:pull_image\r\e[0KPull GDK QA image"
+ - docker pull ${QA_GDK_IMAGE}
+ - echo -e "\e[0Ksection_end:`date +%s`:pull_image\r\e[0K"
+ - echo -e "\e[0Ksection_start:`date +%s`:launch_gdk_and_tests\r\e[0KLaunch GDK and run QA tests"
+ - cd qa && bundle install --jobs=$(nproc) --retry=3 --quiet
+ - mkdir -p $CI_PROJECT_DIR/test_output $CI_PROJECT_DIR/logs/gdk $CI_PROJECT_DIR/logs/gitlab
+ # This command matches the permissions of the user that runs GDK inside the container.
+ - chown -R 1000:1000 $CI_PROJECT_DIR/test_output $CI_PROJECT_DIR/logs
+ - |
+ docker run --rm --name gdk --add-host gdk.test:127.0.0.1 --shm-size=2gb \
+ --env-file <(bundle exec rake ci:env_var_name_list) \
+ --volume /var/run/docker.sock:/var/run/docker.sock:z \
+ --volume $CI_PROJECT_DIR/test_output:/home/gdk/gdk/gitlab/qa/tmp:z \
+ --volume $CI_PROJECT_DIR/logs/gdk:/home/gdk/gdk/log \
+ --volume $CI_PROJECT_DIR/logs/gitlab:/home/gdk/gdk/gitlab/log \
+ ${QA_GDK_IMAGE} "${CI_COMMIT_REF_SLUG}" "$TEST_GDK_TAGS --tag ~requires_praefect" || true
+ - echo -e "\e[0Ksection_end:`date +%s`:launch_gdk_and_tests\r\e[0K"
+ allow_failure: true
+
+test-on-gdk-smoke:
+ extends:
+ - .run-tests
+ parallel: 2
+ variables:
+ TEST_GDK_TAGS: "--tag smoke"
+ QA_KNAPSACK_REPORT_NAME: qa-smoke
+ rules:
+ - when: always
+
+test-on-gdk-full:
+ extends:
+ - .run-tests
+ parallel: 5
+ variables:
+ QA_KNAPSACK_REPORT_NAME: ee-instance-parallel
+ rules:
+ - when: manual
diff --git a/.rubocop_todo/rspec/missing_feature_category.yml b/.rubocop_todo/rspec/missing_feature_category.yml
index d85dd24d803..fa24075c566 100644
--- a/.rubocop_todo/rspec/missing_feature_category.yml
+++ b/.rubocop_todo/rspec/missing_feature_category.yml
@@ -1,6 +1,5 @@
---
RSpec/MissingFeatureCategory:
- Details: grace period
Exclude:
- 'ee/spec/components/billing/plan_component_spec.rb'
- 'ee/spec/components/namespaces/free_user_cap/enforcement_alert_component_spec.rb'
@@ -45,10 +44,8 @@ RSpec/MissingFeatureCategory:
- 'ee/spec/elastic/migrate/20210910100000_redo_backfill_namespace_ancestry_ids_for_issues_spec.rb'
- 'ee/spec/elastic/migrate/20220118150500_delete_orphaned_commits_spec.rb'
- 'ee/spec/elastic/migrate/20220512150000_pause_indexing_for_unsupported_es_versions_spec.rb'
- - 'ee/spec/elastic/migrate/20220613120500_migrate_commits_to_separate_index_spec.rb'
- 'ee/spec/elastic/migrate/20220824123000_add_label_ids_and_schema_version_to_issues_mapping_spec.rb'
- 'ee/spec/elastic/migrate/20221026082700_backfill_users_spec.rb'
- - 'ee/spec/elastic_integration/global_search_spec.rb'
- 'ee/spec/elastic_integration/repository_index_spec.rb'
- 'ee/spec/features/admin/admin_emails_spec.rb'
- 'ee/spec/features/admin/admin_settings_spec.rb'
@@ -63,7 +60,6 @@ RSpec/MissingFeatureCategory:
- 'ee/spec/finders/auth/provisioned_users_finder_spec.rb'
- 'ee/spec/finders/autocomplete/group_subgroups_finder_spec.rb'
- 'ee/spec/finders/autocomplete/project_invited_groups_finder_spec.rb'
- - 'ee/spec/finders/autocomplete/vulnerabilities_autocomplete_finder_spec.rb'
- 'ee/spec/finders/billed_users_finder_spec.rb'
- 'ee/spec/finders/boards/boards_finder_spec.rb'
- 'ee/spec/finders/boards/epic_boards_finder_spec.rb'
@@ -125,7 +121,6 @@ RSpec/MissingFeatureCategory:
- 'ee/spec/finders/iterations_finder_spec.rb'
- 'ee/spec/finders/license_template_finder_spec.rb'
- 'ee/spec/finders/licenses_finder_spec.rb'
- - 'ee/spec/finders/merge_requests/by_approvers_finder_spec.rb'
- 'ee/spec/finders/merge_requests_finder_spec.rb'
- 'ee/spec/finders/merge_trains_finder_spec.rb'
- 'ee/spec/finders/notes_finder_spec.rb'
@@ -791,7 +786,6 @@ RSpec/MissingFeatureCategory:
- 'ee/spec/lib/ee/gitlab/import_export/after_export_strategies/custom_template_export_import_strategy_spec.rb'
- 'ee/spec/lib/ee/gitlab/import_export/group/tree_restorer_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/import_export/project/tree_saver_spec.rb'
- 'ee/spec/lib/ee/gitlab/import_export/repo_restorer_spec.rb'
- 'ee/spec/lib/ee/gitlab/import_export/wiki_repo_saver_spec.rb'
@@ -876,10 +870,8 @@ RSpec/MissingFeatureCategory:
- 'ee/spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_last_edited_spec.rb'
- 'ee/spec/lib/gitlab/analytics/cycle_analytics/summary/base_dora_summary_spec.rb'
- 'ee/spec/lib/gitlab/analytics/cycle_analytics/summary/change_failure_rate_spec.rb'
- - 'ee/spec/lib/gitlab/analytics/cycle_analytics/summary/group/stage_summary_spec.rb'
- 'ee/spec/lib/gitlab/analytics/cycle_analytics/summary/lead_time_for_changes_spec.rb'
- 'ee/spec/lib/gitlab/analytics/cycle_analytics/summary/lead_time_spec.rb'
- - 'ee/spec/lib/gitlab/analytics/cycle_analytics/summary/stage_time_summary_spec.rb'
- 'ee/spec/lib/gitlab/analytics/cycle_analytics/summary/time_to_restore_service_spec.rb'
- 'ee/spec/lib/gitlab/analytics/type_of_work/tasks_by_type_spec.rb'
- 'ee/spec/lib/gitlab/audit/auditor_spec.rb'
@@ -985,7 +977,6 @@ RSpec/MissingFeatureCategory:
- 'ee/spec/lib/gitlab/contribution_analytics/data_collector_spec.rb'
- 'ee/spec/lib/gitlab/custom_file_templates_spec.rb'
- 'ee/spec/lib/gitlab/customers_dot/jwt_spec.rb'
- - 'ee/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb'
- 'ee/spec/lib/gitlab/data_builder/vulnerability_spec.rb'
- 'ee/spec/lib/gitlab/elastic/bulk_indexer_spec.rb'
- 'ee/spec/lib/gitlab/elastic/client_spec.rb'
@@ -1204,7 +1195,6 @@ RSpec/MissingFeatureCategory:
- 'ee/spec/models/alert_management/alert_payload_field_spec.rb'
- 'ee/spec/models/allowed_email_domain_spec.rb'
- 'ee/spec/models/analytics/cycle_analytics/aggregation_context_spec.rb'
- - 'ee/spec/models/analytics/cycle_analytics/group_level_spec.rb'
- 'ee/spec/models/analytics/cycle_analytics/runtime_limiter_spec.rb'
- 'ee/spec/models/analytics/devops_adoption/enabled_namespace_spec.rb'
- 'ee/spec/models/analytics/devops_adoption/snapshot_spec.rb'
@@ -1232,7 +1222,6 @@ RSpec/MissingFeatureCategory:
- 'ee/spec/models/boards/epic_list_user_preference_spec.rb'
- 'ee/spec/models/boards/epic_user_preference_spec.rb'
- 'ee/spec/models/broadcast_message_spec.rb'
- - 'ee/spec/models/burndown_spec.rb'
- 'ee/spec/models/ci/bridge_spec.rb'
- 'ee/spec/models/ci/build_spec.rb'
- 'ee/spec/models/ci/daily_build_group_report_result_spec.rb'
@@ -1265,7 +1254,6 @@ RSpec/MissingFeatureCategory:
- 'ee/spec/models/concerns/elastic/issue_spec.rb'
- 'ee/spec/models/concerns/elastic/merge_request_spec.rb'
- 'ee/spec/models/concerns/elastic/milestone_spec.rb'
- - 'ee/spec/models/concerns/elastic/note_spec.rb'
- 'ee/spec/models/concerns/elastic/project_wiki_spec.rb'
- 'ee/spec/models/concerns/elastic/projects_search_spec.rb'
- 'ee/spec/models/concerns/elastic/repository_spec.rb'
@@ -1326,7 +1314,6 @@ RSpec/MissingFeatureCategory:
- 'ee/spec/models/ee/incident_management/project_incident_management_setting_spec.rb'
- 'ee/spec/models/ee/integration_spec.rb'
- 'ee/spec/models/ee/integrations/jira_spec.rb'
- - 'ee/spec/models/ee/iteration_spec.rb'
- 'ee/spec/models/ee/iterations/cadence_spec.rb'
- 'ee/spec/models/ee/key_spec.rb'
- 'ee/spec/models/ee/label_spec.rb'
@@ -1358,11 +1345,9 @@ RSpec/MissingFeatureCategory:
- 'ee/spec/models/ee/resource_state_event_spec.rb'
- 'ee/spec/models/ee/service_desk_setting_spec.rb'
- 'ee/spec/models/ee/system_note_metadata_spec.rb'
- - 'ee/spec/models/ee/terraform/state_version_spec.rb'
- 'ee/spec/models/ee/user_highest_role_spec.rb'
- 'ee/spec/models/ee/users/merge_request_interaction_spec.rb'
- 'ee/spec/models/ee/users_statistics_spec.rb'
- - 'ee/spec/models/ee/work_items/type_spec.rb'
- 'ee/spec/models/elastic/index_setting_spec.rb'
- 'ee/spec/models/elastic/migration_record_spec.rb'
- 'ee/spec/models/elastic/reindexing_slice_spec.rb'
@@ -1802,7 +1787,6 @@ RSpec/MissingFeatureCategory:
- 'ee/spec/services/ci/minutes/reset_usage_service_spec.rb'
- 'ee/spec/services/ci/minutes/track_live_consumption_service_spec.rb'
- 'ee/spec/services/ci/minutes/update_build_minutes_service_spec.rb'
- - 'ee/spec/services/ci/minutes/update_project_and_namespace_usage_service_spec.rb'
- 'ee/spec/services/ci/pipeline_bridge_status_service_spec.rb'
- 'ee/spec/services/ci/pipeline_creation/drop_not_runnable_builds_service_spec.rb'
- 'ee/spec/services/ci/pipeline_creation/start_pipeline_service_spec.rb'
@@ -1888,15 +1872,12 @@ RSpec/MissingFeatureCategory:
- 'ee/spec/services/ee/merge_requests/base_service_spec.rb'
- 'ee/spec/services/ee/merge_requests/create_approval_event_service_spec.rb'
- 'ee/spec/services/ee/merge_requests/create_from_vulnerability_data_service_spec.rb'
- - 'ee/spec/services/ee/merge_requests/create_pipeline_service_spec.rb'
- 'ee/spec/services/ee/merge_requests/create_service_spec.rb'
- 'ee/spec/services/ee/merge_requests/execute_approval_hooks_service_spec.rb'
- 'ee/spec/services/ee/merge_requests/handle_assignees_change_service_spec.rb'
- 'ee/spec/services/ee/merge_requests/post_merge_service_spec.rb'
- - 'ee/spec/services/ee/merge_requests/refresh_service_spec.rb'
- 'ee/spec/services/ee/merge_requests/update_assignees_service_spec.rb'
- 'ee/spec/services/ee/merge_requests/update_reviewers_service_spec.rb'
- - 'ee/spec/services/ee/merge_requests/update_service_spec.rb'
- 'ee/spec/services/ee/namespace_settings/update_service_spec.rb'
- 'ee/spec/services/ee/notes/destroy_service_spec.rb'
- 'ee/spec/services/ee/notes/post_process_service_spec.rb'
@@ -2017,7 +1998,6 @@ RSpec/MissingFeatureCategory:
- 'ee/spec/services/group_saml/saml_provider/update_service_spec.rb'
- 'ee/spec/services/group_saml/sign_up_service_spec.rb'
- 'ee/spec/services/groups/create_service_spec.rb'
- - 'ee/spec/services/groups/destroy_service_spec.rb'
- 'ee/spec/services/groups/epics_count_service_spec.rb'
- 'ee/spec/services/groups/mark_for_deletion_service_spec.rb'
- 'ee/spec/services/groups/memberships/export_service_spec.rb'
@@ -2121,7 +2101,6 @@ RSpec/MissingFeatureCategory:
- 'ee/spec/services/projects/cleanup_service_spec.rb'
- 'ee/spec/services/projects/create_from_template_service_spec.rb'
- 'ee/spec/services/projects/create_service_spec.rb'
- - 'ee/spec/services/projects/destroy_service_spec.rb'
- 'ee/spec/services/projects/disable_deploy_key_service_spec.rb'
- 'ee/spec/services/projects/disable_legacy_inactive_projects_service_spec.rb'
- 'ee/spec/services/projects/enable_deploy_key_service_spec.rb'
@@ -2168,14 +2147,8 @@ RSpec/MissingFeatureCategory:
- 'ee/spec/services/security/ingestion/ingest_report_slice_service_spec.rb'
- 'ee/spec/services/security/ingestion/ingest_reports_service_spec.rb'
- 'ee/spec/services/security/ingestion/mark_as_resolved_service_spec.rb'
- - 'ee/spec/services/security/ingestion/tasks/attach_findings_to_vulnerabilities_spec.rb'
- 'ee/spec/services/security/ingestion/tasks/hooks_execution_spec.rb'
- 'ee/spec/services/security/ingestion/tasks/ingest_finding_evidence_spec.rb'
- - 'ee/spec/services/security/ingestion/tasks/ingest_finding_identifiers_spec.rb'
- - 'ee/spec/services/security/ingestion/tasks/ingest_finding_links_spec.rb'
- - 'ee/spec/services/security/ingestion/tasks/ingest_finding_pipelines_spec.rb'
- - 'ee/spec/services/security/ingestion/tasks/ingest_finding_signatures_spec.rb'
- - 'ee/spec/services/security/ingestion/tasks/ingest_findings_spec.rb'
- 'ee/spec/services/security/ingestion/tasks/ingest_identifiers_spec.rb'
- 'ee/spec/services/security/ingestion/tasks/ingest_remediations_spec.rb'
- 'ee/spec/services/security/ingestion/tasks/ingest_vulnerabilities/mark_resolved_as_detected_spec.rb'
@@ -2365,7 +2338,6 @@ RSpec/MissingFeatureCategory:
- 'ee/spec/workers/analytics/cycle_analytics/reaggregation_worker_spec.rb'
- 'ee/spec/workers/analytics/devops_adoption/create_all_snapshots_worker_spec.rb'
- 'ee/spec/workers/analytics/devops_adoption/create_snapshot_worker_spec.rb'
- - 'ee/spec/workers/app_sec/dast/profile_schedule_worker_spec.rb'
- 'ee/spec/workers/app_sec/dast/scanner_profiles_builds/consistency_worker_spec.rb'
- 'ee/spec/workers/app_sec/dast/scans/consistency_worker_spec.rb'
- 'ee/spec/workers/app_sec/dast/site_profiles_builds/consistency_worker_spec.rb'
@@ -2437,7 +2409,6 @@ RSpec/MissingFeatureCategory:
- 'ee/spec/workers/geo/reverification_batch_worker_spec.rb'
- 'ee/spec/workers/geo/scheduler/per_shard_scheduler_worker_spec.rb'
- 'ee/spec/workers/geo/scheduler/scheduler_worker_spec.rb'
- - 'ee/spec/workers/geo/secondary/registry_consistency_worker_spec.rb'
- 'ee/spec/workers/geo/secondary_usage_data_cron_worker_spec.rb'
- 'ee/spec/workers/geo/sidekiq_cron_config_worker_spec.rb'
- 'ee/spec/workers/geo/sync_timeout_cron_worker_spec.rb'
@@ -2542,7 +2513,6 @@ RSpec/MissingFeatureCategory:
- 'spec/controllers/admin/application_settings_controller_spec.rb'
- 'spec/controllers/admin/applications_controller_spec.rb'
- 'spec/controllers/admin/ci/variables_controller_spec.rb'
- - 'spec/controllers/admin/clusters_controller_spec.rb'
- 'spec/controllers/admin/cohorts_controller_spec.rb'
- 'spec/controllers/admin/dashboard_controller_spec.rb'
- 'spec/controllers/admin/dev_ops_report_controller_spec.rb'
@@ -2552,7 +2522,6 @@ RSpec/MissingFeatureCategory:
- 'spec/controllers/admin/hooks_controller_spec.rb'
- 'spec/controllers/admin/identities_controller_spec.rb'
- 'spec/controllers/admin/impersonations_controller_spec.rb'
- - 'spec/controllers/admin/instance_review_controller_spec.rb'
- 'spec/controllers/admin/integrations_controller_spec.rb'
- 'spec/controllers/admin/jobs_controller_spec.rb'
- 'spec/controllers/admin/plan_limits_controller_spec.rb'
@@ -2601,26 +2570,21 @@ RSpec/MissingFeatureCategory:
- 'spec/controllers/dashboard/groups_controller_spec.rb'
- 'spec/controllers/dashboard/labels_controller_spec.rb'
- 'spec/controllers/dashboard/milestones_controller_spec.rb'
- - 'spec/controllers/dashboard/projects_controller_spec.rb'
- 'spec/controllers/dashboard/snippets_controller_spec.rb'
- 'spec/controllers/dashboard/todos_controller_spec.rb'
- 'spec/controllers/every_controller_spec.rb'
- 'spec/controllers/explore/groups_controller_spec.rb'
- - 'spec/controllers/explore/projects_controller_spec.rb'
- 'spec/controllers/explore/snippets_controller_spec.rb'
- 'spec/controllers/google_api/authorizations_controller_spec.rb'
- 'spec/controllers/groups/application_controller_spec.rb'
- 'spec/controllers/groups/avatars_controller_spec.rb'
- 'spec/controllers/groups/boards_controller_spec.rb'
- - 'spec/controllers/groups/children_controller_spec.rb'
- - 'spec/controllers/groups/clusters_controller_spec.rb'
- 'spec/controllers/groups/dependency_proxies_controller_spec.rb'
- 'spec/controllers/groups/dependency_proxy_auth_controller_spec.rb'
- 'spec/controllers/groups/dependency_proxy_for_containers_controller_spec.rb'
- 'spec/controllers/groups/group_links_controller_spec.rb'
- 'spec/controllers/groups/group_members_controller_spec.rb'
- 'spec/controllers/groups/imports_controller_spec.rb'
- - 'spec/controllers/groups/labels_controller_spec.rb'
- 'spec/controllers/groups/milestones_controller_spec.rb'
- 'spec/controllers/groups/packages_controller_spec.rb'
- 'spec/controllers/groups/registry/repositories_controller_spec.rb'
@@ -2679,13 +2643,10 @@ RSpec/MissingFeatureCategory:
- 'spec/controllers/projects/blame_controller_spec.rb'
- 'spec/controllers/projects/blob_controller_spec.rb'
- 'spec/controllers/projects/boards_controller_spec.rb'
- - 'spec/controllers/projects/branches_controller_spec.rb'
- 'spec/controllers/projects/ci/daily_build_group_report_results_controller_spec.rb'
- 'spec/controllers/projects/ci/lints_controller_spec.rb'
- 'spec/controllers/projects/ci/pipeline_editor_controller_spec.rb'
- - 'spec/controllers/projects/clusters_controller_spec.rb'
- 'spec/controllers/projects/commit_controller_spec.rb'
- - 'spec/controllers/projects/commits_controller_spec.rb'
- 'spec/controllers/projects/compare_controller_spec.rb'
- 'spec/controllers/projects/cycle_analytics/events_controller_spec.rb'
- 'spec/controllers/projects/cycle_analytics_controller_spec.rb'
@@ -2702,20 +2663,15 @@ RSpec/MissingFeatureCategory:
- 'spec/controllers/projects/feature_flags_controller_spec.rb'
- 'spec/controllers/projects/feature_flags_user_lists_controller_spec.rb'
- 'spec/controllers/projects/find_file_controller_spec.rb'
- - 'spec/controllers/projects/forks_controller_spec.rb'
- 'spec/controllers/projects/graphs_controller_spec.rb'
- 'spec/controllers/projects/hooks_controller_spec.rb'
- 'spec/controllers/projects/import/jira_controller_spec.rb'
- 'spec/controllers/projects/imports_controller_spec.rb'
- 'spec/controllers/projects/incidents_controller_spec.rb'
- 'spec/controllers/projects/issue_links_controller_spec.rb'
- - 'spec/controllers/projects/issues_controller_spec.rb'
- - 'spec/controllers/projects/labels_controller_spec.rb'
- 'spec/controllers/projects/mattermosts_controller_spec.rb'
- 'spec/controllers/projects/merge_requests/conflicts_controller_spec.rb'
- 'spec/controllers/projects/merge_requests/content_controller_spec.rb'
- - 'spec/controllers/projects/merge_requests/creations_controller_spec.rb'
- - 'spec/controllers/projects/merge_requests/diffs_controller_spec.rb'
- 'spec/controllers/projects/merge_requests/drafts_controller_spec.rb'
- 'spec/controllers/projects/milestones_controller_spec.rb'
- 'spec/controllers/projects/mirrors_controller_spec.rb'
@@ -2738,7 +2694,6 @@ RSpec/MissingFeatureCategory:
- 'spec/controllers/projects/security/configuration_controller_spec.rb'
- 'spec/controllers/projects/service_desk_controller_spec.rb'
- 'spec/controllers/projects/service_ping_controller_spec.rb'
- - 'spec/controllers/projects/settings/ci_cd_controller_spec.rb'
- 'spec/controllers/projects/settings/integration_hook_logs_controller_spec.rb'
- 'spec/controllers/projects/settings/merge_requests_controller_spec.rb'
- 'spec/controllers/projects/settings/operations_controller_spec.rb'
@@ -2756,7 +2711,6 @@ RSpec/MissingFeatureCategory:
- 'spec/controllers/projects/web_ide_schemas_controller_spec.rb'
- 'spec/controllers/projects/web_ide_terminals_controller_spec.rb'
- 'spec/controllers/projects/wikis_controller_spec.rb'
- - 'spec/controllers/projects_controller_spec.rb'
- 'spec/controllers/repositories/git_http_controller_spec.rb'
- 'spec/controllers/repositories/lfs_storage_controller_spec.rb'
- 'spec/controllers/root_controller_spec.rb'
@@ -2771,10 +2725,8 @@ RSpec/MissingFeatureCategory:
- 'spec/controllers/users/terms_controller_spec.rb'
- 'spec/controllers/users/unsubscribes_controller_spec.rb'
- 'spec/db/development/add_security_training_providers_spec.rb'
- - 'spec/db/development/create_base_work_item_types_spec.rb'
- 'spec/db/development/import_common_metrics_spec.rb'
- 'spec/db/production/add_security_training_providers_spec.rb'
- - 'spec/db/production/create_base_work_item_types_spec.rb'
- 'spec/db/production/import_common_metrics_spec.rb'
- 'spec/db/production/settings_spec.rb'
- 'spec/dependencies/omniauth_saml_spec.rb'
@@ -2915,7 +2867,6 @@ RSpec/MissingFeatureCategory:
- 'spec/finders/prometheus_metrics_finder_spec.rb'
- 'spec/finders/protected_branches_finder_spec.rb'
- 'spec/finders/releases/evidence_pipeline_finder_spec.rb'
- - 'spec/finders/releases/group_releases_finder_spec.rb'
- 'spec/finders/releases_finder_spec.rb'
- 'spec/finders/repositories/branch_names_finder_spec.rb'
- 'spec/finders/repositories/changelog_commits_finder_spec.rb'
@@ -3573,7 +3524,6 @@ RSpec/MissingFeatureCategory:
- 'spec/helpers/listbox_helper_spec.rb'
- 'spec/helpers/markup_helper_spec.rb'
- 'spec/helpers/members_helper_spec.rb'
- - 'spec/helpers/merge_requests_helper_spec.rb'
- 'spec/helpers/milestones_helper_spec.rb'
- 'spec/helpers/namespaces_helper_spec.rb'
- 'spec/helpers/nav/top_nav_helper_spec.rb'
@@ -3658,7 +3608,6 @@ RSpec/MissingFeatureCategory:
- 'spec/initializers/google_api_client_spec.rb'
- 'spec/initializers/hangouts_chat_http_override_spec.rb'
- 'spec/initializers/hashie_mash_permitted_patch_spec.rb'
- - 'spec/initializers/load_balancing_spec.rb'
- 'spec/initializers/lograge_spec.rb'
- 'spec/initializers/mail_encoding_patch_spec.rb'
- 'spec/initializers/mailer_retries_spec.rb'
@@ -4105,7 +4054,6 @@ RSpec/MissingFeatureCategory:
- 'spec/lib/gitlab/build_access_spec.rb'
- 'spec/lib/gitlab/bullet/exclusions_spec.rb'
- 'spec/lib/gitlab/bullet_spec.rb'
- - 'spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb'
- 'spec/lib/gitlab/cache/helpers_spec.rb'
- 'spec/lib/gitlab/cache/import/caching_spec.rb'
- 'spec/lib/gitlab/cache/metrics_spec.rb'
@@ -4409,7 +4357,6 @@ RSpec/MissingFeatureCategory:
- 'spec/lib/gitlab/ci/templates/katalon_gitlab_ci_yaml_spec.rb'
- 'spec/lib/gitlab/ci/templates/templates_spec.rb'
- 'spec/lib/gitlab/ci/templates/terraform_gitlab_ci_yaml_spec.rb'
- - 'spec/lib/gitlab/ci/trace/archive_spec.rb'
- 'spec/lib/gitlab/ci/trace/backoff_spec.rb'
- 'spec/lib/gitlab/ci/trace/checksum_spec.rb'
- 'spec/lib/gitlab/ci/trace/chunked_io_spec.rb'
@@ -4476,7 +4423,6 @@ RSpec/MissingFeatureCategory:
- 'spec/lib/gitlab/crypto_helper_spec.rb'
- 'spec/lib/gitlab/current_settings_spec.rb'
- 'spec/lib/gitlab/cycle_analytics/permissions_spec.rb'
- - 'spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb'
- 'spec/lib/gitlab/cycle_analytics/summary/value_spec.rb'
- 'spec/lib/gitlab/cycle_analytics/updater_spec.rb'
- 'spec/lib/gitlab/daemon_spec.rb'
@@ -4527,7 +4473,6 @@ RSpec/MissingFeatureCategory:
- 'spec/lib/gitlab/database/load_balancing/sidekiq_server_middleware_spec.rb'
- 'spec/lib/gitlab/database/load_balancing/srv_resolver_spec.rb'
- 'spec/lib/gitlab/database/load_balancing/sticking_spec.rb'
- - 'spec/lib/gitlab/database/load_balancing_spec.rb'
- 'spec/lib/gitlab/database/loose_foreign_keys_spec.rb'
- 'spec/lib/gitlab/database/migration_helpers/announce_database_spec.rb'
- 'spec/lib/gitlab/database/migration_helpers/cascading_namespace_settings_spec.rb'
@@ -4552,7 +4497,6 @@ RSpec/MissingFeatureCategory:
- 'spec/lib/gitlab/database/migrations/runner_spec.rb'
- 'spec/lib/gitlab/database/migrations/sidekiq_helpers_spec.rb'
- 'spec/lib/gitlab/database/migrations/test_background_runner_spec.rb'
- - 'spec/lib/gitlab/database/migrations/timeout_helpers_spec.rb'
- 'spec/lib/gitlab/database/no_cross_db_foreign_keys_spec.rb'
- 'spec/lib/gitlab/database/obsolete_ignored_columns_spec.rb'
- 'spec/lib/gitlab/database/partitioning/convert_table_to_first_list_partition_spec.rb'
@@ -4587,12 +4531,8 @@ RSpec/MissingFeatureCategory:
- 'spec/lib/gitlab/database/query_analyzers/ci/partitioning_routing_analyzer_spec.rb'
- 'spec/lib/gitlab/database/query_analyzers/gitlab_schemas_metrics_spec.rb'
- 'spec/lib/gitlab/database/query_analyzers/restrict_allowed_schemas_spec.rb'
- - 'spec/lib/gitlab/database/reflection_spec.rb'
- 'spec/lib/gitlab/database/reindexing/grafana_notifier_spec.rb'
- 'spec/lib/gitlab/database/reindexing/reindex_concurrently_spec.rb'
- - 'spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb'
- - 'spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb'
- - 'spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb'
- 'spec/lib/gitlab/database/rename_reserved_paths_migration/v1_spec.rb'
- 'spec/lib/gitlab/database/schema_cache_with_renamed_table_spec.rb'
- 'spec/lib/gitlab/database/schema_cleaner_spec.rb'
@@ -4601,20 +4541,16 @@ RSpec/MissingFeatureCategory:
- 'spec/lib/gitlab/database/sha_attribute_spec.rb'
- 'spec/lib/gitlab/database/similarity_score_spec.rb'
- 'spec/lib/gitlab/database/tables_sorted_by_foreign_keys_spec.rb'
- - 'spec/lib/gitlab/database/transaction/observer_spec.rb'
- 'spec/lib/gitlab/database/type/color_spec.rb'
- 'spec/lib/gitlab/database/type/indifferent_jsonb_spec.rb'
- 'spec/lib/gitlab/database/type/json_pg_safe_spec.rb'
- 'spec/lib/gitlab/database/type/symbolized_jsonb_spec.rb'
- 'spec/lib/gitlab/database/unidirectional_copy_trigger_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_importers/common_metrics/prometheus_metric_spec.rb'
- 'spec/lib/gitlab/database_importers/instance_administrators/create_group_spec.rb'
- 'spec/lib/gitlab/database_importers/self_monitoring/project/create_service_spec.rb'
- 'spec/lib/gitlab/database_importers/self_monitoring/project/delete_service_spec.rb'
- - 'spec/lib/gitlab/database_importers/work_items/base_type_importer_spec.rb'
- 'spec/lib/gitlab/database_spec.rb'
- 'spec/lib/gitlab/default_branch_spec.rb'
- 'spec/lib/gitlab/dependency_linker/base_linker_spec.rb'
@@ -5214,7 +5150,6 @@ RSpec/MissingFeatureCategory:
- 'spec/lib/gitlab/metrics/subscribers/action_view_spec.rb'
- 'spec/lib/gitlab/metrics/subscribers/active_record_spec.rb'
- 'spec/lib/gitlab/metrics/subscribers/external_http_spec.rb'
- - 'spec/lib/gitlab/metrics/subscribers/load_balancing_spec.rb'
- 'spec/lib/gitlab/metrics/subscribers/rack_attack_spec.rb'
- 'spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb'
- 'spec/lib/gitlab/metrics/system_spec.rb'
@@ -5798,8 +5733,6 @@ RSpec/MissingFeatureCategory:
- 'spec/mailers/notify_spec.rb'
- 'spec/mailers/previews_spec.rb'
- 'spec/mailers/repository_check_mailer_spec.rb'
- - 'spec/migrations/20221122132812_schedule_prune_stale_project_export_jobs_spec.rb'
- - 'spec/migrations/20221205151917_schedule_backfill_environment_tier_spec.rb'
- 'spec/models/ability_spec.rb'
- 'spec/models/active_session_spec.rb'
- 'spec/models/acts_as_taggable_on/tag_spec.rb'
@@ -5992,7 +5925,6 @@ RSpec/MissingFeatureCategory:
- 'spec/models/concerns/optionally_search_spec.rb'
- 'spec/models/concerns/participable_spec.rb'
- 'spec/models/concerns/partitioned_table_spec.rb'
- - 'spec/models/concerns/pg_full_text_searchable_spec.rb'
- 'spec/models/concerns/presentable_spec.rb'
- 'spec/models/concerns/project_api_compatibility_spec.rb'
- 'spec/models/concerns/project_features_compatibility_spec.rb'
@@ -6033,7 +5965,6 @@ RSpec/MissingFeatureCategory:
- 'spec/models/concerns/x509_serial_number_attribute_spec.rb'
- 'spec/models/container_expiration_policy_spec.rb'
- 'spec/models/container_registry/event_spec.rb'
- - 'spec/models/container_repository_spec.rb'
- 'spec/models/context_commits_diff_spec.rb'
- 'spec/models/custom_emoji_spec.rb'
- 'spec/models/customer_relations/contact_spec.rb'
@@ -6189,13 +6120,11 @@ RSpec/MissingFeatureCategory:
- 'spec/models/list_user_preference_spec.rb'
- 'spec/models/loose_foreign_keys/deleted_record_spec.rb'
- 'spec/models/loose_foreign_keys/modification_tracker_spec.rb'
- - 'spec/models/member_spec.rb'
- 'spec/models/members/group_member_spec.rb'
- 'spec/models/members/last_group_owner_assigner_spec.rb'
- 'spec/models/members/member_task_spec.rb'
- 'spec/models/members/project_member_spec.rb'
- 'spec/models/merge_request/approval_removal_settings_spec.rb'
- - 'spec/models/merge_request/cleanup_schedule_spec.rb'
- 'spec/models/merge_request/diff_commit_user_spec.rb'
- 'spec/models/merge_request/metrics_spec.rb'
- 'spec/models/merge_request_assignee_spec.rb'
@@ -7168,7 +7097,6 @@ RSpec/MissingFeatureCategory:
- 'spec/services/groups/deploy_tokens/create_service_spec.rb'
- 'spec/services/groups/deploy_tokens/destroy_service_spec.rb'
- 'spec/services/groups/deploy_tokens/revoke_service_spec.rb'
- - 'spec/services/groups/destroy_service_spec.rb'
- 'spec/services/groups/group_links/create_service_spec.rb'
- 'spec/services/groups/group_links/destroy_service_spec.rb'
- 'spec/services/groups/group_links/update_service_spec.rb'
@@ -7222,7 +7150,6 @@ RSpec/MissingFeatureCategory:
- 'spec/services/issues/close_service_spec.rb'
- 'spec/services/issues/create_service_spec.rb'
- 'spec/services/issues/duplicate_service_spec.rb'
- - 'spec/services/issues/move_service_spec.rb'
- 'spec/services/issues/prepare_import_csv_service_spec.rb'
- 'spec/services/issues/referenced_merge_requests_service_spec.rb'
- 'spec/services/issues/related_branches_service_spec.rb'
@@ -7279,19 +7206,15 @@ RSpec/MissingFeatureCategory:
- 'spec/services/merge_requests/approval_service_spec.rb'
- 'spec/services/merge_requests/assign_issues_service_spec.rb'
- 'spec/services/merge_requests/cleanup_refs_service_spec.rb'
- - 'spec/services/merge_requests/close_service_spec.rb'
- 'spec/services/merge_requests/conflicts/list_service_spec.rb'
- 'spec/services/merge_requests/conflicts/resolve_service_spec.rb'
- 'spec/services/merge_requests/create_approval_event_service_spec.rb'
- - 'spec/services/merge_requests/create_from_issue_service_spec.rb'
- 'spec/services/merge_requests/create_pipeline_service_spec.rb'
- - 'spec/services/merge_requests/create_service_spec.rb'
- 'spec/services/merge_requests/delete_non_latest_diffs_service_spec.rb'
- 'spec/services/merge_requests/execute_approval_hooks_service_spec.rb'
- 'spec/services/merge_requests/ff_merge_service_spec.rb'
- 'spec/services/merge_requests/get_urls_service_spec.rb'
- 'spec/services/merge_requests/handle_assignees_change_service_spec.rb'
- - 'spec/services/merge_requests/link_lfs_objects_service_spec.rb'
- 'spec/services/merge_requests/mark_reviewer_reviewed_service_spec.rb'
- 'spec/services/merge_requests/merge_orchestration_service_spec.rb'
- 'spec/services/merge_requests/merge_service_spec.rb'
@@ -7309,15 +7232,12 @@ RSpec/MissingFeatureCategory:
- 'spec/services/merge_requests/migrate_external_diffs_service_spec.rb'
- 'spec/services/merge_requests/post_merge_service_spec.rb'
- 'spec/services/merge_requests/push_options_handler_service_spec.rb'
- - 'spec/services/merge_requests/pushed_branches_service_spec.rb'
- - 'spec/services/merge_requests/rebase_service_spec.rb'
- 'spec/services/merge_requests/reload_diffs_service_spec.rb'
- 'spec/services/merge_requests/reload_merge_head_diff_service_spec.rb'
- 'spec/services/merge_requests/reopen_service_spec.rb'
- 'spec/services/merge_requests/request_review_service_spec.rb'
- 'spec/services/merge_requests/resolve_todos_service_spec.rb'
- 'spec/services/merge_requests/resolved_discussion_notification_service_spec.rb'
- - 'spec/services/merge_requests/retarget_chain_service_spec.rb'
- 'spec/services/merge_requests/squash_service_spec.rb'
- 'spec/services/merge_requests/update_assignees_service_spec.rb'
- 'spec/services/merge_requests/update_reviewers_service_spec.rb'
@@ -7420,7 +7340,6 @@ RSpec/MissingFeatureCategory:
- 'spec/services/packages/update_package_file_service_spec.rb'
- 'spec/services/packages/update_tags_service_spec.rb'
- 'spec/services/pages/delete_service_spec.rb'
- - 'spec/services/pages/migrate_from_legacy_storage_service_spec.rb'
- 'spec/services/pages/migrate_legacy_storage_to_deployment_service_spec.rb'
- 'spec/services/pages/zip_directory_service_spec.rb'
- 'spec/services/pages_domains/create_acme_order_service_spec.rb'
@@ -7455,7 +7374,6 @@ RSpec/MissingFeatureCategory:
- 'spec/services/projects/create_from_template_service_spec.rb'
- 'spec/services/projects/deploy_tokens/create_service_spec.rb'
- 'spec/services/projects/deploy_tokens/destroy_service_spec.rb'
- - 'spec/services/projects/destroy_service_spec.rb'
- 'spec/services/projects/detect_repository_languages_service_spec.rb'
- 'spec/services/projects/download_service_spec.rb'
- 'spec/services/projects/enable_deploy_key_service_spec.rb'
@@ -7904,7 +7822,6 @@ RSpec/MissingFeatureCategory:
- 'spec/views/projects/jobs/show.html.haml_spec.rb'
- 'spec/views/projects/merge_requests/_close_reopen_draft_report_toggle.html.haml_spec.rb'
- 'spec/views/projects/merge_requests/_commits.html.haml_spec.rb'
- - 'spec/views/projects/merge_requests/creations/_new_submit.html.haml_spec.rb'
- 'spec/views/projects/merge_requests/edit.html.haml_spec.rb'
- 'spec/views/projects/merge_requests/show.html.haml_spec.rb'
- 'spec/views/projects/milestones/index.html.haml_spec.rb'
@@ -7973,7 +7890,6 @@ RSpec/MissingFeatureCategory:
- 'spec/workers/ci/delete_objects_worker_spec.rb'
- 'spec/workers/ci/delete_unit_tests_worker_spec.rb'
- 'spec/workers/ci/drop_pipeline_worker_spec.rb'
- - 'spec/workers/ci/external_pull_requests/create_pipeline_worker_spec.rb'
- 'spec/workers/ci/job_artifacts/expire_project_build_artifacts_worker_spec.rb'
- 'spec/workers/ci/job_artifacts/track_artifact_report_worker_spec.rb'
- 'spec/workers/ci/merge_requests/add_todo_when_build_fails_worker_spec.rb'
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index 9153b5364c1..c75f591c824 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-cfc26d1625b38163a88a48c67fdf7e1598e38f81
+8d2bce18d28dcffcaac90d0b2cb8815af07beef1
diff --git a/Gemfile b/Gemfile
index bbda77ae01d..0f64f3c9b04 100644
--- a/Gemfile
+++ b/Gemfile
@@ -378,7 +378,7 @@ group :development do
gem 'solargraph', '~> 0.47.2', require: false
gem 'letter_opener_web', '~> 2.0.0'
- gem 'lookbook', '~> 1.4', '>= 1.4.5'
+ gem 'lookbook', '~> 1.5', '>= 1.5.3'
# Better errors handler
gem 'better_errors', '~> 2.9.1'
diff --git a/Gemfile.checksum b/Gemfile.checksum
index a68b2f221ef..338358973e2 100644
--- a/Gemfile.checksum
+++ b/Gemfile.checksum
@@ -163,7 +163,7 @@
{"name":"faraday_middleware-aws-sigv4","version":"0.3.0","platform":"ruby","checksum":"744654bd5b15539a54aed39b806e2dfb45aa47708fa1e6f6766fedcda6c262be"},
{"name":"faraday_middleware-multi_json","version":"0.0.6","platform":"ruby","checksum":"38fc4dab7a78916ad09827d5a164aab62fbf2cb8b9de0507763de1f561d7a118"},
{"name":"fast_blank","version":"1.0.0","platform":"ruby","checksum":"a67c93dbcb8c34ba40973688e4b600b640760503362f3aeb63b37ebe3d8d419b"},
-{"name":"fast_gettext","version":"2.1.0","platform":"ruby","checksum":"0d095dbc5a003b3caea13b9569288703086ae05aac2cc6d7b0881c8e0a07ae15"},
+{"name":"fast_gettext","version":"2.3.0","platform":"ruby","checksum":"0253e26423ccab68061c42387827e3b99243a1b15ad614df1c800ba870d64f84"},
{"name":"ffaker","version":"2.10.0","platform":"ruby","checksum":"4323b85b4bbdb0d932695b2ebffeb3645304215092e64e2a451630a9f5a5e507"},
{"name":"ffi","version":"1.15.5","platform":"java","checksum":"610b9a993e67b812123cfedc1c45a639aa2f2455747af5443d54f98e092b1abe"},
{"name":"ffi","version":"1.15.5","platform":"ruby","checksum":"6f2ed2fa68047962d6072b964420cba91d82ce6fa8ee251950c17fca6af3c2a0"},
@@ -326,7 +326,7 @@
{"name":"lockbox","version":"1.1.1","platform":"ruby","checksum":"0af16b14c54f791c148615a0115387b51903d868c7fe622f49606c97071c2ac0"},
{"name":"lograge","version":"0.11.2","platform":"ruby","checksum":"4cbd1554b86f545d795eff15a0c24fd25057d2ac4e1caa5fc186168b3da932ef"},
{"name":"loofah","version":"2.19.1","platform":"ruby","checksum":"6c6469efdefe3496010000a346f9d3bf710e11ac4661e353cf56852326fb1023"},
-{"name":"lookbook","version":"1.4.5","platform":"ruby","checksum":"bc15b332d2c84f51aca60353f070c0b6a363b7496259e1dd7572d5ec122c9cdb"},
+{"name":"lookbook","version":"1.5.3","platform":"ruby","checksum":"4a0ff475af85de0dcdf45a5541fbc40dd8f66669a559efe8297c1d7fee028b38"},
{"name":"lru_redux","version":"1.1.0","platform":"ruby","checksum":"ee71d0ccab164c51de146c27b480a68b3631d5b4297b8ffe8eda1c72de87affb"},
{"name":"lumberjack","version":"1.2.7","platform":"ruby","checksum":"a5c6aae6b4234f1420dbcd80b23e3bca0817bd239440dde097ebe3fa63c63b1f"},
{"name":"mail","version":"2.7.1","platform":"ruby","checksum":"ec2a3d489f7510b90d8eaa3f6abaad7038cf1d663cdf8ee66d0214a0bdf99c03"},
@@ -470,7 +470,7 @@
{"name":"re2","version":"1.6.0","platform":"ruby","checksum":"2e37f27971f6a76223eac688c04f3e48aea374f34b302ec22d75b4635cd64bc1"},
{"name":"recaptcha","version":"5.12.3","platform":"ruby","checksum":"37d1894add9e70a54d0c6c7f0ecbeedffbfa7d075acfbd4c509818dfdebdb7ee"},
{"name":"recursive-open-struct","version":"1.1.3","platform":"ruby","checksum":"a3538a72552fcebcd0ada657bdff313641a4a5fbc482c08cfb9a65acb1c9de5a"},
-{"name":"redcarpet","version":"3.5.1","platform":"ruby","checksum":"717f64cb6ec11c8d9ec9b521ed26ca2eeda68b4fe1fc3388a641176dbd47732f"},
+{"name":"redcarpet","version":"3.6.0","platform":"ruby","checksum":"8ad1889c0355ff4c47174af14edd06d62f45a326da1da6e8a121d59bdcd2e9e9"},
{"name":"redis","version":"4.8.0","platform":"ruby","checksum":"2000cf5014669c9dc821704b6d322a35a9a33852a95208911d9175d63b448a44"},
{"name":"redis-actionpack","version":"5.3.0","platform":"ruby","checksum":"3fb1ad0a8fd9d26a289c9399bb609dcaef38bf37711e6f677a53ca728fc19140"},
{"name":"redis-namespace","version":"1.9.0","platform":"ruby","checksum":"0923961f38cf15b86cb57d92507e0a3b32480729eb5033249f5de8b12e0d8612"},
diff --git a/Gemfile.lock b/Gemfile.lock
index 2a5a163dcc5..ca37508841b 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -478,7 +478,7 @@ GEM
faraday_middleware
multi_json
fast_blank (1.0.0)
- fast_gettext (2.1.0)
+ fast_gettext (2.3.0)
ffaker (2.10.0)
ffi (1.15.5)
ffi-compiler (1.0.1)
@@ -883,7 +883,7 @@ GEM
loofah (2.19.1)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
- lookbook (1.4.5)
+ lookbook (1.5.3)
actioncable
activemodel
css_parser
@@ -893,7 +893,7 @@ GEM
railties (>= 5.0)
redcarpet (~> 3.5)
rouge (>= 3.26, < 5.0)
- view_component (~> 2.0)
+ view_component (> 2.0, < 4)
yard (~> 0.9.25)
zeitwerk (~> 2.5)
lru_redux (1.1.0)
@@ -1188,7 +1188,7 @@ GEM
recaptcha (5.12.3)
json
recursive-open-struct (1.1.3)
- redcarpet (3.5.1)
+ redcarpet (3.6.0)
redis (4.8.0)
redis-actionpack (5.3.0)
actionpack (>= 5, < 8)
@@ -1746,7 +1746,7 @@ DEPENDENCIES
lockbox (~> 1.1.1)
lograge (~> 0.5)
loofah (~> 2.19.1)
- lookbook (~> 1.4, >= 1.4.5)
+ lookbook (~> 1.5, >= 1.5.3)
lru_redux
mail (= 2.7.1)
mail-smtp_pool (~> 0.1.0)!
diff --git a/app/assets/javascripts/boards/components/boards_selector.vue b/app/assets/javascripts/boards/components/boards_selector.vue
index 2f521363c16..a1a49386b37 100644
--- a/app/assets/javascripts/boards/components/boards_selector.vue
+++ b/app/assets/javascripts/boards/components/boards_selector.vue
@@ -68,11 +68,11 @@ export default {
data() {
return {
hasScrollFade: false,
- loadingBoards: 0,
- loadingRecentBoards: false,
scrollFadeInitialized: false,
boards: [],
recentBoards: [],
+ loadingBoards: false,
+ loadingRecentBoards: false,
throttledSetScrollFade: throttle(this.setScrollFade, this.throttleDuration),
contentClientHeight: 0,
maxPosition: 0,
@@ -90,7 +90,7 @@ export default {
return this.boardType;
},
loading() {
- return this.loadingRecentBoards || Boolean(this.loadingBoards);
+ return this.loadingRecentBoards || this.loadingBoards;
},
filteredBoards() {
return this.boards.filter((board) =>
@@ -171,8 +171,10 @@ export default {
return { fullPath: this.fullPath };
},
query: this.boardQuery,
- loadingKey: 'loadingBoards',
update: (data) => this.boardUpdate(data, 'boards'),
+ watchLoading: (isLoading) => {
+ this.loadingBoards = isLoading;
+ },
});
this.loadRecentBoards();
@@ -183,8 +185,10 @@ export default {
return { fullPath: this.fullPath };
},
query: this.recentBoardsQuery,
- loadingKey: 'loadingRecentBoards',
update: (data) => this.boardUpdate(data, 'recentIssueBoards'),
+ watchLoading: (isLoading) => {
+ this.loadingRecentBoards = isLoading;
+ },
});
},
isScrolledUp() {
diff --git a/app/assets/javascripts/diffs/components/diff_row.vue b/app/assets/javascripts/diffs/components/diff_row.vue
index e5695c4390f..dfca6d61270 100644
--- a/app/assets/javascripts/diffs/components/diff_row.vue
+++ b/app/assets/javascripts/diffs/components/diff_row.vue
@@ -60,6 +60,16 @@ export default {
type: Boolean,
required: true,
},
+ isFirstHighlightedLine: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ isLastHighlightedLine: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
fileLineCoverage: {
type: Function,
required: true,
@@ -81,12 +91,23 @@ export default {
),
parallelViewLeftLineType: memoize(
(props) => {
- return utils.parallelViewLeftLineType(props.line, props.isHighlighted || props.isCommented);
+ return utils.parallelViewLeftLineType({
+ line: props.line,
+ highlighted: props.isHighlighted,
+ commented: props.isCommented,
+ selectionStart: props.isFirstHighlightedLine,
+ selectionEnd: props.isLastHighlightedLine,
+ });
},
(props) =>
- [props.line.left?.type, props.line.right?.type, props.isHighlighted, props.isCommented].join(
- ':',
- ),
+ [
+ props.line.left?.type,
+ props.line.right?.type,
+ props.isHighlighted,
+ props.isCommented,
+ props.isFirstHighlightedLine,
+ props.isLastHighlightedLine,
+ ].join(':'),
),
coverageStateLeft: memoize(
(props) => {
@@ -118,20 +139,40 @@ export default {
classNameMapCellLeft: memoize(
(props) => {
return utils.classNameMapCell({
- line: props.line.left,
- hll: props.isHighlighted || props.isCommented,
+ line: props.line?.left,
+ highlighted: props.isHighlighted,
+ commented: props.isCommented,
+ selectionStart: props.isFirstHighlightedLine,
+ selectionEnd: props.isLastHighlightedLine,
});
},
- (props) => [props.line.left.type, props.isHighlighted, props.isCommented].join(':'),
+ (props) =>
+ [
+ props.line?.left?.type,
+ props.isHighlighted,
+ props.isCommented,
+ props.isFirstHighlightedLine,
+ props.isLastHighlightedLine,
+ ].join(':'),
),
classNameMapCellRight: memoize(
(props) => {
return utils.classNameMapCell({
- line: props.line.right,
- hll: props.isHighlighted || props.isCommented,
+ line: props.line?.right,
+ highlighted: props.isHighlighted,
+ commented: props.isCommented,
+ selectionStart: props.isFirstHighlightedLine,
+ selectionEnd: props.isLastHighlightedLine,
});
},
- (props) => [props.line.right.type, props.isHighlighted, props.isCommented].join(':'),
+ (props) =>
+ [
+ props.line?.right?.type,
+ props.isHighlighted,
+ props.isCommented,
+ props.isFirstHighlightedLine,
+ props.isLastHighlightedLine,
+ ].join(':'),
),
shouldRenderCommentButton: memoize(
(props) => {
@@ -303,15 +344,24 @@ export default {
!props.inline || (props.line.left && props.line.left.type === $options.CONFLICT_MARKER)
"
>
- <div data-testid="left-empty-cell" class="diff-td diff-line-num old_line empty-cell">
+ <div
+ data-testid="left-empty-cell"
+ class="diff-td diff-line-num old_line empty-cell"
+ :class="$options.classNameMapCellLeft(props)"
+ >
&nbsp;
</div>
- <div v-if="props.inline" class="diff-td diff-line-num old_line empty-cell"></div>
- <div class="diff-td line-coverage left-side empty-cell"></div>
- <div v-if="props.inline" class="diff-td line-codequality left-side empty-cell"></div>
+ <div
+ class="diff-td line-coverage left-side empty-cell"
+ :class="$options.classNameMapCellLeft(props)"
+ ></div>
+ <div
+ class="diff-td line-codequality left-side empty-cell"
+ :class="$options.classNameMapCellLeft(props)"
+ ></div>
<div
class="diff-td line_content with-coverage left-side empty-cell"
- :class="[{ parallel: !props.inline }]"
+ :class="[{ parallel: !props.inline }, ...$options.classNameMapCellLeft(props)]"
></div>
</template>
</div>
@@ -390,13 +440,13 @@ export default {
:class="[
props.line.right.type,
$options.coverageStateRight(props).class,
- { hll: props.isHighlighted, hll: props.isCommented },
+ ...$options.classNameMapCellRight(props),
]"
class="diff-td line-coverage right-side has-tooltip"
></div>
<div
class="diff-td line-codequality right-side"
- :class="[props.line.right.type, { hll: props.isHighlighted, hll: props.isCommented }]"
+ :class="$options.classNameMapCellRight(props)"
>
<component
:is="$options.CodeQualityGutterIcon"
@@ -414,10 +464,9 @@ export default {
:class="[
props.line.right.type,
{
- hll: props.isHighlighted,
- hll: props.isCommented,
'gl-font-weight-bold': props.line.right.type === $options.CONFLICT_MARKER_THEIR,
},
+ ...$options.classNameMapCellRight(props),
]"
class="diff-td line_content with-coverage right-side parallel"
v-html="
@@ -426,10 +475,23 @@ export default {
></div>
</template>
<template v-else>
- <div data-testid="right-empty-cell" class="diff-td diff-line-num old_line empty-cell"></div>
- <div class="diff-td line-coverage right-side empty-cell"></div>
- <div class="diff-td line-codequality right-side empty-cell"></div>
- <div class="diff-td line_content with-coverage right-side empty-cell parallel"></div>
+ <div
+ data-testid="right-empty-cell"
+ class="diff-td diff-line-num old_line empty-cell"
+ :class="$options.classNameMapCellRight(props)"
+ ></div>
+ <div
+ class="diff-td line-coverage right-side empty-cell"
+ :class="$options.classNameMapCellRight(props)"
+ ></div>
+ <div
+ class="diff-td line-codequality right-side empty-cell"
+ :class="$options.classNameMapCellRight(props)"
+ ></div>
+ <div
+ class="diff-td line_content with-coverage right-side empty-cell parallel"
+ :class="$options.classNameMapCellRight(props)"
+ ></div>
</template>
</div>
</div>
diff --git a/app/assets/javascripts/diffs/components/diff_row_utils.js b/app/assets/javascripts/diffs/components/diff_row_utils.js
index 479853caae3..a489c96b0c9 100644
--- a/app/assets/javascripts/diffs/components/diff_row_utils.js
+++ b/app/assets/javascripts/diffs/components/diff_row_utils.js
@@ -40,19 +40,33 @@ export const lineCode = (line) => {
return line.line_code || line.left?.line_code || line.right?.line_code;
};
-export const classNameMapCell = ({ line, hll, isLoggedIn, isHover }) => {
- if (!line) return [];
- const { type } = line;
+export const classNameMapCell = ({
+ line,
+ highlighted,
+ commented,
+ selectionStart,
+ selectionEnd,
+ isLoggedIn,
+ isHover,
+}) => {
+ const classes = {
+ 'highlight-top': highlighted || selectionStart,
+ 'highlight-bottom': highlighted || selectionEnd,
+ hll: highlighted,
+ commented,
+ };
- return [
- type,
- {
- hll,
+ if (line) {
+ const { type } = line;
+ Object.assign(classes, {
+ [type]: true,
[LINE_HOVER_CLASS_NAME]: isLoggedIn && isHover && !isContextLine(type) && !isMetaLine(type),
- old_line: line.type === 'old',
- new_line: line.type === 'new',
- },
- ];
+ old_line: type === 'old',
+ new_line: type === 'new',
+ });
+ }
+
+ return [classes];
};
export const addCommentTooltip = (line) => {
@@ -88,14 +102,28 @@ export const addCommentTooltip = (line) => {
return tooltip;
};
-export const parallelViewLeftLineType = (line, hll) => {
+export const parallelViewLeftLineType = ({
+ line,
+ highlighted,
+ commented,
+ selectionStart,
+ selectionEnd,
+}) => {
if (line?.right?.type === NEW_NO_NEW_LINE_TYPE) {
return OLD_NO_NEW_LINE_TYPE;
}
const lineTypeClass = line?.left ? line.left.type : EMPTY_CELL_TYPE;
- return [lineTypeClass, { hll }];
+ return [
+ lineTypeClass,
+ {
+ hll: highlighted,
+ commented,
+ 'highlight-top': highlighted || selectionStart,
+ 'highlight-bottom': highlighted || selectionEnd,
+ },
+ ];
};
export const shouldShowCommentButton = (hover, context, meta, discussions) => {
diff --git a/app/assets/javascripts/diffs/components/diff_view.vue b/app/assets/javascripts/diffs/components/diff_view.vue
index aa9a17d18e3..a2e052e0f93 100644
--- a/app/assets/javascripts/diffs/components/diff_view.vue
+++ b/app/assets/javascripts/diffs/components/diff_view.vue
@@ -59,7 +59,12 @@ export default {
},
computed: {
...mapGetters('diffs', ['commitId', 'fileLineCoverage']),
- ...mapState('diffs', ['codequalityDiff', 'highlightedRow', 'coverageLoaded']),
+ ...mapState('diffs', [
+ 'codequalityDiff',
+ 'highlightedRow',
+ 'coverageLoaded',
+ 'selectedCommentPosition',
+ ]),
...mapState({
selectedCommentPosition: ({ notes }) => notes.selectedCommentPosition,
selectedCommentPositionHover: ({ notes }) => notes.selectedCommentPositionHover,
@@ -144,6 +149,14 @@ export default {
false,
);
},
+ isFirstHighlightedLine(line) {
+ const lineCode = line.left?.line_code || line.right?.line_code;
+ return lineCode && lineCode === this.selectedCommentPosition?.start.line_code;
+ },
+ isLastHighlightedLine(line) {
+ const lineCode = line.left?.line_code || line.right?.line_code;
+ return lineCode && lineCode === this.selectedCommentPosition?.end.line_code;
+ },
handleParallelLineMouseDown(e) {
const line = e.target.closest('.diff-td');
if (line) {
@@ -230,10 +243,14 @@ export default {
:line="line"
:is-bottom="index + 1 === diffLinesLength"
:is-commented="index >= commentedLines.startLine && index <= commentedLines.endLine"
+ :is-highlighted="isHighlighted(line)"
+ :is-first-highlighted-line="
+ isFirstHighlightedLine(line) || index === commentedLines.startLine
+ "
+ :is-last-highlighted-line="isLastHighlightedLine(line) || index === commentedLines.endLine"
:inline="inline"
:index="index"
:code-quality-expanded="codeQualityExpandedLines.includes(getCodeQualityLine(line))"
- :is-highlighted="isHighlighted(line)"
:file-line-coverage="fileLineCoverage"
:coverage-loaded="coverageLoaded"
@showCommentForm="(code) => singleLineComment(code, line)"
diff --git a/app/assets/javascripts/gpg_badges.js b/app/assets/javascripts/gpg_badges.js
index 0a4733de65f..ad339155a59 100644
--- a/app/assets/javascripts/gpg_badges.js
+++ b/app/assets/javascripts/gpg_badges.js
@@ -13,7 +13,7 @@ export default class GpgBadges {
return Promise.resolve();
}
- const badges = $('.js-loading-gpg-badge');
+ const badges = $('.js-loading-signature-badge');
badges.html(loadingIconForLegacyJS());
badges.children().attr('aria-label', __('Loading'));
diff --git a/app/assets/javascripts/issuable/components/issuable_by_email.vue b/app/assets/javascripts/issuable/components/issuable_by_email.vue
index fcebae3af71..71ec5544c34 100644
--- a/app/assets/javascripts/issuable/components/issuable_by_email.vue
+++ b/app/assets/javascripts/issuable/components/issuable_by_email.vue
@@ -9,6 +9,7 @@ import {
GlFormInputGroup,
GlIcon,
} from '@gitlab/ui';
+import { TYPE_ISSUE } from '~/issues/constants';
import axios from '~/lib/utils/axios_utils';
import { sprintf, __ } from '~/locale';
import ModalCopyButton from '~/vue_shared/components/modal_copy_button.vue';
@@ -36,7 +37,7 @@ export default {
default: null,
},
issuableType: {
- default: 'issue',
+ default: TYPE_ISSUE,
},
emailsHelpPagePath: {
default: '',
@@ -54,7 +55,7 @@ export default {
data() {
return {
email: this.initialEmail,
- issuableName: this.issuableType === 'issue' ? __('issue') : __('merge request'),
+ issuableName: this.issuableType === TYPE_ISSUE ? __('issue') : __('merge request'),
};
},
computed: {
diff --git a/app/assets/javascripts/issues/show/components/fields/type.vue b/app/assets/javascripts/issues/show/components/fields/type.vue
index c5064f46e97..5ade1a86d30 100644
--- a/app/assets/javascripts/issues/show/components/fields/type.vue
+++ b/app/assets/javascripts/issues/show/components/fields/type.vue
@@ -1,5 +1,6 @@
<script>
import { GlFormGroup, GlIcon, GlListbox } from '@gitlab/ui';
+import { TYPE_ISSUE } from '~/issues/constants';
import { __ } from '~/locale';
import { issuableTypes, INCIDENT_TYPE } from '../../constants';
import getIssueStateQuery from '../../queries/get_issue_state.query.graphql';
@@ -22,7 +23,7 @@ export default {
default: false,
},
issueType: {
- default: 'issue',
+ default: TYPE_ISSUE,
},
},
data() {
diff --git a/app/assets/javascripts/notes/components/note_actions.vue b/app/assets/javascripts/notes/components/note_actions.vue
index ecf06401ccd..abed95a9706 100644
--- a/app/assets/javascripts/notes/components/note_actions.vue
+++ b/app/assets/javascripts/notes/components/note_actions.vue
@@ -4,6 +4,7 @@ import { mapActions, mapGetters, mapState } from 'vuex';
import Api from '~/api';
import resolvedStatusMixin from '~/batch_comments/mixins/resolved_status';
import { createAlert } from '~/flash';
+import { TYPE_ISSUE } from '~/issues/constants';
import { BV_HIDE_TOOLTIP } from '~/lib/utils/constants';
import { __, sprintf } from '~/locale';
import eventHub from '~/sidebar/event_hub';
@@ -173,7 +174,7 @@ export default {
return this.getNoteableData.assignees || [];
},
isIssue() {
- return this.targetType === 'issue';
+ return this.targetType === TYPE_ISSUE;
},
canAssign() {
return this.getNoteableData.current_user?.can_set_issue_metadata && this.isIssue;
@@ -235,7 +236,7 @@ export default {
assignees.push({ id: this.author.id });
}
- if (this.targetType === 'issue') {
+ if (this.targetType === TYPE_ISSUE) {
Api.updateIssue(project_id, iid, {
assignee_ids: assignees.map((assignee) => assignee.id),
})
diff --git a/app/assets/javascripts/notes/stores/actions.js b/app/assets/javascripts/notes/stores/actions.js
index c37fbdacae2..f6b9be6ee9b 100644
--- a/app/assets/javascripts/notes/stores/actions.js
+++ b/app/assets/javascripts/notes/stores/actions.js
@@ -4,6 +4,7 @@ import Vue from 'vue';
import Api from '~/api';
import { createAlert, VARIANT_INFO } from '~/flash';
import { EVENT_ISSUABLE_VUE_APP_CHANGE } from '~/issuable/constants';
+import { TYPE_ISSUE } from '~/issues/constants';
import axios from '~/lib/utils/axios_utils';
import { __, sprintf } from '~/locale';
import toast from '~/vue_shared/plugins/global_toast';
@@ -37,7 +38,8 @@ export const updateLockedAttribute = ({ commit, getters }, { locked, fullPath })
return utils.gqClient
.mutate({
- mutation: targetType === 'issue' ? updateIssueLockMutation : updateMergeRequestLockMutation,
+ mutation:
+ targetType === TYPE_ISSUE ? updateIssueLockMutation : updateMergeRequestLockMutation,
variables: {
input: {
projectPath: fullPath,
@@ -48,7 +50,7 @@ export const updateLockedAttribute = ({ commit, getters }, { locked, fullPath })
})
.then(({ data }) => {
const discussionLocked =
- targetType === 'issue'
+ targetType === TYPE_ISSUE
? data.issueSetLocked.issue.discussionLocked
: data.mergeRequestSetLocked.mergeRequest.discussionLocked;
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 11de734f5d4..7387b9ab87c 100644
--- a/app/assets/javascripts/related_issues/components/related_issues_list.vue
+++ b/app/assets/javascripts/related_issues/components/related_issues_list.vue
@@ -2,6 +2,7 @@
import { GlLoadingIcon } from '@gitlab/ui';
import Sortable from 'sortablejs';
import RelatedIssuableItem from '~/issuable/components/related_issuable_item.vue';
+import { TYPE_ISSUE } from '~/issues/constants';
import { defaultSortableOptions } from '~/sortable/constants';
export default {
@@ -88,7 +89,7 @@ export default {
document.body.classList.remove('is-dragging');
},
issuableOrderingId({ epicIssueId, id }) {
- return this.issuableType === 'issue' ? epicIssueId : id;
+ return this.issuableType === TYPE_ISSUE ? epicIssueId : id;
},
},
};
diff --git a/app/assets/javascripts/related_issues/index.js b/app/assets/javascripts/related_issues/index.js
index c42ee27fbdf..cc00ef10dda 100644
--- a/app/assets/javascripts/related_issues/index.js
+++ b/app/assets/javascripts/related_issues/index.js
@@ -1,9 +1,10 @@
import Vue from 'vue';
+import { TYPE_ISSUE } from '~/issues/constants';
import { apolloProvider } from '~/graphql_shared/issuable_client';
import { parseBoolean } from '~/lib/utils/common_utils';
import RelatedIssuesRoot from './components/related_issues_root.vue';
-export function initRelatedIssues(issueType = 'issue') {
+export function initRelatedIssues(issueType = TYPE_ISSUE) {
const el = document.querySelector('.js-related-issues-root');
if (!el) {
diff --git a/app/assets/javascripts/repository/components/preview/index.vue b/app/assets/javascripts/repository/components/preview/index.vue
index 8feac6b8e35..90949536cc1 100644
--- a/app/assets/javascripts/repository/components/preview/index.vue
+++ b/app/assets/javascripts/repository/components/preview/index.vue
@@ -14,7 +14,6 @@ export default {
url: this.blob.webPath,
};
},
- loadingKey: 'loading',
},
},
components: {
@@ -34,9 +33,13 @@ export default {
data() {
return {
readme: null,
- loading: 0,
};
},
+ computed: {
+ isLoading() {
+ return this.$apollo.queries.readme.loading;
+ },
+ },
watch: {
readme(newVal) {
if (newVal) {
@@ -64,7 +67,7 @@ export default {
</div>
</div>
<div class="blob-viewer" data-qa-selector="blob_viewer_content" itemprop="about">
- <gl-loading-icon v-if="loading > 0" size="lg" color="dark" class="my-4 mx-auto" />
+ <gl-loading-icon v-if="isLoading" size="lg" color="dark" class="my-4 mx-auto" />
<div
v-else-if="readme"
ref="readme"
diff --git a/app/assets/javascripts/sidebar/components/assignees/assignee_avatar.vue b/app/assets/javascripts/sidebar/components/assignees/assignee_avatar.vue
index 240e12ee597..323f6f23df6 100644
--- a/app/assets/javascripts/sidebar/components/assignees/assignee_avatar.vue
+++ b/app/assets/javascripts/sidebar/components/assignees/assignee_avatar.vue
@@ -1,6 +1,6 @@
<script>
import { GlIcon } from '@gitlab/ui';
-import { IssuableType } from '~/issues/constants';
+import { IssuableType, TYPE_ISSUE } from '~/issues/constants';
import { __, sprintf } from '~/locale';
export default {
@@ -19,7 +19,7 @@ export default {
issuableType: {
type: String,
required: false,
- default: 'issue',
+ default: TYPE_ISSUE,
},
},
computed: {
diff --git a/app/assets/javascripts/sidebar/components/assignees/assignee_avatar_link.vue b/app/assets/javascripts/sidebar/components/assignees/assignee_avatar_link.vue
index d17c8a123d5..73cd0044c16 100644
--- a/app/assets/javascripts/sidebar/components/assignees/assignee_avatar_link.vue
+++ b/app/assets/javascripts/sidebar/components/assignees/assignee_avatar_link.vue
@@ -1,6 +1,6 @@
<script>
import { GlTooltipDirective, GlLink } from '@gitlab/ui';
-import { IssuableType } from '~/issues/constants';
+import { IssuableType, TYPE_ISSUE } from '~/issues/constants';
import { isGid, getIdFromGraphQLId } from '~/graphql_shared/utils';
import { __ } from '~/locale';
import { isUserBusy } from '~/set_status_modal/utils';
@@ -67,7 +67,7 @@ export default {
},
issuableType: {
type: String,
- default: 'issue',
+ default: TYPE_ISSUE,
required: false,
},
},
diff --git a/app/assets/javascripts/sidebar/components/assignees/assignees.vue b/app/assets/javascripts/sidebar/components/assignees/assignees.vue
index cf07752a0b8..5cdebee04ad 100644
--- a/app/assets/javascripts/sidebar/components/assignees/assignees.vue
+++ b/app/assets/javascripts/sidebar/components/assignees/assignees.vue
@@ -1,4 +1,5 @@
<script>
+import { TYPE_ISSUE } from '~/issues/constants';
import CollapsedAssigneeList from './collapsed_assignee_list.vue';
import UncollapsedAssigneeList from './uncollapsed_assignee_list.vue';
@@ -22,7 +23,7 @@ export default {
issuableType: {
type: String,
required: false,
- default: 'issue',
+ default: TYPE_ISSUE,
},
},
computed: {
diff --git a/app/assets/javascripts/sidebar/components/assignees/collapsed_assignee.vue b/app/assets/javascripts/sidebar/components/assignees/collapsed_assignee.vue
index 46bda26c327..fab856883cc 100644
--- a/app/assets/javascripts/sidebar/components/assignees/collapsed_assignee.vue
+++ b/app/assets/javascripts/sidebar/components/assignees/collapsed_assignee.vue
@@ -1,4 +1,5 @@
<script>
+import { TYPE_ISSUE } from '~/issues/constants';
import AssigneeAvatar from './assignee_avatar.vue';
import UserNameWithStatus from './user_name_with_status.vue';
@@ -15,7 +16,7 @@ export default {
issuableType: {
type: String,
required: false,
- default: 'issue',
+ default: TYPE_ISSUE,
},
},
computed: {
diff --git a/app/assets/javascripts/sidebar/components/assignees/collapsed_assignee_list.vue b/app/assets/javascripts/sidebar/components/assignees/collapsed_assignee_list.vue
index f894ef0c42d..d2f0ceb19c9 100644
--- a/app/assets/javascripts/sidebar/components/assignees/collapsed_assignee_list.vue
+++ b/app/assets/javascripts/sidebar/components/assignees/collapsed_assignee_list.vue
@@ -1,5 +1,6 @@
<script>
import { GlIcon, GlTooltipDirective } from '@gitlab/ui';
+import { TYPE_ISSUE } from '~/issues/constants';
import { __, sprintf } from '~/locale';
import { isUserBusy } from '~/set_status_modal/utils';
import CollapsedAssignee from './collapsed_assignee.vue';
@@ -41,7 +42,7 @@ export default {
issuableType: {
type: String,
required: false,
- default: 'issue',
+ default: TYPE_ISSUE,
},
},
computed: {
diff --git a/app/assets/javascripts/sidebar/components/assignees/issuable_assignees.vue b/app/assets/javascripts/sidebar/components/assignees/issuable_assignees.vue
index fd51cd5bb16..ed29ccb3447 100644
--- a/app/assets/javascripts/sidebar/components/assignees/issuable_assignees.vue
+++ b/app/assets/javascripts/sidebar/components/assignees/issuable_assignees.vue
@@ -1,5 +1,6 @@
<script>
import { GlButton } from '@gitlab/ui';
+import { TYPE_ISSUE } from '~/issues/constants';
import { n__ } from '~/locale';
import UncollapsedAssigneeList from './uncollapsed_assignee_list.vue';
@@ -16,7 +17,7 @@ export default {
issuableType: {
type: String,
required: false,
- default: 'issue',
+ default: TYPE_ISSUE,
},
signedIn: {
type: Boolean,
diff --git a/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees.vue b/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees.vue
index 7979f450fdd..caf3bb2f798 100644
--- a/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees.vue
+++ b/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees.vue
@@ -1,6 +1,7 @@
<script>
import { refreshUserMergeRequestCounts } from '~/commons/nav/user_merge_requests';
import { createAlert } from '~/flash';
+import { TYPE_ISSUE } from '~/issues/constants';
import { __ } from '~/locale';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import eventHub from '../../event_hub';
@@ -34,7 +35,7 @@ export default {
issuableType: {
type: String,
required: false,
- default: 'issue',
+ default: TYPE_ISSUE,
},
issuableIid: {
type: String,
@@ -63,7 +64,7 @@ export default {
computed: {
shouldEnableRealtime() {
// Note: Realtime is only available on issues right now, future support for MR wil be built later.
- return this.issuableType === 'issue';
+ return this.issuableType === TYPE_ISSUE;
},
queryVariables() {
return {
diff --git a/app/assets/javascripts/sidebar/components/assignees/uncollapsed_assignee_list.vue b/app/assets/javascripts/sidebar/components/assignees/uncollapsed_assignee_list.vue
index d83ae782e26..71f349bb87e 100644
--- a/app/assets/javascripts/sidebar/components/assignees/uncollapsed_assignee_list.vue
+++ b/app/assets/javascripts/sidebar/components/assignees/uncollapsed_assignee_list.vue
@@ -1,6 +1,6 @@
<script>
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
-import { IssuableType } from '~/issues/constants';
+import { IssuableType, TYPE_ISSUE } from '~/issues/constants';
import { __, sprintf } from '~/locale';
import AssigneeAvatarLink from './assignee_avatar_link.vue';
import UserNameWithStatus from './user_name_with_status.vue';
@@ -21,7 +21,7 @@ export default {
issuableType: {
type: String,
required: false,
- default: 'issue',
+ default: TYPE_ISSUE,
},
},
data() {
diff --git a/app/assets/javascripts/sidebar/components/lock/issuable_lock_form.vue b/app/assets/javascripts/sidebar/components/lock/issuable_lock_form.vue
index cdce6617591..9d8f1304911 100644
--- a/app/assets/javascripts/sidebar/components/lock/issuable_lock_form.vue
+++ b/app/assets/javascripts/sidebar/components/lock/issuable_lock_form.vue
@@ -1,6 +1,7 @@
<script>
import { GlIcon, GlTooltipDirective, GlOutsideDirective as Outside } from '@gitlab/ui';
import { mapGetters, mapActions } from 'vuex';
+import { TYPE_ISSUE } from '~/issues/constants';
import { __, sprintf } from '~/locale';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { createAlert } from '~/flash';
@@ -9,7 +10,6 @@ import eventHub from '../../event_hub';
import EditForm from './edit_form.vue';
export default {
- issue: 'issue',
locked: {
icon: 'lock',
class: 'value',
@@ -49,7 +49,7 @@ export default {
return this.getNoteableData.targetType === 'merge_request' && this.glFeatures.movedMrSidebar;
},
issuableDisplayName() {
- const isInIssuePage = this.getNoteableData.targetType === this.$options.issue;
+ const isInIssuePage = this.getNoteableData.targetType === TYPE_ISSUE;
return isInIssuePage ? __('issue') : __('merge request');
},
isLocked() {
diff --git a/app/assets/javascripts/sidebar/components/reviewers/reviewer_avatar_link.vue b/app/assets/javascripts/sidebar/components/reviewers/reviewer_avatar_link.vue
index f69c027e201..56ac4c39e84 100644
--- a/app/assets/javascripts/sidebar/components/reviewers/reviewer_avatar_link.vue
+++ b/app/assets/javascripts/sidebar/components/reviewers/reviewer_avatar_link.vue
@@ -2,6 +2,7 @@
// NOTE! For the first iteration, we are simply copying the implementation of Assignees
// It will soon be overhauled in Issue https://gitlab.com/gitlab-org/gitlab/-/issues/233736
import { GlTooltipDirective, GlLink } from '@gitlab/ui';
+import { TYPE_ISSUE } from '~/issues/constants';
import { __, sprintf } from '~/locale';
import ReviewerAvatar from './reviewer_avatar.vue';
@@ -34,7 +35,7 @@ export default {
},
issuableType: {
type: String,
- default: 'issue',
+ default: TYPE_ISSUE,
required: false,
},
},
diff --git a/app/assets/javascripts/sidebar/components/reviewers/reviewers.vue b/app/assets/javascripts/sidebar/components/reviewers/reviewers.vue
index 7af8dcb4e3e..bd1d9fbff0c 100644
--- a/app/assets/javascripts/sidebar/components/reviewers/reviewers.vue
+++ b/app/assets/javascripts/sidebar/components/reviewers/reviewers.vue
@@ -1,6 +1,7 @@
<script>
// NOTE! For the first iteration, we are simply copying the implementation of Assignees
// It will soon be overhauled in Issue https://gitlab.com/gitlab-org/gitlab/-/issues/233736
+import { TYPE_ISSUE } from '~/issues/constants';
import CollapsedReviewerList from './collapsed_reviewer_list.vue';
import UncollapsedReviewerList from './uncollapsed_reviewer_list.vue';
@@ -28,7 +29,7 @@ export default {
issuableType: {
type: String,
required: false,
- default: 'issue',
+ default: TYPE_ISSUE,
},
},
computed: {
diff --git a/app/assets/javascripts/sidebar/components/reviewers/sidebar_reviewers.vue b/app/assets/javascripts/sidebar/components/reviewers/sidebar_reviewers.vue
index a5577d45f92..8dd58d33ecf 100644
--- a/app/assets/javascripts/sidebar/components/reviewers/sidebar_reviewers.vue
+++ b/app/assets/javascripts/sidebar/components/reviewers/sidebar_reviewers.vue
@@ -4,6 +4,7 @@
import Vue from 'vue';
import { refreshUserMergeRequestCounts } from '~/commons/nav/user_merge_requests';
import { createAlert } from '~/flash';
+import { TYPE_ISSUE } from '~/issues/constants';
import { __ } from '~/locale';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import eventHub from '../../event_hub';
@@ -37,7 +38,7 @@ export default {
issuableType: {
type: String,
required: false,
- default: 'issue',
+ default: TYPE_ISSUE,
},
issuableIid: {
type: String,
diff --git a/app/assets/javascripts/sidebar/components/reviewers/uncollapsed_reviewer_list.vue b/app/assets/javascripts/sidebar/components/reviewers/uncollapsed_reviewer_list.vue
index 217ca2e2548..a3710d9534e 100644
--- a/app/assets/javascripts/sidebar/components/reviewers/uncollapsed_reviewer_list.vue
+++ b/app/assets/javascripts/sidebar/components/reviewers/uncollapsed_reviewer_list.vue
@@ -1,5 +1,6 @@
<script>
import { GlButton, GlTooltipDirective, GlIcon } from '@gitlab/ui';
+import { TYPE_ISSUE } from '~/issues/constants';
import { __, sprintf, s__ } from '~/locale';
import ReviewerAvatarLink from './reviewer_avatar_link.vue';
@@ -30,7 +31,7 @@ export default {
issuableType: {
type: String,
required: false,
- default: 'issue',
+ default: TYPE_ISSUE,
},
},
data() {
diff --git a/app/assets/javascripts/sidebar/components/time_tracking/create_timelog_form.vue b/app/assets/javascripts/sidebar/components/time_tracking/create_timelog_form.vue
index abd84abef6e..964da3b6138 100644
--- a/app/assets/javascripts/sidebar/components/time_tracking/create_timelog_form.vue
+++ b/app/assets/javascripts/sidebar/components/time_tracking/create_timelog_form.vue
@@ -10,6 +10,7 @@ import {
GlSprintf,
} from '@gitlab/ui';
import { convertToGraphQLId } from '~/graphql_shared/utils';
+import { TYPE_ISSUE } from '~/issues/constants';
import { formatDate } from '~/lib/utils/datetime_utility';
import { TYPENAME_ISSUE, TYPENAME_MERGE_REQUEST } from '~/graphql_shared/constants';
import { joinPaths } from '~/lib/utils/url_utility';
@@ -127,7 +128,7 @@ export default {
});
},
isIssue() {
- return this.issuableType === 'issue';
+ return this.issuableType === TYPE_ISSUE;
},
getGraphQLEntityType() {
return this.isIssue() ? TYPENAME_ISSUE : TYPENAME_MERGE_REQUEST;
diff --git a/app/assets/javascripts/sidebar/components/time_tracking/report.vue b/app/assets/javascripts/sidebar/components/time_tracking/report.vue
index 12705baf33a..cffbb6466f2 100644
--- a/app/assets/javascripts/sidebar/components/time_tracking/report.vue
+++ b/app/assets/javascripts/sidebar/components/time_tracking/report.vue
@@ -3,6 +3,7 @@ import { GlLoadingIcon, GlTableLite, GlButton, GlTooltipDirective } from '@gitla
import { createAlert } from '~/flash';
import { TYPENAME_ISSUE, TYPENAME_MERGE_REQUEST } from '~/graphql_shared/constants';
import { convertToGraphQLId } from '~/graphql_shared/utils';
+import { TYPE_ISSUE } from '~/issues/constants';
import { formatDate, parseSeconds, stringifyTime } from '~/lib/utils/datetime_utility';
import { __, s__ } from '~/locale';
import { timelogQueries } from '../../constants';
@@ -61,7 +62,7 @@ export default {
return this.removingIds.includes(timelogId);
},
isIssue() {
- return this.issuableType === 'issue';
+ return this.issuableType === TYPE_ISSUE;
},
getQueryVariables() {
return {
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue b/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue
index 1e7dd639247..b78293a9815 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue
@@ -293,7 +293,7 @@ export default {
}
},
onClickedAction(action) {
- if (action.fullReport) {
+ if (action.trackFullReportClicked) {
this.telemetry?.fullReportClicked();
}
},
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/widget/widget.vue b/app/assets/javascripts/vue_merge_request_widget/components/widget/widget.vue
index 6003aa40c6d..73129a86877 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/widget/widget.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/widget/widget.vue
@@ -111,7 +111,7 @@ export default {
* "testId":string,
* "text": string,
* "class": string | Object,
- * "fullReport": boolean,
+ * "trackFullReportClicked": boolean,
* }
*/
actionButtons: {
@@ -204,7 +204,7 @@ export default {
},
methods: {
onActionClick(action) {
- if (action.fullReport) {
+ if (action.trackFullReportClicked) {
this.telemetryHub?.fullReportClicked();
}
},
diff --git a/app/assets/javascripts/vue_merge_request_widget/extensions/issues.js b/app/assets/javascripts/vue_merge_request_widget/extensions/issues.js
index ca95e1b5de8..ff225afbc7b 100644
--- a/app/assets/javascripts/vue_merge_request_widget/extensions/issues.js
+++ b/app/assets/javascripts/vue_merge_request_widget/extensions/issues.js
@@ -44,7 +44,12 @@ export default {
console.log('Hello world');
},
},
- { text: 'Full report', href: this.conflictsDocsPath, target: '_blank', fullReport: true },
+ {
+ text: 'Full report',
+ href: this.conflictsDocsPath,
+ target: '_blank',
+ trackFullReportClicked: true,
+ },
];
},
shouldCollapse() {
diff --git a/app/assets/javascripts/vue_merge_request_widget/extensions/terraform/index.js b/app/assets/javascripts/vue_merge_request_widget/extensions/terraform/index.js
index 626a99f7d64..c5cbed4a280 100644
--- a/app/assets/javascripts/vue_merge_request_widget/extensions/terraform/index.js
+++ b/app/assets/javascripts/vue_merge_request_widget/extensions/terraform/index.js
@@ -115,7 +115,7 @@ export default {
href: report.job_path,
text: this.$options.i18n.fullLog,
target: '_blank',
- fullReport: true,
+ trackFullReportClicked: true,
};
actions.push(action);
}
diff --git a/app/assets/javascripts/vue_merge_request_widget/extensions/test_report/index.js b/app/assets/javascripts/vue_merge_request_widget/extensions/test_report/index.js
index 7566e083f14..6ac462d4ad5 100644
--- a/app/assets/javascripts/vue_merge_request_widget/extensions/test_report/index.js
+++ b/app/assets/javascripts/vue_merge_request_widget/extensions/test_report/index.js
@@ -75,7 +75,7 @@ export default {
text: this.$options.i18n.fullReport,
href: `${this.pipeline.path}/test_report`,
target: '_blank',
- fullReport: true,
+ trackFullReportClicked: true,
testId: 'full-report-link',
});
diff --git a/app/assets/stylesheets/framework/diffs.scss b/app/assets/stylesheets/framework/diffs.scss
index f7cd5d7e183..4eb26d533c2 100644
--- a/app/assets/stylesheets/framework/diffs.scss
+++ b/app/assets/stylesheets/framework/diffs.scss
@@ -450,6 +450,16 @@
}
}
+.code .diff-grid-row.line_holder.diff-tr .diff-td.commented:not(.hll) {
+ --highlight-border-color: #{$blue-300};
+ background-color: $blue-50;
+
+ .gl-dark & {
+ --highlight-border-color: #{$blue-600};
+ background-color: $blue-900;
+ }
+}
+
.diff-table.code,
table.code {
width: 100%;
@@ -461,6 +471,21 @@ table.code {
table-layout: fixed;
border-radius: 0 0 $border-radius-default $border-radius-default;
+ .diff-td.highlight-top {
+ box-shadow: 0 -1px var(--highlight-border-color, $blue-300);
+ z-index: 1;
+ }
+
+ .diff-td.highlight-bottom {
+ box-shadow: 0 1px var(--highlight-border-color, $blue-300);
+ z-index: 1;
+ }
+
+ .diff-td.highlight-top.highlight-bottom {
+ box-shadow: 0 -1px var(--highlight-border-color, $blue-300), 0 1px var(--highlight-border-color, $blue-300);
+ z-index: 2;
+ }
+
.diff-tr.line_holder .diff-td,
tr.line_holder td {
line-height: $code-line-height;
@@ -485,13 +510,16 @@ table.code {
user-select: none;
margin: 0;
padding: 0 10px 0 5px;
- border-right-width: 1px;
- border-right-style: solid;
text-align: right;
width: 50px;
position: relative;
white-space: nowrap;
+ &:nth-of-type(2) {
+ border-right-width: 1px;
+ border-right-style: solid;
+ }
+
a {
transition: none;
float: left;
diff --git a/app/assets/stylesheets/highlight/common.scss b/app/assets/stylesheets/highlight/common.scss
index 96df8487c0e..085e25a0cdc 100644
--- a/app/assets/stylesheets/highlight/common.scss
+++ b/app/assets/stylesheets/highlight/common.scss
@@ -57,6 +57,15 @@
}
}
+@mixin line-number-hover-dark {
+ background-color: $purple-800;
+ border-color: $purple-300;
+
+ a {
+ color: $purple-50;
+ }
+}
+
@mixin conflict-colors($theme) {
.diff-line-num {
&.conflict_marker_our,
@@ -75,6 +84,8 @@
.line_holder {
.line_content,
.line-coverage {
+ position: relative;
+
&.conflict_marker_our {
background-color: map-get($conflict-colors, #{$theme}-header-head-neutral);
border-color: map-get($conflict-colors, #{$theme}-header-head-neutral);
diff --git a/app/assets/stylesheets/highlight/themes/dark.scss b/app/assets/stylesheets/highlight/themes/dark.scss
index 3438a73eff6..02469cf5165 100644
--- a/app/assets/stylesheets/highlight/themes/dark.scss
+++ b/app/assets/stylesheets/highlight/themes/dark.scss
@@ -131,7 +131,7 @@ $dark-il: #de935f;
@include hljs-override('title\\.class\\.inherited', $dark-no);
@include hljs-override('variable\\.constant', $dark-no);
@include hljs-override('title\\.function', $dark-nf);
-
+
// Line numbers
.file-line-num {
@@ -174,6 +174,11 @@ $dark-il: #de935f;
@include diff-expansion($gray-600, $gray-200, $gray-300, $white);
}
+ .diff-grid-row.line_holder.diff-tr .diff-td.commented:not(.hll) {
+ --highlight-border-color: #{$blue-600};
+ background-color: $blue-900;
+ }
+
// Diff line
.line_holder {
&.match .line_content,
@@ -188,15 +193,15 @@ $dark-il: #de935f;
@include dark-diff-expansion-line;
}
- .diff-td.diff-line-num.hll:not(.empty-cell),
- .diff-td.line-coverage.hll:not(.empty-cell),
- .diff-td.line-codequality.hll:not(.empty-cell),
- .diff-td.line_content.hll:not(.empty-cell),
- td.diff-line-num.hll:not(.empty-cell),
- td.line-coverage.hll:not(.empty-cell),
- td.line_content.hll:not(.empty-cell) {
- background-color: $dark-diff-not-empty-bg;
- border-color: darken($dark-diff-not-empty-bg, 15%);
+ .diff-td.diff-line-num.hll,
+ .diff-td.line-coverage.hll,
+ .diff-td.line-codequality.hll,
+ .diff-td.line_content.hll,
+ td.diff-line-num.hll,
+ td.line-coverage.hll,
+ td.line_content.hll {
+ --highlight-border-color: #{$orange-500};
+ background-color: $orange-800;
}
.line-coverage {
@@ -239,14 +244,14 @@ $dark-il: #de935f;
&:not(.match) .diff-grid-right:hover,
&.code-search-line:hover {
.diff-line-num:not(.empty-cell) {
- @include line-number-hover;
+ @include line-number-hover-dark;
}
}
.diff-line-num {
&.is-over,
&.hll:not(.empty-cell).is-over {
- @include line-number-hover;
+ @include line-number-hover-dark;
}
}
diff --git a/app/assets/stylesheets/highlight/themes/monokai.scss b/app/assets/stylesheets/highlight/themes/monokai.scss
index 02aa9ed6b16..30d04b4002e 100644
--- a/app/assets/stylesheets/highlight/themes/monokai.scss
+++ b/app/assets/stylesheets/highlight/themes/monokai.scss
@@ -148,6 +148,11 @@ $monokai-gh: #75715e;
color: $monokai-line-num-color;
}
+ .diff-grid-row.line_holder.diff-tr .diff-td.commented:not(.hll) {
+ --highlight-border-color: #{$blue-600};
+ background-color: $blue-900;
+ }
+
// Code itself
pre.code,
.diff-line-num {
@@ -179,15 +184,15 @@ $monokai-gh: #75715e;
@include dark-diff-expansion-line;
}
- .diff-td.diff-line-num.hll:not(.empty-cell),
- .diff-td.line-coverage.hll:not(.empty-cell),
- .diff-td.line-codequality.hll:not(.empty-cell),
- .diff-td.line_content.hll:not(.empty-cell),
- td.diff-line-num.hll:not(.empty-cell),
- td.line-coverage.hll:not(.empty-cell),
- td.line_content.hll:not(.empty-cell) {
- background-color: $monokai-line-empty-bg;
- border-color: $monokai-line-empty-border;
+ .diff-td.diff-line-num.hll,
+ .diff-td.line-coverage.hll,
+ .diff-td.line-codequality.hll,
+ .diff-td.line_content.hll,
+ td.diff-line-num.hll,
+ td.line-coverage.hll,
+ td.line_content.hll {
+ --highlight-border-color: #{$orange-500};
+ background-color: $orange-800;
}
.line-coverage {
@@ -230,14 +235,14 @@ $monokai-gh: #75715e;
&:not(.match) .diff-grid-right:hover,
&.code-search-line:hover {
.diff-line-num:not(.empty-cell) {
- @include line-number-hover;
+ @include line-number-hover-dark;
}
}
.diff-line-num {
&.is-over,
&.hll:not(.empty-cell).is-over {
- @include line-number-hover;
+ @include line-number-hover-dark;
}
}
diff --git a/app/assets/stylesheets/highlight/themes/none.scss b/app/assets/stylesheets/highlight/themes/none.scss
index fa1f7211b3e..8339d7eff80 100644
--- a/app/assets/stylesheets/highlight/themes/none.scss
+++ b/app/assets/stylesheets/highlight/themes/none.scss
@@ -55,7 +55,7 @@
&,
pre.code,
- .line_holder .line_content {
+ .line_holder .line_content:not(.hll) {
background-color: $white;
color: $gl-text-color;
}
@@ -84,8 +84,8 @@
@include line-coverage-border-color($green-500, $orange-500);
}
- .line-coverage,
- .line-codequality {
+ .line-coverage:not(.hll),
+ .line-codequality:not(.hll) {
&.old,
&.new,
&.new-nomappinginraw,
@@ -119,11 +119,6 @@
&.hll:not(.empty-cell).is-over {
@include line-number-hover;
}
-
- &.hll:not(.empty-cell) {
- background-color: $white;
- border-color: $white-normal;
- }
}
&:not(.diff-expanded) + .diff-expanded,
@@ -158,7 +153,7 @@
}
}
- &.new, &.new-nomappinginraw {
+ &.new:not(.hll), &.new-nomappinginraw:not(.hll) {
background-color: $white-normal;
&::before {
@@ -174,18 +169,9 @@
&.match {
@include match-line;
}
-
- &.hll:not(.empty-cell) {
- background-color: $white-normal;
- }
}
}
- // highlight line via anchor
- pre .hll {
- background-color: $white-normal;
- }
-
// Search result highlight
span.highlight_word {
background-color: $white-normal;
@@ -197,7 +183,10 @@
text-decoration: underline;
}
- .hll { background-color: $white; }
+ .hll {
+ --highlight-border-color: #{$orange-200};
+ background-color: $orange-50;
+ }
.gd {
color: $gl-text-color;
diff --git a/app/assets/stylesheets/highlight/themes/solarized-dark.scss b/app/assets/stylesheets/highlight/themes/solarized-dark.scss
index 18e18619c09..075510e6e5f 100644
--- a/app/assets/stylesheets/highlight/themes/solarized-dark.scss
+++ b/app/assets/stylesheets/highlight/themes/solarized-dark.scss
@@ -151,6 +151,11 @@ $solarized-dark-il: #2aa198;
color: $solarized-dark-line-color;
}
+ .diff-grid-row.line_holder.diff-tr .diff-td.commented:not(.hll) {
+ --highlight-border-color: #{$blue-600};
+ background-color: $blue-900;
+ }
+
// Code itself
pre.code,
.diff-line-num {
@@ -182,15 +187,15 @@ $solarized-dark-il: #2aa198;
@include dark-diff-expansion-line;
}
- .diff-td.diff-line-num.hll:not(.empty-cell),
- .diff-td.line-coverage.hll:not(.empty-cell),
- .diff-td.line-codequality.hll:not(.empty-cell),
- .diff-td.line_content.hll:not(.empty-cell),
- td.diff-line-num.hll:not(.empty-cell),
- td.line-coverage.hll:not(.empty-cell),
- td.line_content.hll:not(.empty-cell) {
- background-color: $solarized-dark-hll-bg;
- border-color: darken($solarized-dark-hll-bg, 15%);
+ .diff-td.diff-line-num.hll,
+ .diff-td.line-coverage.hll,
+ .diff-td.line-codequality.hll,
+ .diff-td.line_content.hll,
+ td.diff-line-num.hll,
+ td.line-coverage.hll,
+ td.line_content.hll {
+ --highlight-border-color: #{$orange-500};
+ background-color: $orange-800;
}
.line-coverage {
@@ -201,7 +206,7 @@ $solarized-dark-il: #2aa198;
&:not(.match) .diff-grid-right:hover,
&.code-search-line:hover {
.diff-line-num:not(.empty-cell) {
- @include line-number-hover;
+ @include line-number-hover-dark;
}
}
@@ -240,7 +245,7 @@ $solarized-dark-il: #2aa198;
.diff-line-num {
&.is-over,
&.hll:not(.empty-cell).is-over {
- @include line-number-hover;
+ @include line-number-hover-dark;
}
}
diff --git a/app/assets/stylesheets/highlight/themes/solarized-light.scss b/app/assets/stylesheets/highlight/themes/solarized-light.scss
index d2dea024408..4e244ed7420 100644
--- a/app/assets/stylesheets/highlight/themes/solarized-light.scss
+++ b/app/assets/stylesheets/highlight/themes/solarized-light.scss
@@ -116,7 +116,7 @@ $solarized-light-il: #2aa198;
@include hljs-override('variable\\.constant', $solarized-light-no);
@include hljs-override('variable\\.language', $solarized-light-nb);
@include hljs-override('params', $solarized-light-nb);
-
+
// Line numbers
.file-line-num {
@include line-link($black, 'link');
@@ -174,13 +174,13 @@ $solarized-light-il: #2aa198;
background-color: $solarized-light-matchline-bg;
}
- .diff-td.diff-line-num.hll:not(.empty-cell),
- .diff-td.line-coverage.hll:not(.empty-cell),
- .diff-td.line-codequality.hll:not(.empty-cell),
- .diff-td.line_content.hll:not(.empty-cell),
- td.diff-line-num.hll:not(.empty-cell),
- td.line-coverage.hll:not(.empty-cell),
- td.line_content.hll:not(.empty-cell) {
+ .diff-td.diff-line-num.hll,
+ .diff-td.line-coverage.hll,
+ .diff-td.line-codequality.hll,
+ .diff-td.line_content.hll,
+ td.diff-line-num.hll,
+ td.line-coverage.hll,
+ td.line_content.hll {
background-color: $solarized-light-hll-bg;
border-color: darken($solarized-light-hll-bg, 15%);
}
diff --git a/app/assets/stylesheets/highlight/themes/white.scss b/app/assets/stylesheets/highlight/themes/white.scss
index f6cce25671f..0a283254a4c 100644
--- a/app/assets/stylesheets/highlight/themes/white.scss
+++ b/app/assets/stylesheets/highlight/themes/white.scss
@@ -19,4 +19,4 @@
:root {
--default-diff-color-deletion: #eb919b;
--default-diff-color-addition: #a0f5b4;
-} \ No newline at end of file
+}
diff --git a/app/assets/stylesheets/highlight/white_base.scss b/app/assets/stylesheets/highlight/white_base.scss
index 816aa88cfde..ccb5d96e966 100644
--- a/app/assets/stylesheets/highlight/white_base.scss
+++ b/app/assets/stylesheets/highlight/white_base.scss
@@ -125,13 +125,13 @@ $white-gc-bg: #eaf2f5;
.diff-line-num,
.diff-line-num a {
- color: $black-transparent;
+ color: $gray-400;
}
// Code itself
pre.code,
.diff-line-num {
- border-color: $white-normal;
+ border-color: rgba(0, 0, 0, 0.1);
}
&,
@@ -173,7 +173,7 @@ pre.code,
background-color: $line-number-old;
a {
- color: scale-color($line-number-old, $red: -30%, $green: -30%, $blue: -30%);
+ color: scale-color($gray-300, $red: -30%, $green: -30%, $blue: -30%);
}
}
@@ -182,7 +182,7 @@ pre.code,
background-color: $line-number-new;
a {
- color: scale-color($line-number-new, $red: -30%, $green: -30%, $blue: -30%);
+ color: scale-color($gray-200, $red: -30%, $green: -30%, $blue: -30%);
}
}
@@ -191,9 +191,9 @@ pre.code,
@include line-number-hover;
}
- &.hll:not(.empty-cell) {
- background-color: $line-number-select;
- border-color: $line-select-yellow-dark;
+ &.hll {
+ --highlight-border-color: #{$orange-200};
+ background-color: $orange-50;
}
}
@@ -246,8 +246,9 @@ pre.code,
@include match-line;
}
- &.hll:not(.empty-cell) {
- background-color: $line-select-yellow;
+ &.hll {
+ --highlight-border-color: #{$orange-200};
+ background-color: $orange-50;
}
}
@@ -267,8 +268,9 @@ pre.code,
background-color: $line-added;
}
- &.hll:not(.empty-cell) {
- background-color: $line-select-yellow;
+ &.hll {
+ --highlight-border-color: #{$orange-200};
+ background-color: $orange-50;
}
}
}
diff --git a/app/assets/stylesheets/pages/commits.scss b/app/assets/stylesheets/pages/commits.scss
index dd24e3fcb5d..7d465dbcc04 100644
--- a/app/assets/stylesheets/pages/commits.scss
+++ b/app/assets/stylesheets/pages/commits.scss
@@ -266,24 +266,9 @@
}
}
-.gpg-status-box {
- padding: 2px 10px;
-
- &:empty {
- display: none;
- }
-
- &.valid {
- @include green-status-color;
- }
-
- &.invalid {
- @include status-color($gray-dark, color('gray'), $gray-darkest);
- border-color: $gray-darkest;
-
- &:not(span):hover {
- color: color('gray');
- }
+.signature-badge {
+ &:hover {
+ @include gl-text-decoration-none;
}
}
@@ -297,7 +282,7 @@
}
}
-.gpg-popover-status {
+.signature-popover {
display: flex;
align-items: center;
font-weight: $gl-font-weight-normal;
diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss
index c6fa1d50997..5d03281a30a 100644
--- a/app/assets/stylesheets/pages/notes.scss
+++ b/app/assets/stylesheets/pages/notes.scss
@@ -671,6 +671,7 @@ $system-note-svg-size: 1rem;
}
.discussion-reply-holder {
+ border-top: 0;
border-radius: 0 0 $border-radius-default $border-radius-default;
position: relative;
diff --git a/app/assets/stylesheets/startup/startup-dark.scss b/app/assets/stylesheets/startup/startup-dark.scss
index df81d9fbbd0..3b28025053b 100644
--- a/app/assets/stylesheets/startup/startup-dark.scss
+++ b/app/assets/stylesheets/startup/startup-dark.scss
@@ -1631,8 +1631,6 @@ svg.s16 {
--gray-200: #535158;
--gray-700: #bfbfc3;
--gray-900: #ececef;
- --green-100: #0d532a;
- --green-700: #91d4a8;
--gl-text-color: #ececef;
--border-color: #434248;
--white: #333238;
diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb
index 813e8d7f84d..9a88a8160b6 100644
--- a/app/controllers/projects/environments_controller.rb
+++ b/app/controllers/projects/environments_controller.rb
@@ -58,8 +58,7 @@ class Projects::EnvironmentsController < Projects::ApplicationController
render json: {
environments: serialize_environments(request, response, params[:nested]),
review_app: serialize_review_app,
- can_stop_stale_environments: Feature.enabled?(:stop_stale_environments, @project) &&
- can?(current_user, :stop_environment, @project),
+ can_stop_stale_environments: can?(current_user, :stop_environment, @project),
available_count: environments_count_by_state[:available],
stopped_count: environments_count_by_state[:stopped]
}
diff --git a/app/graphql/types/project_type.rb b/app/graphql/types/project_type.rb
index 33d711133d5..c105ab9814c 100644
--- a/app/graphql/types/project_type.rb
+++ b/app/graphql/types/project_type.rb
@@ -571,6 +571,16 @@ module Types
resolver: Resolvers::DataTransferResolver.project,
description: 'Data transfer data point for a specific period. This is mocked data under a development feature flag.'
+ field :visible_forks, Types::ProjectType.connection_type,
+ null: true,
+ alpha: { milestone: '15.10' },
+ description: "Visible forks of the project." do
+ argument :minimum_access_level,
+ type: ::Types::AccessLevelEnum,
+ required: false,
+ description: 'Minimum access level.'
+ end
+
def timelog_categories
object.project_namespace.timelog_categories if Feature.enabled?(:timelog_categories)
end
@@ -663,6 +673,14 @@ module Types
::Projects::RepositoryLanguagesService.new(project, current_user).execute
end
+ def visible_forks(minimum_access_level: nil)
+ if minimum_access_level.nil?
+ object.forks.public_or_visible_to_user(current_user)
+ else
+ object.forks.visible_to_user_and_access_level(current_user, minimum_access_level)
+ end
+ end
+
private
def project
diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb
index 53781364af7..f75d3657986 100644
--- a/app/helpers/commits_helper.rb
+++ b/app/helpers/commits_helper.rb
@@ -131,10 +131,6 @@ module CommitsHelper
}
end
- def commit_signature_badge_classes(additional_classes)
- %w(btn gpg-status-box) + Array(additional_classes)
- end
-
def conditionally_paginate_diff_files(diffs, paginate:, page:, per:)
if paginate
diff_files = diffs.diff_files.to_a
diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb
index 62023c6da74..46d2d2c42d9 100644
--- a/app/helpers/issuables_helper.rb
+++ b/app/helpers/issuables_helper.rb
@@ -6,7 +6,7 @@ module IssuablesHelper
include ::Sidebars::Concerns::HasPill
def sidebar_gutter_toggle_icon
- content_tag(:span, class: 'js-sidebar-toggle-container', data: { is_expanded: !sidebar_gutter_collapsed? }) do
+ content_tag(:span, class: 'js-sidebar-toggle-container gl-button-text', data: { is_expanded: !sidebar_gutter_collapsed? }) do
sprite_icon('chevron-double-lg-left', css_class: "js-sidebar-expand #{'hidden' unless sidebar_gutter_collapsed?}") +
sprite_icon('chevron-double-lg-right', css_class: "js-sidebar-collapse #{'hidden' if sidebar_gutter_collapsed?}")
end
diff --git a/app/models/concerns/noteable.rb b/app/models/concerns/noteable.rb
index 49c4bf46695..7addcf9e2ec 100644
--- a/app/models/concerns/noteable.rb
+++ b/app/models/concerns/noteable.rb
@@ -116,7 +116,9 @@ module Noteable
relations += synthetic_note_ids_relations
end
- Note.from_union(relations, remove_duplicates: false).fresh
+ Note.from_union(relations, remove_duplicates: false)
+ .select(:table_name, :id, :created_at, :ids)
+ .fresh
end
def capped_notes_count(max)
diff --git a/app/models/note.rb b/app/models/note.rb
index 1bc664936ab..a64f7311725 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -23,6 +23,9 @@ class Note < ApplicationRecord
include FromUnion
include Sortable
include EachBatch
+ include IgnorableColumns
+
+ ignore_column :id_convert_to_bigint, remove_with: '16.0', remove_after: '2023-05-22'
ISSUE_TASK_SYSTEM_NOTE_PATTERN = /\A.*marked\sthe\stask.+as\s(completed|incomplete).*\z/.freeze
diff --git a/app/views/projects/commit/_ajax_signature.html.haml b/app/views/projects/commit/_ajax_signature.html.haml
index e1bf0940f59..87ccf01c011 100644
--- a/app/views/projects/commit/_ajax_signature.html.haml
+++ b/app/views/projects/commit/_ajax_signature.html.haml
@@ -1,2 +1,2 @@
- if commit.has_signature?
- %button{ tabindex: 0, class: commit_signature_badge_classes('js-loading-gpg-badge'), data: { toggle: 'tooltip', placement: 'top', title: _('GPG signature (loading...)'), 'commit-sha' => commit.sha } }
+ %a.js-loading-signature-badge{ tabindex: 0, role: 'button', data: { toggle: 'tooltip', placement: 'top', title: _('GPG signature (loading...)'), 'commit-sha' => commit.sha } }
diff --git a/app/views/projects/commit/_multiple_signatures_signature_badge.html.haml b/app/views/projects/commit/_multiple_signatures_signature_badge.html.haml
index 2568a69cc2c..f80f194bd4d 100644
--- a/app/views/projects/commit/_multiple_signatures_signature_badge.html.haml
+++ b/app/views/projects/commit/_multiple_signatures_signature_badge.html.haml
@@ -1,5 +1,5 @@
- title = _('Multiple signatures')
- description = _('This commit was signed with multiple signatures.')
-- locals = { signature: signature, title: title, description: description, label: _('Unverified'), css_class: 'invalid' }
+- locals = { signature: signature, title: title, description: description, label: _('Unverified'), variant: 'muted' }
= render partial: 'projects/commit/signature_badge', locals: locals
diff --git a/app/views/projects/commit/_other_user_signature_badge.html.haml b/app/views/projects/commit/_other_user_signature_badge.html.haml
index ffc4b25dc21..345a1964259 100644
--- a/app/views/projects/commit/_other_user_signature_badge.html.haml
+++ b/app/views/projects/commit/_other_user_signature_badge.html.haml
@@ -1,5 +1,5 @@
- title = _("Different user's signature")
- description = _("This commit was signed with a different user's verified signature.")
-- locals = { signature: signature, title: title, description: description, label: _('Unverified'), css_class: 'invalid' }
+- locals = { signature: signature, title: title, description: description, label: _('Unverified'), variant: 'muted' }
= render partial: 'projects/commit/signature_badge', locals: locals
diff --git a/app/views/projects/commit/_revoked_key_signature_badge.html.haml b/app/views/projects/commit/_revoked_key_signature_badge.html.haml
index 2e0ca42561a..cbcc39249ce 100644
--- a/app/views/projects/commit/_revoked_key_signature_badge.html.haml
+++ b/app/views/projects/commit/_revoked_key_signature_badge.html.haml
@@ -1,5 +1,5 @@
- title = s_('CommitSignature|Unverified signature')
- description = s_('CommitSignature|This commit was signed with a key that was revoked.')
-- locals = { signature: signature, title: title, description: description, label: s_('CommitSignature|Unverified'), css_class: 'invalid' }
+- locals = { signature: signature, title: title, description: description, label: s_('CommitSignature|Unverified'), variant: 'muted' }
= render partial: 'projects/commit/signature_badge', locals: locals
diff --git a/app/views/projects/commit/_same_user_different_email_signature_badge.html.haml b/app/views/projects/commit/_same_user_different_email_signature_badge.html.haml
index 61fdf6fc87a..afce5c10065 100644
--- a/app/views/projects/commit/_same_user_different_email_signature_badge.html.haml
+++ b/app/views/projects/commit/_same_user_different_email_signature_badge.html.haml
@@ -1,5 +1,5 @@
- title = _('GPG key mismatch')
- description = _('This commit was signed with a verified signature, but the committer email is not associated with the GPG Key.')
-- locals = { signature: signature, title: title, description: description, label: _('Unverified'), css_class: ['invalid'] }
+- locals = { signature: signature, title: title, description: description, label: _('Unverified'), variant: 'muted' }
= render partial: 'projects/commit/signature_badge', locals: locals
diff --git a/app/views/projects/commit/_signature_badge.html.haml b/app/views/projects/commit/_signature_badge.html.haml
index 41ba581b9d9..88631f14e56 100644
--- a/app/views/projects/commit/_signature_badge.html.haml
+++ b/app/views/projects/commit/_signature_badge.html.haml
@@ -2,12 +2,10 @@
- title = local_assigns.fetch(:title)
- description = local_assigns.fetch(:description, nil)
- label = local_assigns.fetch(:label)
-- css_class = local_assigns.fetch(:css_class)
-
-- css_classes = commit_signature_badge_classes(css_class)
+- variant = local_assigns.fetch(:variant)
- title = capture do
- .gpg-popover-status
+ .signature-popover
%div
%strong
= title
@@ -31,5 +29,5 @@
= link_to(_('Learn about signing commits'), help_page_path('user/project/repository/gpg_signed_commits/index.md'), class: 'gl-link gl-display-block gl-mt-3')
-%a{ role: 'button', tabindex: 0, class: css_classes, data: { toggle: 'popover', html: 'true', placement: 'top', title: title, content: content } }
- = label
+%a.signature-badge.gl-display-flex{ role: 'button', tabindex: 0, data: { toggle: 'popover', html: 'true', placement: 'top', title: title, content: content } }
+ = gl_badge_tag label, variant: variant
diff --git a/app/views/projects/commit/_unverified_signature_badge.html.haml b/app/views/projects/commit/_unverified_signature_badge.html.haml
index 0eae8d5564d..62a27aea60e 100644
--- a/app/views/projects/commit/_unverified_signature_badge.html.haml
+++ b/app/views/projects/commit/_unverified_signature_badge.html.haml
@@ -1,5 +1,5 @@
- title = _('Unverified signature')
- description = _('This commit was signed with an unverified signature.')
-- locals = { signature: signature, title: title, description: description, label: _('Unverified'), css_class: 'invalid' }
+- locals = { signature: signature, title: title, description: description, label: _('Unverified'), variant: 'muted' }
= render partial: 'projects/commit/signature_badge', locals: locals
diff --git a/app/views/projects/commit/_verified_signature_badge.html.haml b/app/views/projects/commit/_verified_signature_badge.html.haml
index 417d816c711..dd5d0d7d6eb 100644
--- a/app/views/projects/commit/_verified_signature_badge.html.haml
+++ b/app/views/projects/commit/_verified_signature_badge.html.haml
@@ -1,5 +1,5 @@
- title = _('Verified commit')
- description = _('This commit was signed with a verified signature and the committer email was verified to belong to the same user.')
-- locals = { signature: signature, title: title, description: description, label: _('Verified'), css_class: 'valid' }
+- locals = { signature: signature, title: title, description: description, label: _('Verified'), variant: 'success' }
= render partial: 'projects/commit/signature_badge', locals: locals
diff --git a/app/views/projects/commit/x509/_unverified_signature_badge.html.haml b/app/views/projects/commit/x509/_unverified_signature_badge.html.haml
index 6204a6977c0..94b9abda69e 100644
--- a/app/views/projects/commit/x509/_unverified_signature_badge.html.haml
+++ b/app/views/projects/commit/x509/_unverified_signature_badge.html.haml
@@ -1,6 +1,6 @@
- title = capture do
= html_escape(_('This commit was signed with an %{strong_open}unverified%{strong_close} signature.')) % { strong_open: '<strong>'.html_safe, strong_close: '</strong>'.html_safe }
-- locals = { signature: signature, title: title, label: _('Unverified'), css_class: 'invalid', icon: 'status_notfound_borderless', show_user: true }
+- locals = { signature: signature, title: title, label: _('Unverified'), variant: 'muted', icon: 'status_notfound_borderless', show_user: true }
= render partial: 'projects/commit/signature_badge', locals: locals
diff --git a/app/views/projects/commit/x509/_verified_signature_badge.html.haml b/app/views/projects/commit/x509/_verified_signature_badge.html.haml
index 357ad467539..a10516d275a 100644
--- a/app/views/projects/commit/x509/_verified_signature_badge.html.haml
+++ b/app/views/projects/commit/x509/_verified_signature_badge.html.haml
@@ -1,6 +1,6 @@
- title = capture do
= html_escape(_('This commit was signed with a %{strong_open}verified%{strong_close} signature and the committer email is verified to belong to the same user.')) % { strong_open: '<strong>'.html_safe, strong_close: '</strong>'.html_safe }
-- locals = { signature: signature, title: title, label: _('Verified'), css_class: 'valid', icon: 'status_success_borderless', show_user: true }
+- locals = { signature: signature, title: title, label: _('Verified'), variant: 'success', icon: 'status_success_borderless', show_user: true }
= render partial: 'projects/commit/signature_badge', locals: locals
diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml
index be4a9291d95..f54354674e2 100644
--- a/app/views/shared/issuable/_sidebar.html.haml
+++ b/app/views/shared/issuable/_sidebar.html.haml
@@ -14,7 +14,7 @@
%aside.right-sidebar.js-right-sidebar.js-issuable-sidebar{ data: { signed: { in: signed_in }, issuable_type: issuable_type }, class: "#{sidebar_gutter_collapsed_class} #{'right-sidebar-merge-requests' if moved_sidebar_enabled}", 'aria-live' => 'polite', 'aria-label': issuable_type }
.issuable-sidebar{ class: "#{'is-merge-request' if moved_sidebar_enabled}" }
.issuable-sidebar-header{ class: "#{'gl-pb-2! gl-md-display-flex gl-justify-content-end gl-lg-display-none!' if moved_sidebar_enabled}" }
- %a.gutter-toggle.float-right.js-sidebar-toggle.has-tooltip{ role: "button", class: "#{'gl-display-block' if moved_sidebar_enabled}", href: "#", "aria-label" => _('Toggle sidebar'), title: sidebar_gutter_tooltip_text, data: { container: 'body', placement: 'left', boundary: 'viewport' } }
+ %button.btn.gl-button.gutter-toggle.float-right.js-sidebar-toggle.has-tooltip{ type: "reset", class: "gl-shadow-none! #{'gl-display-block' if moved_sidebar_enabled}", "aria-label" => _('Toggle sidebar'), title: sidebar_gutter_tooltip_text, data: { container: 'body', placement: 'left', boundary: 'viewport' } }
= sidebar_gutter_toggle_icon
- if signed_in && !moved_sidebar_enabled
.js-sidebar-todo-widget-root{ data: { project_path: issuable_sidebar[:project_full_path], iid: issuable_sidebar[:iid], id: issuable_sidebar[:id] } }
diff --git a/config/feature_flags/development/stop_stale_environments.yml b/config/feature_flags/development/stop_stale_environments.yml
deleted file mode 100644
index ea1484f0970..00000000000
--- a/config/feature_flags/development/stop_stale_environments.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: stop_stale_environments
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/108616
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/387820
-milestone: '15.8'
-type: development
-group: group::release
-default_enabled: false
diff --git a/db/migrate/20230131004948_initialize_conversion_of_notes_id_to_bigint.rb b/db/migrate/20230131004948_initialize_conversion_of_notes_id_to_bigint.rb
new file mode 100644
index 00000000000..a376ba50e87
--- /dev/null
+++ b/db/migrate/20230131004948_initialize_conversion_of_notes_id_to_bigint.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class InitializeConversionOfNotesIdToBigint < Gitlab::Database::Migration[2.1]
+ TABLE = :notes
+ COLUMNS = %i[id]
+
+ enable_lock_retries!
+
+ def up
+ initialize_conversion_of_integer_to_bigint(TABLE, COLUMNS)
+ end
+
+ def down
+ revert_initialize_conversion_of_integer_to_bigint(TABLE, COLUMNS)
+ end
+end
diff --git a/db/post_migrate/20230131005411_backfill_notes_id_for_bigint_conversion.rb b/db/post_migrate/20230131005411_backfill_notes_id_for_bigint_conversion.rb
new file mode 100644
index 00000000000..b0ccc14e947
--- /dev/null
+++ b/db/post_migrate/20230131005411_backfill_notes_id_for_bigint_conversion.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class BackfillNotesIdForBigintConversion < Gitlab::Database::Migration[2.1]
+ TABLE = :notes
+ COLUMNS = %i[id]
+
+ restrict_gitlab_migration gitlab_schema: :gitlab_main
+
+ def up
+ backfill_conversion_of_integer_to_bigint(TABLE, COLUMNS, sub_batch_size: 500)
+ end
+
+ def down
+ revert_backfill_conversion_of_integer_to_bigint(TABLE, COLUMNS)
+ end
+end
diff --git a/db/post_migrate/20230214122717_fix_partition_ids_for_ci_job_variables.rb b/db/post_migrate/20230214122717_fix_partition_ids_for_ci_job_variables.rb
new file mode 100644
index 00000000000..0a201c51467
--- /dev/null
+++ b/db/post_migrate/20230214122717_fix_partition_ids_for_ci_job_variables.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class FixPartitionIdsForCiJobVariables < Gitlab::Database::Migration[2.1]
+ disable_ddl_transaction!
+ restrict_gitlab_migration gitlab_schema: :gitlab_ci
+
+ BATCH_SIZE = 50
+
+ def up
+ return unless Gitlab.com?
+
+ define_batchable_model(:ci_job_variables)
+ .where(partition_id: 101)
+ .each_batch(of: BATCH_SIZE) do |batch|
+ batch.update_all(partition_id: 100)
+ sleep 0.1
+ end
+ end
+
+ def down
+ # no-op
+ end
+end
diff --git a/db/post_migrate/20230216054348_prepare_async_foreign_key_validation_for_ci_job_artifacts.rb b/db/post_migrate/20230216054348_prepare_async_foreign_key_validation_for_ci_job_artifacts.rb
new file mode 100644
index 00000000000..6d545361e10
--- /dev/null
+++ b/db/post_migrate/20230216054348_prepare_async_foreign_key_validation_for_ci_job_artifacts.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class PrepareAsyncForeignKeyValidationForCiJobArtifacts < Gitlab::Database::Migration[2.1]
+ TABLE_NAME = :ci_job_artifacts
+ COLUMN_NAMES = [:partition_id, :job_id]
+ FOREIGN_KEY_NAME = :fk_rails_c5137cb2c1_p
+
+ def up
+ prepare_async_foreign_key_validation(TABLE_NAME, COLUMN_NAMES, name: FOREIGN_KEY_NAME)
+ end
+
+ def down
+ unprepare_async_foreign_key_validation(TABLE_NAME, COLUMN_NAMES, name: FOREIGN_KEY_NAME)
+ end
+end
diff --git a/db/schema_migrations/20230131004948 b/db/schema_migrations/20230131004948
new file mode 100644
index 00000000000..843732944a4
--- /dev/null
+++ b/db/schema_migrations/20230131004948
@@ -0,0 +1 @@
+a72828f13fa31c30338ba1b833addbf7fd439e4ea2c51ded252db943826289d9 \ No newline at end of file
diff --git a/db/schema_migrations/20230131005411 b/db/schema_migrations/20230131005411
new file mode 100644
index 00000000000..31ba576c9c9
--- /dev/null
+++ b/db/schema_migrations/20230131005411
@@ -0,0 +1 @@
+21088bc90a263d5fd5e4cff9cfdea3b778dd98f9207ef6729acafadec40383b6 \ No newline at end of file
diff --git a/db/schema_migrations/20230214122717 b/db/schema_migrations/20230214122717
new file mode 100644
index 00000000000..6f69502caa3
--- /dev/null
+++ b/db/schema_migrations/20230214122717
@@ -0,0 +1 @@
+803a4aa4c28aecf498d2a70046850d8128327feb12fe1a42f1255cd08da7746e \ No newline at end of file
diff --git a/db/schema_migrations/20230216054348 b/db/schema_migrations/20230216054348
new file mode 100644
index 00000000000..c878ce97f9e
--- /dev/null
+++ b/db/schema_migrations/20230216054348
@@ -0,0 +1 @@
+d86d07d1a1f02b72cfa45ebe83088366d200af00c8ab77f3a287af8476d00f14 \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 48186e629b3..c277291e823 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -225,6 +225,15 @@ RETURN NULL;
END
$$;
+CREATE FUNCTION trigger_080e73845bfd() RETURNS trigger
+ LANGUAGE plpgsql
+ AS $$
+BEGIN
+ NEW."id_convert_to_bigint" := NEW."id";
+ RETURN NEW;
+END;
+$$;
+
CREATE FUNCTION trigger_0e214b8a14f2() RETURNS trigger
LANGUAGE plpgsql
AS $$
@@ -18657,7 +18666,8 @@ CREATE TABLE notes (
review_id bigint,
confidential boolean,
last_edited_at timestamp with time zone,
- internal boolean DEFAULT false NOT NULL
+ internal boolean DEFAULT false NOT NULL,
+ id_convert_to_bigint bigint DEFAULT 0 NOT NULL
);
CREATE SEQUENCE notes_id_seq
@@ -33737,6 +33747,8 @@ CREATE TRIGGER nullify_merge_request_metrics_build_data_on_update BEFORE UPDATE
CREATE TRIGGER projects_loose_fk_trigger AFTER DELETE ON projects REFERENCING OLD TABLE AS old_table FOR EACH STATEMENT EXECUTE FUNCTION insert_into_loose_foreign_keys_deleted_records();
+CREATE TRIGGER trigger_080e73845bfd BEFORE INSERT OR UPDATE ON notes FOR EACH ROW EXECUTE FUNCTION trigger_080e73845bfd();
+
CREATE TRIGGER trigger_0e214b8a14f2 BEFORE INSERT OR UPDATE ON vulnerability_user_mentions FOR EACH ROW EXECUTE FUNCTION trigger_0e214b8a14f2();
CREATE TRIGGER trigger_17c3a95ee58a BEFORE INSERT OR UPDATE ON commit_user_mentions FOR EACH ROW EXECUTE FUNCTION trigger_17c3a95ee58a();
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 5c66c98cb0c..7dc5b557d33 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -18976,6 +18976,26 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="projecttimelogsstarttime"></a>`startTime` | [`Time`](#time) | List timelogs within a time range where the logged time is equal to or after startTime. |
| <a id="projecttimelogsusername"></a>`username` | [`String`](#string) | List timelogs for a user. |
+##### `Project.visibleForks`
+
+Visible forks of the project.
+
+WARNING:
+**Introduced** in 15.10.
+This feature is in Alpha. It can be changed or removed at any time.
+
+Returns [`ProjectConnection`](#projectconnection).
+
+This field returns a [connection](#connections). It accepts the
+four standard [pagination arguments](#connection-pagination-arguments):
+`before: String`, `after: String`, `first: Int`, `last: Int`.
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="projectvisibleforksminimumaccesslevel"></a>`minimumAccessLevel` | [`AccessLevelEnum`](#accesslevelenum) | Minimum access level. |
+
##### `Project.vulnerabilities`
Vulnerabilities reported on the project.
diff --git a/doc/integration/partner_marketplace.md b/doc/integration/partner_marketplace.md
new file mode 100644
index 00000000000..a15457b5b0c
--- /dev/null
+++ b/doc/integration/partner_marketplace.md
@@ -0,0 +1,64 @@
+---
+stage: Fulfillment
+group: Commerce Integrations
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
+---
+
+# Marketplace partner integration guide
+
+GitLab supports automation for selected distribution marketplaces to process sales of GitLab products to authorized
+channel partners. Marketplace partners can use the GitLab Marketplace APIs to integrate their systems with GitLab to
+sell GitLab subscriptions on their site.
+
+This document's target audience is third-party developers for Marketplace partners.
+
+## How the Marketplace APIs work
+
+The Marketplace APIs are hosted in the [Customers Portal](https://customers.gitlab.com/). The Customers Portal allows
+individual customers to purchase and manage GitLab subscriptions and supports APIs for partners
+to make sales on behalf of their customers. The Customers Portal integrates with other GitLab services, including
+Zuora and Salesforce, to provide a task-oriented interface for users.
+
+The following example shows a typical purchase flow of request and response between the following components:
+
+- Customer
+- Marketplace partner system
+- Customers Portal
+- Zuora
+- Salesforce
+
+```mermaid
+sequenceDiagram
+ participant Customer
+ participant Marketplace partner system
+ participant Customers Portal
+ participant Zuora
+ participant Salesforce
+ Customer ->> Marketplace partner system: Place order to purchase GitLab subscription
+ Marketplace partner system ->> Customers Portal: Get OAuth token
+ Customers Portal ->> Marketplace partner system: Access token
+ Marketplace partner system ->> Customers Portal: Place order
+ Customers Portal ->> Zuora: Create Zuora subscription
+ Customers Portal ->> Salesforce: Create Salesforce objects
+ Zuora ->> Customers Portal: Success response with Zuora subscription data
+ Customers Portal ->> Marketplace partner system: Success response with order ID
+ Zuora ->> Customers Portal: Zuora callout event
+ Customers Portal ->> Customer: send license notification
+ Marketplace partner system ->> Customers Portal: Poll order status
+ Customers Portal ->> Marketplace partner system: Success response with order status
+```
+
+## Prerequisites
+
+Before a marketplace partner client can use the Marketplace API, GitLab must set up the following configurations for the client:
+
+1. Client credential. Marketplace APIs are secured with OAuth 2.0. A client credential is required to get the OAuth token.
+1. Invoice owner account in Zuora system. Required for invoice processing.
+1. Distributor account in Salesforce system.
+1. Trading partner account in Salesforce system.
+
+Interested GitLab Partners should contact their GitLab Partner Manager or email [`partnerorderops`](mailto:partnerorderops@gitlab.com).
+
+## Marketplace API Specification
+
+OpenAPI specs for the Marketplace APIs are available upon request. The specs will be made public before the end of Q1 2023.
diff --git a/doc/operations/img/copy-group-id.png b/doc/operations/img/copy-group-id.png
new file mode 100644
index 00000000000..7837f49c3e3
--- /dev/null
+++ b/doc/operations/img/copy-group-id.png
Binary files differ
diff --git a/doc/operations/img/create-gitlab-application.png b/doc/operations/img/create-gitlab-application.png
new file mode 100644
index 00000000000..430b830cdb2
--- /dev/null
+++ b/doc/operations/img/create-gitlab-application.png
Binary files differ
diff --git a/doc/operations/img/listing_groups.png b/doc/operations/img/listing_groups.png
new file mode 100644
index 00000000000..1094bf4ff28
--- /dev/null
+++ b/doc/operations/img/listing_groups.png
Binary files differ
diff --git a/doc/operations/quickstart-guide.md b/doc/operations/quickstart-guide.md
new file mode 100644
index 00000000000..91c5f25405c
--- /dev/null
+++ b/doc/operations/quickstart-guide.md
@@ -0,0 +1,229 @@
+---
+stage: Monitor
+group: Observability
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
+---
+
+# GitLab Observability Quickstart
+
+You can try GitLab Observability by [cloning or forking the project](https://gitlab.com/gitlab-org/opstrace/opstrace.git) and creating a local installation.
+
+## Prerequisites and dependencies
+
+To install GitLab Observability Platform (GOP), install and configure the following third-party dependencies. You can do this manually, or [automatically by using asdf](#install-dependencies-using-asdf):
+
+- [kind](https://kind.sigs.k8s.io/docs/user/quick-start/#installation) for creating a local Kubernetes cluster.
+- [Docker](https://docs.docker.com/install)
+ - [Docker Compose](https://docs.docker.com/compose/compose-v2/) is now part of the `docker` distribution.
+- [kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) for interacting with GitLab Observability.
+- [Telepresence](https://www.telepresence.io/) allows you to code and test microservices locally against a remote Kubernetes cluster.
+- [jq](https://stedolan.github.io/jq/download/) for some Makefile utilities.
+- [Go 1.19](https://go.dev/doc/install).
+
+The current versions of these dependencies are pinned in the `.tool-versions` file in the project.
+
+You can run the following commands to check the availability and versions of these dependencies on your machine:
+
+```shell
+kind --version
+docker --version
+kubectl version
+telepresence version
+jq --version
+go version
+```
+
+### Run GOP on macOS
+
+If you're running GOP on macOS, ensure you have enough resources dedicated to Docker Desktop. The recommended minimum is:
+
+- CPUs: 4+
+- Memory: 8 GB+
+- Swap: 1 GB+
+
+It's possible to run GOP with fewer resources, but this specification works.
+
+### Install dependencies using asdf
+
+If you install dependencies using [`asdf`](https://asdf-vm.com/#/core-manage-asdf), GOP manages them for you automatically.
+
+1. If you have not already done so, clone the `opstrace` repository into your preferred location:
+
+ ```shell
+ git clone https://gitlab.com/gitlab-org/opstrace/opstrace.git
+ ```
+
+1. Change into the project directory:
+
+ ```shell
+ cd opstrace
+ ```
+
+1. Optional. If you need to install `asdf`, run:
+
+ ```shell
+ make install-asdf
+ ```
+
+1. Install dependencies using `asdf`:
+
+ ```shell
+ make bootstrap
+ ```
+
+## Step 1: Create a local Kubernetes cluster with kind
+
+Make sure Docker Desktop is running. In the `opstrace` project you cloned, run the following command:
+
+```shell
+make kind
+```
+
+Wait a few minutes while kind creates your Kubernetes cluster. When it's finished, you should see the following message:
+
+```plaintext
+Traffic Manager installed successfully
+```
+
+Now deploy the scheduler by running the following command in the `opstrace` project:
+
+```shell
+make deploy
+```
+
+This takes around 1 minute.
+
+## Step 2: Create a GitLab application for authentication
+
+You must create a GitLab application to use for authentication.
+
+In the GitLab instance you'd like to connect with GOP, [create an OAuth application](../integration/oauth_provider.md).
+This application can be a user-owned, group-owned or instance-wide application.
+In production, you would create a trusted instance-wide application so that users are explicitly authorized without the consent screen.
+The following example shows how to configure the application.
+
+1. Select the API scope and enter `http://localhost/v1/auth/callback` as the redirect URI.
+
+1. Run the following command to create the secret that holds the authentication data:
+
+ ```shell
+ kubectl create secret generic \
+ --from-literal=gitlab_oauth_client_id=<gitlab_application_client_id> \
+ --from-literal=gitlab_oauth_client_secret=<gitlab_application_client_secret> \
+ --from-literal=internal_endpoint_token=<error_tracking_internal_endpoint_token> \
+ dev-secret
+ ```
+
+1. Replace `<gitlab_application_client_id>` and `<gitlab_application_client_secret>` with the values from the GitLab application you just created.
+Replace `<error_tracking_internal_endpoint_token>` with any string if you do not plan to use error tracking.
+
+You can also view [this MR on how to get the token to test error tracking](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91928).
+You must specify all the parameters when creating the secret.
+
+## Step 3: Create the cluster definition
+
+1. In your `opstrace` project, run the following command to create a `Cluster.yaml` manifest file:
+
+ ```shell
+ cat <<EOF > Cluster.yaml
+ apiVersion: opstrace.com/v1alpha1
+ kind: Cluster
+ metadata:
+ name: dev-cluster
+ spec:
+ target: kind
+ goui:
+ image: "registry.gitlab.com/gitlab-org/opstrace/opstrace-ui/ gitlab-observability-ui:c9fb6e70"
+ dns:
+ acmeEmail: ""
+ dns01Challenge: {}
+ externalDNSProvider: {}
+ gitlab:
+ groupAllowedAccess: '*'
+ groupAllowedSystemAccess: "6543"
+ instanceUrl: https://gitlab.com
+ authSecret:
+ name: dev-secret
+ EOF
+ ```
+
+1. Apply the file you just created with the following command:
+
+ ```shell
+ kubectl apply -f Cluster.yaml
+ ```
+
+1. Run the following command to wait for the cluster to be ready:
+
+ ```shell
+ kubectl wait --for=condition=ready cluster/dev-cluster --timeout=600s
+ ```
+
+After the previous command exits, the cluster is ready.
+
+## Step 4: Enable Observability on a GitLab namespace you own
+
+Go to a namespace you own in the connected GitLab instance and copy the Group ID below the group name.
+
+GOP can only be enabled for groups you own.
+To list all the groups that your user owns, go to the menu in upper left corner and select `Groups`->`View all Groups`. You then see the **Your groups** tab.
+
+In your browser, go to `http://localhost/-/{GroupID}`. For example, `http://localhost/-/14485840`.
+
+Follow the on-screen instructions to enable observability for the namespace.
+This can take a couple of minutes if it's the first time observability has been enabled for the root level namespace (GitLab.org in the previous example.)
+
+Once your namespace has been enabled and is ready, the page automatically redirects you to the GitLab Observability UI.
+
+## Step 5: Send traces to GOP
+
+[Follow this guide to send traces to your namespace and monitor them in the UI](https://gitlab.com/gitlab-org/opstrace/opstrace/-/blob/main/docs/guides/user/sending-traces-locally.md).
+
+## Step 6: Clean up your local GOP
+
+To tear down your locally running GOP instance, run the following command:
+
+```shell
+make destroy
+```
+
+## Known issues
+
+### Incorrect architecture for `kind/node` image
+
+If your machine has an Apple silicon (M1/M2) chip, you might encounter an architecture problem with the `kind/node` image when running the `make kind` command. For more details, see [issue 1802](https://gitlab.com/gitlab-org/opstrace/opstrace/-/issues/1802).
+
+To fix this problem, you first need to create a Dockerfile. Then build and deploy the image:
+
+1. Create a new Dockerfile (without a file extension) and paste the following commands:
+
+ ```Dockerfile
+ FROM --platform=arm64 kindest/node:v1.23.13
+ RUN arch
+ ```
+
+1. Save your Dockerfile, then build the image with the following command:
+
+ ```shell
+ docker build -t tempkind .
+ ```
+
+ Do not forget the period at the end.
+
+1. Create a cluster using your new image with the following command:
+
+ ```shell
+ kind create cluster --image tempkind
+ ```
+
+### scheduler-controller-manager pod cannot start due to ImagePullBackOff
+
+If while executing `make deploy` in step 1, the `scheduler-controller-manager` pod cannot start due to `ImagePullBackOff`, you must set the `CI_COMMIT_TAG` to a non-dirty state. By setting the commit tag to the latest commit, you ensure the Docker image can be pulled from the container registry.
+
+Run the following command to set the commit tag:
+
+```shell
+make kind
+export CI_COMMIT_TAG=0.2.0-e1206acf
+make deploy
+```
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index c8b63b58559..a811c9b16bb 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -34678,9 +34678,15 @@ msgstr ""
msgid "ProtectedEnvironments|Set which groups, access levels or users that are allowed to deploy to this environment"
msgstr ""
+msgid "ProtectedEnvironments|Unified approval rules have been removed from the settings UI"
+msgstr ""
+
msgid "ProtectedEnvironments|Users"
msgstr ""
+msgid "ProtectedEnvironments|You can still use the %{apiLinkStart}API%{apiLinkEnd} to configure unified approval rules. Consider using %{docsLinkStart}multiple approval rules%{docsLinkEnd} instead, because they provide greater flexibility."
+msgstr ""
+
msgid "ProtectedEnvironment|%{environment_name} will be writable for developers. Are you sure?"
msgstr ""
diff --git a/qa/gdk/Dockerfile b/qa/gdk/Dockerfile
new file mode 100644
index 00000000000..ed8f3f317eb
--- /dev/null
+++ b/qa/gdk/Dockerfile
@@ -0,0 +1,50 @@
+FROM registry.gitlab.com/gitlab-org/gitlab-development-kit/asdf-bootstrapped-gdk-installed-gitlab-e2e:ml-create-image-for-gitlab-qa-tests
+
+ENV CHROME_DRIVER_VERSION="107.0.5304.62"
+ENV CHROME_VERSION="107.0.5304.87-1"
+ENV CHROME_DEB="google-chrome-stable_${CHROME_VERSION}_amd64.deb"
+ENV CHROME_URL="https://gitlab.com/api/v4/projects/gitlab-org%2Fgitlab-build-images/packages/generic/google-chrome-stable/${CHROME_VERSION}/${CHROME_DEB}"
+
+WORKDIR /home/gdk/gdk
+
+COPY --chown=gdk qa/gdk/gdk.yml .
+
+RUN cat gdk.yml && \
+ gdk update && \
+ gdk restart && \
+ ./support/test_url http://gdk.test:3000 && \
+ gdk stop && sleep 5 && \
+ GDK_KILL_CONFIRM=true gdk kill && \
+ ps -ef && \
+ cd gitlab && git reset --hard && \
+ sudo rm -rf "$HOME/gdk/gitaly/_build/deps/git/source" \
+ "$HOME/gdk/gitaly/_build/deps/libgit2/source" \
+ "$HOME/gdk/gitaly/_build/cache" \
+ "$HOME/gdk/gitaly/_build/deps" \
+ "$HOME/gdk/gitaly/_build/intermediate" \
+ "$HOME/.cache/" \
+ "$HOME/gdk/gdk/gitlab" \
+ /tmp/*
+
+# Install Google Chrome version with headless support
+# Download from our local S3 bucket, populated by https://gitlab.com/gitlab-org/gitlab-build-images/-/blob/master/scripts/cache-google-chrome
+#
+RUN echo "${CHROME_URL}" && \
+ curl --silent --show-error --fail -O "${CHROME_URL}" && \
+ sudo apt update && \
+ sudo dpkg -i "./${CHROME_DEB}" || true && \
+ sudo apt install -f -y && \
+ rm -f "./${CHROME_DEB}"
+
+WORKDIR /home/gdk/gdk/gitlab
+
+RUN bundle install --jobs=$(nproc) --retry=3 --quiet
+RUN cd qa && \
+ bundle install --jobs=$(nproc) --retry=3 --quiet && \
+ bundle exec rake -f tasks/webdrivers.rake webdrivers:chromedriver:update[${CHROME_DRIVER_VERSION}]
+
+RUN git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
+
+COPY --chown=gdk qa/gdk/launch .
+
+ENTRYPOINT ["./launch"]
diff --git a/qa/gdk/gdk.yml b/qa/gdk/gdk.yml
new file mode 100644
index 00000000000..0494cd0d3c1
--- /dev/null
+++ b/qa/gdk/gdk.yml
@@ -0,0 +1,26 @@
+---
+hostname: gdk.test
+sshd:
+ additional_config: 'AcceptEnv GIT_PROTOCOL'
+webpack:
+ live_reload: false
+ sourcemaps: false
+ incremental: false
+gdk:
+ ask_to_restart_after_update: false
+ auto_reconfigure: false
+ overwrite_changes: true
+ quiet: false
+gitlab:
+ rails:
+ bootsnap: false
+ hostname: gdk.test
+gitlab_k8s_agent:
+ enabled: false
+gitlab_pages:
+ enabled: false
+prometheus:
+ enabled: false
+tracer:
+ jaeger:
+ enabled: false
diff --git a/qa/gdk/launch b/qa/gdk/launch
new file mode 100755
index 00000000000..4b1fc6ae191
--- /dev/null
+++ b/qa/gdk/launch
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+COMMIT_REF=${1:-$CI_COMMIT_REF_SLUG}
+RSPEC_ARGS=$2
+
+if [ -z "${COMMIT_REF}" ]; then
+ echo "Please provide a commit ref with the code to be tested as the first argument"
+ exit 1
+fi
+
+# Set the GitLab license mode to "test" so that GitLab uses the appropriate encryption key
+export GITLAB_LICENSE_MODE="test"
+
+# Create the temporary directory that screenshots are saved to
+sudo install -m 777 -d /home/gdk/gdk/gitlab/qa/tmp
+
+# Update GDK
+(cd .. ; gdk update ; cat gdk.yml)
+
+# Reset, fetch, and checkout the GitLab repository with the code from the ref to be tested
+git reset --hard
+git fetch origin $COMMIT_REF
+git checkout $COMMIT_REF
+
+# Install the required gems
+bundle install --jobs=$(nproc) --retry=3 --quiet
+
+# Run the database migrations
+bundle exec rake db:migrate
+
+# Restart GDK to be sure any changes are accounted for in running services, start any stopped services, and wait until the GDK is reachable
+(cd .. ; gdk restart ; ./support/test_url http://gdk.test:3000)
+
+# Install the required gems in the QA directory
+cd qa
+bundle install --jobs=$(nproc) --retry=3 --quiet
+
+# Run the tests
+bundle exec rake "knapsack:download[test]"
+bundle exec bin/qa Test::Instance::All http://gdk.test:3000 -- $RSPEC_ARGS || true
diff --git a/qa/qa.rb b/qa/qa.rb
index fe0c19e0818..cb1278771d9 100644
--- a/qa/qa.rb
+++ b/qa/qa.rb
@@ -85,11 +85,6 @@ module QA
"fips" => "FIPS"
)
- # Configure knapsack at the very begining of the setup
- loader.on_setup do
- QA::Support::KnapsackReport.configure!
- end
-
loader.setup
loader.eager_load
end
diff --git a/qa/qa/page/main/login.rb b/qa/qa/page/main/login.rb
index 8af78bb86c6..f4f8820bc04 100644
--- a/qa/qa/page/main/login.rb
+++ b/qa/qa/page/main/login.rb
@@ -76,16 +76,13 @@ module QA
end
def sign_in_using_admin_credentials
- admin = QA::Resource::User.init do |user|
- user.username = QA::Runtime::User.admin_username
- user.password = QA::Runtime::User.admin_password
- end
-
using_wait_time 0 do
set_initial_password_if_present
sign_in_using_gitlab_credentials(user: admin)
end
+ set_up_new_admin_password_if_required
+
Page::Main::Menu.perform(&:has_personal_area?)
end
@@ -105,6 +102,24 @@ module QA
Page::Main::Menu.perform(&:signed_in?)
end
+ # Handle request for password change
+ # Happens on clean GDK installations when seeded root admin password is expired
+ #
+ def set_up_new_password_if_required(user:, skip_page_validation:)
+ return unless has_content?('Set up new password')
+
+ Profile::Password.perform do |new_password_page|
+ password = user&.password || Runtime::User.password
+ new_password_page.set_new_password(password, password)
+ end
+
+ sign_in_using_credentials(user: user, skip_page_validation: skip_page_validation)
+ end
+
+ def set_up_new_admin_password_if_required
+ set_up_new_password_if_required(user: admin, skip_page_validation: false)
+ end
+
def self.path
'/users/sign_in'
end
@@ -181,6 +196,13 @@ module QA
private
+ def admin
+ @admin ||= QA::Resource::User.init do |user|
+ user.username = QA::Runtime::User.admin_username
+ user.password = QA::Runtime::User.admin_password
+ end
+ end
+
def sign_in_using_gitlab_credentials(user:, skip_page_validation: false)
wait_if_retry_later
@@ -219,20 +241,6 @@ module QA
fill_element :password_field, user.password
end
- # Handle request for password change
- # Happens on clean GDK installations when seeded root admin password is expired
- #
- def set_up_new_password_if_required(user:, skip_page_validation:)
- return unless has_content?('Set up new password')
-
- Profile::Password.perform do |new_password_page|
- password = user&.password || Runtime::User.password
- new_password_page.set_new_password(password, password)
- end
-
- sign_in_using_credentials(user: user, skip_page_validation: skip_page_validation)
- end
-
def set_initial_password_if_present
return unless has_content?('Change your password')
diff --git a/qa/qa/specs/knapsack_runner.rb b/qa/qa/specs/knapsack_runner.rb
index 4908553e43d..0c4f938ee28 100644
--- a/qa/qa/specs/knapsack_runner.rb
+++ b/qa/qa/specs/knapsack_runner.rb
@@ -4,6 +4,8 @@ module QA
module Specs
class KnapsackRunner
def self.run(args)
+ QA::Support::KnapsackReport.configure!
+
allocator = Knapsack::AllocatorBuilder.new(Knapsack::Adapters::RSpecAdapter).allocator
Knapsack.logger.info '==== Knapsack specs to execute ====='
diff --git a/qa/qa/specs/spec_helper.rb b/qa/qa/specs/spec_helper.rb
index 0e6e3973de9..1bf189ed6ac 100644
--- a/qa/qa/specs/spec_helper.rb
+++ b/qa/qa/specs/spec_helper.rb
@@ -11,6 +11,7 @@ QA::Support::GitlabAddress.define_gitlab_address_attribute!
QA::Runtime::Browser.configure! unless QA::Runtime::Env.dry_run
QA::Runtime::AllureReport.configure!
QA::Runtime::Scenario.from_env(QA::Runtime::Env.runtime_scenario_attributes)
+QA::Support::KnapsackReport.configure!
# Enable zero monkey patching mode before loading any other RSpec code.
RSpec.configure(&:disable_monkey_patching!)
diff --git a/qa/tasks/ci.rake b/qa/tasks/ci.rake
index bfb364aa5ee..aaf691de1b5 100644
--- a/qa/tasks/ci.rake
+++ b/qa/tasks/ci.rake
@@ -60,4 +60,9 @@ namespace :ci do
QA::Tools::Ci::TestMetrics.export(args[:glob])
end
+
+ desc "Get available QA environment variables"
+ task :env_var_name_list do
+ puts Gitlab::QA::Runtime::Env.variables.keys.join("\n")
+ end
end
diff --git a/qa/tasks/knapsack.rake b/qa/tasks/knapsack.rake
index c502d1cbb4a..5e60703ced3 100644
--- a/qa/tasks/knapsack.rake
+++ b/qa/tasks/knapsack.rake
@@ -20,6 +20,7 @@ namespace :knapsack do
test_stage_name = args[:stage_name]
knapsack_reports = ENV["QA_KNAPSACK_REPORTS"]&.split(",")
ci_token = ENV["QA_GITLAB_CI_TOKEN"]
+ QA::Support::KnapsackReport.configure!
reports = if knapsack_reports
knapsack_reports
@@ -43,6 +44,7 @@ namespace :knapsack do
desc "Merge and upload knapsack report"
task :upload, [:glob] do |_task, args|
+ QA::Support::KnapsackReport.configure!
QA::Support::KnapsackReport.upload_report(args[:glob])
end
diff --git a/spec/controllers/admin/clusters_controller_spec.rb b/spec/controllers/admin/clusters_controller_spec.rb
index 86a4ac61194..8e62aeed7d0 100644
--- a/spec/controllers/admin/clusters_controller_spec.rb
+++ b/spec/controllers/admin/clusters_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Admin::ClustersController do
+RSpec.describe Admin::ClustersController, feature_category: :kubernetes_management do
include AccessMatchersForController
include GoogleApi::CloudPlatformHelpers
diff --git a/spec/controllers/admin/instance_review_controller_spec.rb b/spec/controllers/admin/instance_review_controller_spec.rb
index 342562618b2..6eab135b3a6 100644
--- a/spec/controllers/admin/instance_review_controller_spec.rb
+++ b/spec/controllers/admin/instance_review_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Admin::InstanceReviewController do
+RSpec.describe Admin::InstanceReviewController, feature_category: :service_ping do
include UsageDataHelpers
let(:admin) { create(:admin) }
diff --git a/spec/controllers/autocomplete_controller_spec.rb b/spec/controllers/autocomplete_controller_spec.rb
index e9b39d44e46..97729d181b1 100644
--- a/spec/controllers/autocomplete_controller_spec.rb
+++ b/spec/controllers/autocomplete_controller_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe AutocompleteController do
let(:project) { create(:project) }
let(:user) { project.first_owner }
- context 'GET users' do
+ context 'GET users', feature_category: :user_management do
let!(:user2) { create(:user) }
let!(:non_member) { create(:user) }
@@ -248,7 +248,7 @@ RSpec.describe AutocompleteController do
end
end
- context 'GET projects' do
+ context 'GET projects', feature_category: :projects do
let(:authorized_project) { create(:project) }
let(:authorized_search_project) { create(:project, name: 'rugged') }
@@ -339,7 +339,7 @@ RSpec.describe AutocompleteController do
end
end
- context 'GET award_emojis' do
+ context 'GET award_emojis', feature_category: :team_planning do
let(:user2) { create(:user) }
let!(:award_emoji1) { create_list(:award_emoji, 2, user: user, name: 'thumbsup') }
let!(:award_emoji2) { create_list(:award_emoji, 1, user: user, name: 'thumbsdown') }
@@ -377,7 +377,7 @@ RSpec.describe AutocompleteController do
end
end
- context 'GET deploy_keys_with_owners' do
+ context 'GET deploy_keys_with_owners', feature_category: :continuous_delivery do
let_it_be(:public_project) { create(:project, :public) }
let_it_be(:user) { create(:user) }
let_it_be(:deploy_key) { create(:deploy_key, user: user) }
@@ -451,7 +451,7 @@ RSpec.describe AutocompleteController do
end
end
- context 'Get merge_request_target_branches' do
+ context 'Get merge_request_target_branches', feature_category: :code_review_workflow do
let!(:merge_request) { create(:merge_request, source_project: project, target_branch: 'feature') }
context 'anonymous user' do
diff --git a/spec/controllers/dashboard/projects_controller_spec.rb b/spec/controllers/dashboard/projects_controller_spec.rb
index b4a4ac56fce..e8ee146a13a 100644
--- a/spec/controllers/dashboard/projects_controller_spec.rb
+++ b/spec/controllers/dashboard/projects_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Dashboard::ProjectsController, :aggregate_failures do
+RSpec.describe Dashboard::ProjectsController, :aggregate_failures, feature_category: :projects do
include ExternalAuthorizationServiceHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/explore/projects_controller_spec.rb b/spec/controllers/explore/projects_controller_spec.rb
index a79d9fa1276..c4f0feb21e2 100644
--- a/spec/controllers/explore/projects_controller_spec.rb
+++ b/spec/controllers/explore/projects_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Explore::ProjectsController do
+RSpec.describe Explore::ProjectsController, feature_category: :projects do
shared_examples 'explore projects' do
let(:expected_default_sort) { 'latest_activity_desc' }
diff --git a/spec/controllers/groups/children_controller_spec.rb b/spec/controllers/groups/children_controller_spec.rb
index f05551432fa..d0656ee47ce 100644
--- a/spec/controllers/groups/children_controller_spec.rb
+++ b/spec/controllers/groups/children_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Groups::ChildrenController do
+RSpec.describe Groups::ChildrenController, feature_category: :subgroups do
include ExternalAuthorizationServiceHelpers
let(:group) { create(:group, :public) }
diff --git a/spec/controllers/groups/clusters_controller_spec.rb b/spec/controllers/groups/clusters_controller_spec.rb
index 46f507c34ba..01ea7101f2e 100644
--- a/spec/controllers/groups/clusters_controller_spec.rb
+++ b/spec/controllers/groups/clusters_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Groups::ClustersController do
+RSpec.describe Groups::ClustersController, feature_category: :kubernetes_management do
include AccessMatchersForController
include GoogleApi::CloudPlatformHelpers
diff --git a/spec/controllers/groups/labels_controller_spec.rb b/spec/controllers/groups/labels_controller_spec.rb
index 0521c5e02a8..916b2cf10dd 100644
--- a/spec/controllers/groups/labels_controller_spec.rb
+++ b/spec/controllers/groups/labels_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Groups::LabelsController do
+RSpec.describe Groups::LabelsController, feature_category: :team_planning do
let_it_be(:group) { create(:group) }
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, namespace: group) }
diff --git a/spec/controllers/projects/branches_controller_spec.rb b/spec/controllers/projects/branches_controller_spec.rb
index fd01aee709a..dcde22c1fd6 100644
--- a/spec/controllers/projects/branches_controller_spec.rb
+++ b/spec/controllers/projects/branches_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Projects::BranchesController do
+RSpec.describe Projects::BranchesController, feature_category: :source_code_management do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let(:developer) { create(:user) }
diff --git a/spec/controllers/projects/clusters_controller_spec.rb b/spec/controllers/projects/clusters_controller_spec.rb
index 894f0f8354d..a4f7c92f5cd 100644
--- a/spec/controllers/projects/clusters_controller_spec.rb
+++ b/spec/controllers/projects/clusters_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Projects::ClustersController do
+RSpec.describe Projects::ClustersController, feature_category: :kubernetes_management do
include AccessMatchersForController
include GoogleApi::CloudPlatformHelpers
include KubernetesHelpers
diff --git a/spec/controllers/projects/commits_controller_spec.rb b/spec/controllers/projects/commits_controller_spec.rb
index 26d4725656f..67aa82dacbb 100644
--- a/spec/controllers/projects/commits_controller_spec.rb
+++ b/spec/controllers/projects/commits_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Projects::CommitsController do
+RSpec.describe Projects::CommitsController, feature_category: :source_code_management do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/environments_controller_spec.rb b/spec/controllers/projects/environments_controller_spec.rb
index 48e58cc0e38..169fed1ab17 100644
--- a/spec/controllers/projects/environments_controller_spec.rb
+++ b/spec/controllers/projects/environments_controller_spec.rb
@@ -104,30 +104,16 @@ RSpec.describe Projects::EnvironmentsController, feature_category: :continuous_d
end
context 'can access stop stale environments feature' do
- context 'when stop_stale_environments FF is enabled' do
- it 'maintainers can access the feature' do
- get :index, params: environment_params(format: :json)
-
- expect(json_response['can_stop_stale_environments']).to be_truthy
- end
-
- context 'when user is a reporter' do
- let(:user) { reporter }
+ it 'maintainers can access the feature' do
+ get :index, params: environment_params(format: :json)
- it 'reporters cannot access the feature' do
- get :index, params: environment_params(format: :json)
-
- expect(json_response['can_stop_stale_environments']).to be_falsey
- end
- end
+ expect(json_response['can_stop_stale_environments']).to be_truthy
end
- context 'when stop_stale_environments FF is disabled' do
- before do
- stub_feature_flags(stop_stale_environments: false)
- end
+ context 'when user is a reporter' do
+ let(:user) { reporter }
- it 'maintainers cannot access the feature' do
+ it 'reporters cannot access the feature' do
get :index, params: environment_params(format: :json)
expect(json_response['can_stop_stale_environments']).to be_falsey
diff --git a/spec/controllers/projects/forks_controller_spec.rb b/spec/controllers/projects/forks_controller_spec.rb
index 962ef93dc72..25c722173c1 100644
--- a/spec/controllers/projects/forks_controller_spec.rb
+++ b/spec/controllers/projects/forks_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Projects::ForksController do
+RSpec.describe Projects::ForksController, feature_category: :source_code_management do
let(:user) { create(:user) }
let(:project) { create(:project, :public, :repository) }
let(:forked_project) { Projects::ForkService.new(project, user, name: 'Some name').execute }
diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb
index b4084e0f9eb..9c272872a73 100644
--- a/spec/controllers/projects/issues_controller_spec.rb
+++ b/spec/controllers/projects/issues_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Projects::IssuesController do
+RSpec.describe Projects::IssuesController, feature_category: :team_planning do
include ProjectForksHelper
include_context 'includes Spam constants'
diff --git a/spec/controllers/projects/labels_controller_spec.rb b/spec/controllers/projects/labels_controller_spec.rb
index dfa6ed639b6..98982856d6c 100644
--- a/spec/controllers/projects/labels_controller_spec.rb
+++ b/spec/controllers/projects/labels_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Projects::LabelsController do
+RSpec.describe Projects::LabelsController, feature_category: :team_planning do
let_it_be(:group) { create(:group) }
let_it_be(:project, reload: true) { create(:project, namespace: group) }
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/merge_requests/creations_controller_spec.rb b/spec/controllers/projects/merge_requests/creations_controller_spec.rb
index 7db708e0e78..3d4a884587f 100644
--- a/spec/controllers/projects/merge_requests/creations_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests/creations_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Projects::MergeRequests::CreationsController do
+RSpec.describe Projects::MergeRequests::CreationsController, feature_category: :code_review_workflow do
let(:project) { create(:project, :repository) }
let(:user) { project.first_owner }
let(:fork_project) { create(:forked_project_with_submodules) }
diff --git a/spec/controllers/projects/merge_requests/diffs_controller_spec.rb b/spec/controllers/projects/merge_requests/diffs_controller_spec.rb
index 05c07c9f00d..23a33d7e0b1 100644
--- a/spec/controllers/projects/merge_requests/diffs_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests/diffs_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Projects::MergeRequests::DiffsController do
+RSpec.describe Projects::MergeRequests::DiffsController, feature_category: :code_review_workflow do
include ProjectForksHelper
include TrackingHelpers
diff --git a/spec/controllers/projects/settings/ci_cd_controller_spec.rb b/spec/controllers/projects/settings/ci_cd_controller_spec.rb
index dcd1072612a..ba917fa3a31 100644
--- a/spec/controllers/projects/settings/ci_cd_controller_spec.rb
+++ b/spec/controllers/projects/settings/ci_cd_controller_spec.rb
@@ -2,7 +2,7 @@
require('spec_helper')
-RSpec.describe Projects::Settings::CiCdController do
+RSpec.describe Projects::Settings::CiCdController, feature_category: :continuous_integration do
let_it_be(:user) { create(:user) }
let_it_be(:project_auto_devops) { create(:project_auto_devops) }
diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb
index cf87b2c4437..51f8a3b1197 100644
--- a/spec/controllers/projects_controller_spec.rb
+++ b/spec/controllers/projects_controller_spec.rb
@@ -2,7 +2,7 @@
require('spec_helper')
-RSpec.describe ProjectsController do
+RSpec.describe ProjectsController, feature_category: :projects do
include ExternalAuthorizationServiceHelpers
include ProjectForksHelper
using RSpec::Parameterized::TableSyntax
diff --git a/spec/features/profiles/keys_spec.rb b/spec/features/profiles/keys_spec.rb
index e1c21f2117a..ae61f1cf492 100644
--- a/spec/features/profiles/keys_spec.rb
+++ b/spec/features/profiles/keys_spec.rb
@@ -126,7 +126,7 @@ RSpec.describe 'Profile > SSH Keys', feature_category: :user_profile do
visit project_commit_path(project, commit)
wait_for_all_requests
- page.find('a.gpg-status-box', text: 'Verified').click
+ find('a.signature-badge', text: 'Verified').click
within('.popover') do
expect(page).to have_content("Verified commit")
@@ -138,7 +138,7 @@ RSpec.describe 'Profile > SSH Keys', feature_category: :user_profile do
visit project_commit_path(project, commit)
wait_for_all_requests
- page.find('a.gpg-status-box', text: 'Unverified').click
+ find('a.signature-badge', text: 'Unverified').click
within('.popover') do
expect(page).to have_content("Unverified signature")
diff --git a/spec/features/projects/blobs/blob_show_spec.rb b/spec/features/projects/blobs/blob_show_spec.rb
index 0c5985f7735..7faf0e1a6b1 100644
--- a/spec/features/projects/blobs/blob_show_spec.rb
+++ b/spec/features/projects/blobs/blob_show_spec.rb
@@ -1007,8 +1007,8 @@ RSpec.describe 'File blob', :js, feature_category: :projects do
it 'displays a GPG badge' do
visit_blob('CONTRIBUTING.md', ref: '33f3729a45c02fc67d00adb1b8bca394b0e761d9')
- expect(page).not_to have_selector '.gpg-status-box.js-loading-gpg-badge'
- expect(page).to have_selector '.gpg-status-box.invalid'
+ expect(page).not_to have_selector '.js-loading-signature-badge'
+ expect(page).to have_selector '.gl-badge.badge-muted'
end
end
@@ -1016,8 +1016,8 @@ RSpec.describe 'File blob', :js, feature_category: :projects do
it 'displays a GPG badge' do
visit_blob('conflicting-file.md', ref: '6101e87e575de14b38b4e1ce180519a813671e10')
- expect(page).not_to have_selector '.gpg-status-box.js-loading-gpg-badge'
- expect(page).to have_selector '.gpg-status-box.invalid'
+ expect(page).not_to have_selector '.js-loading-signature-badge'
+ expect(page).to have_selector '.gl-badge.badge-muted'
end
end
diff --git a/spec/features/projects/tree/tree_show_spec.rb b/spec/features/projects/tree/tree_show_spec.rb
index da589b97e3f..52c6cb2192b 100644
--- a/spec/features/projects/tree/tree_show_spec.rb
+++ b/spec/features/projects/tree/tree_show_spec.rb
@@ -94,8 +94,8 @@ RSpec.describe 'Projects tree', :js, feature_category: :web_ide do
visit project_tree_path(project, '33f3729a45c02fc67d00adb1b8bca394b0e761d9')
wait_for_requests
- expect(page).not_to have_selector '.gpg-status-box.js-loading-gpg-badge'
- expect(page).to have_selector '.gpg-status-box.invalid'
+ expect(page).not_to have_selector '.js-loading-signature-badge'
+ expect(page).to have_selector '.gl-badge.badge-muted'
end
context 'on a directory that has not changed recently' do
@@ -104,8 +104,8 @@ RSpec.describe 'Projects tree', :js, feature_category: :web_ide do
visit project_tree_path(project, tree_path)
wait_for_requests
- expect(page).not_to have_selector '.gpg-status-box.js-loading-gpg-badge'
- expect(page).to have_selector '.gpg-status-box.invalid'
+ expect(page).not_to have_selector '.js-loading-signature-badge'
+ expect(page).to have_selector '.gl-badge.badge-muted'
end
end
end
@@ -152,8 +152,8 @@ RSpec.describe 'Projects tree', :js, feature_category: :web_ide do
visit project_tree_path(project, '33f3729a45c02fc67d00adb1b8bca394b0e761d9')
wait_for_requests
- expect(page).not_to have_selector '.gpg-status-box.js-loading-gpg-badge'
- expect(page).to have_selector '.gpg-status-box.invalid'
+ expect(page).not_to have_selector '.js-loading-signature-badge'
+ expect(page).to have_selector '.gl-badge.badge-muted'
end
end
end
diff --git a/spec/features/projects_spec.rb b/spec/features/projects_spec.rb
index 84702b3a6bb..73ee250a8b8 100644
--- a/spec/features/projects_spec.rb
+++ b/spec/features/projects_spec.rb
@@ -343,8 +343,8 @@ RSpec.describe 'Project', feature_category: :projects do
visit project_path(project)
wait_for_requests
- expect(page).not_to have_selector '.gpg-status-box.js-loading-gpg-badge'
- expect(page).to have_selector '.gpg-status-box.invalid'
+ expect(page).not_to have_selector '.js-loading-signature-badge'
+ expect(page).to have_selector '.gl-badge.badge-muted'
end
end
@@ -371,8 +371,8 @@ RSpec.describe 'Project', feature_category: :projects do
visit project_path(project)
wait_for_requests
- expect(page).not_to have_selector '.gpg-status-box.js-loading-gpg-badge'
- expect(page).to have_selector '.gpg-status-box.invalid'
+ expect(page).not_to have_selector '.gl-badge.js-loading-signature-badge'
+ expect(page).to have_selector '.gl-badge.badge-muted'
end
end
end
diff --git a/spec/features/signed_commits_spec.rb b/spec/features/signed_commits_spec.rb
index bc82afc70a3..5d9b451cdf6 100644
--- a/spec/features/signed_commits_spec.rb
+++ b/spec/features/signed_commits_spec.rb
@@ -16,7 +16,7 @@ RSpec.describe 'GPG signed commits', feature_category: :source_code_management d
visit project_commit_path(project, ref)
- expect(page).to have_selector('.gpg-status-box', text: 'Unverified')
+ expect(page).to have_selector('.gl-badge', text: 'Unverified')
# user changes their email which makes the gpg key verified
perform_enqueued_jobs do
@@ -26,7 +26,7 @@ RSpec.describe 'GPG signed commits', feature_category: :source_code_management d
visit project_commit_path(project, ref)
- expect(page).to have_selector('.gpg-status-box', text: 'Verified')
+ expect(page).to have_selector('.gl-badge', text: 'Verified')
end
it 'changes from unverified to verified when the user adds the missing gpg key', :sidekiq_might_not_need_inline do
@@ -35,7 +35,7 @@ RSpec.describe 'GPG signed commits', feature_category: :source_code_management d
visit project_commit_path(project, ref)
- expect(page).to have_selector('.gpg-status-box', text: 'Unverified')
+ expect(page).to have_selector('.gl-badge', text: 'Unverified')
# user adds the gpg key which makes the signature valid
perform_enqueued_jobs do
@@ -44,7 +44,7 @@ RSpec.describe 'GPG signed commits', feature_category: :source_code_management d
visit project_commit_path(project, ref)
- expect(page).to have_selector('.gpg-status-box', text: 'Verified')
+ expect(page).to have_selector('.gl-badge', text: 'Verified')
end
context 'shows popover badges', :js do
@@ -75,7 +75,7 @@ RSpec.describe 'GPG signed commits', feature_category: :source_code_management d
visit project_commit_path(project, GpgHelpers::SIGNED_COMMIT_SHA)
wait_for_all_requests
- page.find('.gpg-status-box', text: 'Unverified').click
+ page.find('.gl-badge', text: 'Unverified').click
within '.popover' do
expect(page).to have_content 'This commit was signed with an unverified signature.'
@@ -90,7 +90,7 @@ RSpec.describe 'GPG signed commits', feature_category: :source_code_management d
visit project_commit_path(project, GpgHelpers::SIGNED_COMMIT_SHA)
wait_for_all_requests
- page.find('.gpg-status-box', text: 'Unverified').click
+ page.find('.gl-badge', text: 'Unverified').click
within '.popover' do
expect(page).to have_content 'This commit was signed with a verified signature, but the committer email is not associated with the GPG Key.'
@@ -104,7 +104,7 @@ RSpec.describe 'GPG signed commits', feature_category: :source_code_management d
visit project_commit_path(project, GpgHelpers::SIGNED_COMMIT_SHA)
wait_for_all_requests
- page.find('.gpg-status-box', text: 'Unverified').click
+ page.find('.gl-badge', text: 'Unverified').click
within '.popover' do
expect(page).to have_content "This commit was signed with a different user's verified signature."
@@ -118,7 +118,7 @@ RSpec.describe 'GPG signed commits', feature_category: :source_code_management d
visit project_commit_path(project, GpgHelpers::MULTIPLE_SIGNATURES_SHA)
wait_for_all_requests
- page.find('.gpg-status-box', text: 'Unverified').click
+ page.find('.gl-badge', text: 'Unverified').click
within '.popover' do
expect(page).to have_content "This commit was signed with multiple signatures."
@@ -131,7 +131,7 @@ RSpec.describe 'GPG signed commits', feature_category: :source_code_management d
visit project_commit_path(project, GpgHelpers::SIGNED_AND_AUTHORED_SHA)
wait_for_all_requests
- page.find('.gpg-status-box', text: 'Verified').click
+ page.find('.gl-badge', text: 'Verified').click
within '.popover' do
expect(page).to have_content 'This commit was signed with a verified signature and the committer email was verified to belong to the same user.'
@@ -146,14 +146,14 @@ RSpec.describe 'GPG signed commits', feature_category: :source_code_management d
wait_for_all_requests
# wait for the signature to get generated
- expect(page).to have_selector('.gpg-status-box', text: 'Verified')
+ expect(page).to have_selector('.gl-badge', text: 'Verified')
user_1.destroy!
refresh
wait_for_all_requests
- page.find('.gpg-status-box', text: 'Verified').click
+ page.find('.gl-badge', text: 'Verified').click
within '.popover' do
expect(page).to have_content 'This commit was signed with a verified signature and the committer email was verified to belong to the same user.'
@@ -170,9 +170,9 @@ RSpec.describe 'GPG signed commits', feature_category: :source_code_management d
end
it 'displays commit signature' do
- expect(page).to have_selector('.gpg-status-box', text: 'Unverified')
+ expect(page).to have_selector('.gl-badge', text: 'Unverified')
- page.find('.gpg-status-box', text: 'Unverified').click
+ page.find('.gl-badge', text: 'Unverified').click
within '.popover' do
expect(page).to have_content 'This commit was signed with multiple signatures.'
diff --git a/spec/finders/releases/group_releases_finder_spec.rb b/spec/finders/releases/group_releases_finder_spec.rb
index 5eac6f4fbdc..c47477eb3d5 100644
--- a/spec/finders/releases/group_releases_finder_spec.rb
+++ b/spec/finders/releases/group_releases_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Releases::GroupReleasesFinder do
+RSpec.describe Releases::GroupReleasesFinder, feature_category: :subgroups do
let(:user) { create(:user) }
let(:group) { create(:group) }
let(:project) { create(:project, :repository, group: group) }
diff --git a/spec/frontend/boards/board_card_inner_spec.js b/spec/frontend/boards/board_card_inner_spec.js
index 0edc8359b6a..1e823e3321a 100644
--- a/spec/frontend/boards/board_card_inner_spec.js
+++ b/spec/frontend/boards/board_card_inner_spec.js
@@ -1,7 +1,9 @@
import { GlLabel, GlLoadingIcon, GlTooltip } from '@gitlab/ui';
import { range } from 'lodash';
import Vue, { nextTick } from 'vue';
+import VueApollo from 'vue-apollo';
import Vuex from 'vuex';
+import createMockApollo from 'helpers/mock_apollo_helper';
import setWindowLocation from 'helpers/set_window_location_helper';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import { mountExtended } from 'helpers/vue_test_utils_helper';
@@ -18,6 +20,7 @@ jest.mock('~/lib/utils/url_utility');
jest.mock('~/boards/eventhub');
Vue.use(Vuex);
+Vue.use(VueApollo);
describe('Board card component', () => {
const user = {
@@ -69,6 +72,7 @@ describe('Board card component', () => {
const createWrapper = ({ props = {}, isEpicBoard = false, isGroupBoard = true } = {}) => {
wrapper = mountExtended(BoardCardInner, {
store,
+ apolloProvider: createMockApollo(),
propsData: {
list,
item: issue,
@@ -82,13 +86,6 @@ describe('Board card component', () => {
directives: {
GlTooltip: createMockDirective(),
},
- mocks: {
- $apollo: {
- queries: {
- blockingIssuables: { loading: false },
- },
- },
- },
provide: {
rootPath: '/',
scopedLabelsAvailable: false,
diff --git a/spec/frontend/diffs/components/commit_item_spec.js b/spec/frontend/diffs/components/commit_item_spec.js
index 75d55376d09..08be3fa2745 100644
--- a/spec/frontend/diffs/components/commit_item_spec.js
+++ b/spec/frontend/diffs/components/commit_item_spec.js
@@ -9,8 +9,8 @@ import CommitPipelineStatus from '~/projects/tree/components/commit_pipeline_sta
const TEST_AUTHOR_NAME = 'test';
const TEST_AUTHOR_EMAIL = 'test+test@gitlab.com';
const TEST_AUTHOR_GRAVATAR = `${TEST_HOST}/avatar/test?s=40`;
-const TEST_SIGNATURE_HTML = `<a class="btn gpg-status-box valid" data-content="signature-content" data-html="true" data-placement="top" data-title="signature-title" data-toggle="popover" role="button" tabindex="0">
- Verified
+const TEST_SIGNATURE_HTML = `<a class="btn signature-badge" data-content="signature-content" data-html="true" data-placement="top" data-title="signature-title" data-toggle="popover" role="button" tabindex="0">
+ <span class="gl-badge badge badge-pill badge-success md">Verified</span>
</a>`;
const TEST_PIPELINE_STATUS_PATH = `${TEST_HOST}/pipeline/status`;
@@ -156,7 +156,7 @@ describe('diffs/components/commit_item', () => {
it('renders signature html', () => {
const actionsElement = getCommitActionsElement();
- const signatureElement = actionsElement.find('.gpg-status-box');
+ const signatureElement = actionsElement.find('.signature-badge');
expect(signatureElement.html()).toBe(TEST_SIGNATURE_HTML);
});
diff --git a/spec/frontend/diffs/components/diff_row_utils_spec.js b/spec/frontend/diffs/components/diff_row_utils_spec.js
index a6f508c73eb..6e9eb433924 100644
--- a/spec/frontend/diffs/components/diff_row_utils_spec.js
+++ b/spec/frontend/diffs/components/diff_row_utils_spec.js
@@ -21,262 +21,287 @@ function problemsClone({
};
}
-describe('isHighlighted', () => {
- it('should return true if line is highlighted', () => {
- const line = { line_code: LINE_CODE };
- const isCommented = false;
- expect(utils.isHighlighted(LINE_CODE, line, isCommented)).toBe(true);
- });
-
- it('should return false if line is not highlighted', () => {
- const line = { line_code: LINE_CODE };
- const isCommented = false;
- expect(utils.isHighlighted('xxx', line, isCommented)).toBe(false);
- });
-
- it('should return true if isCommented is true', () => {
- const line = { line_code: LINE_CODE };
- const isCommented = true;
- expect(utils.isHighlighted('xxx', line, isCommented)).toBe(true);
- });
-});
-
-describe('isContextLine', () => {
- it('return true if line type is context', () => {
- expect(utils.isContextLine(CONTEXT_LINE_TYPE)).toBe(true);
- });
-
- it('return false if line type is not context', () => {
- expect(utils.isContextLine('xxx')).toBe(false);
- });
-});
-
-describe('isMatchLine', () => {
- it('return true if line type is match', () => {
- expect(utils.isMatchLine(MATCH_LINE_TYPE)).toBe(true);
- });
-
- it('return false if line type is not match', () => {
- expect(utils.isMatchLine('xxx')).toBe(false);
- });
-});
-
-describe('isMetaLine', () => {
- it.each`
- type | expectation
- ${OLD_NO_NEW_LINE_TYPE} | ${true}
- ${NEW_NO_NEW_LINE_TYPE} | ${true}
- ${EMPTY_CELL_TYPE} | ${true}
- ${'xxx'} | ${false}
- `('should return $expectation if type is $type', ({ type, expectation }) => {
- expect(utils.isMetaLine(type)).toBe(expectation);
- });
-});
-
-describe('shouldRenderCommentButton', () => {
- it('should return false if comment button is not rendered', () => {
- expect(utils.shouldRenderCommentButton(true, false)).toBe(false);
- });
-
- it('should return false if not logged in', () => {
- expect(utils.shouldRenderCommentButton(false, true)).toBe(false);
- });
-
- it('should return true logged in and rendered', () => {
- expect(utils.shouldRenderCommentButton(true, true)).toBe(true);
- });
-});
-
-describe('hasDiscussions', () => {
- it('should return false if line is undefined', () => {
- expect(utils.hasDiscussions()).toBe(false);
- });
-
- it('should return false if discussions is undefined', () => {
- expect(utils.hasDiscussions({})).toBe(false);
- });
-
- it('should return false if discussions has legnth of 0', () => {
- expect(utils.hasDiscussions({ discussions: [] })).toBe(false);
- });
+describe('diff_row_utils', () => {
+ describe('isHighlighted', () => {
+ it('should return true if line is highlighted', () => {
+ const line = { line_code: LINE_CODE };
+ const isCommented = false;
+ expect(utils.isHighlighted(LINE_CODE, line, isCommented)).toBe(true);
+ });
+
+ it('should return false if line is not highlighted', () => {
+ const line = { line_code: LINE_CODE };
+ const isCommented = false;
+ expect(utils.isHighlighted('xxx', line, isCommented)).toBe(false);
+ });
- it('should return true if discussions has legnth > 0', () => {
- expect(utils.hasDiscussions({ discussions: [1] })).toBe(true);
- });
-});
-
-describe('lineHref', () => {
- it(`should return #${LINE_CODE}`, () => {
- expect(utils.lineHref({ line_code: LINE_CODE })).toEqual(`#${LINE_CODE}`);
- });
-
- it(`should return '#' if line is undefined`, () => {
- expect(utils.lineHref()).toEqual('#');
- });
-
- it(`should return '#' if line_code is undefined`, () => {
- expect(utils.lineHref({})).toEqual('#');
- });
-});
-
-describe('lineCode', () => {
- it(`should return undefined if line_code is undefined`, () => {
- expect(utils.lineCode()).toEqual(undefined);
- expect(utils.lineCode({ left: {} })).toEqual(undefined);
- expect(utils.lineCode({ right: {} })).toEqual(undefined);
- });
-
- it(`should return ${LINE_CODE}`, () => {
- expect(utils.lineCode({ line_code: LINE_CODE })).toEqual(LINE_CODE);
- expect(utils.lineCode({ left: { line_code: LINE_CODE } })).toEqual(LINE_CODE);
- expect(utils.lineCode({ right: { line_code: LINE_CODE } })).toEqual(LINE_CODE);
- });
-});
-
-describe('classNameMapCell', () => {
- it.each`
- line | hll | isLoggedIn | isHover | expectation
- ${undefined} | ${true} | ${true} | ${true} | ${[]}
- ${{ type: 'new' }} | ${false} | ${false} | ${false} | ${['new', { hll: false, 'is-over': false, new_line: true, old_line: false }]}
- ${{ type: 'new' }} | ${true} | ${true} | ${false} | ${['new', { hll: true, 'is-over': false, new_line: true, old_line: false }]}
- ${{ type: 'new' }} | ${true} | ${false} | ${true} | ${['new', { hll: true, 'is-over': false, new_line: true, old_line: false }]}
- ${{ type: 'new' }} | ${true} | ${true} | ${true} | ${['new', { hll: true, 'is-over': true, new_line: true, old_line: false }]}
- `('should return $expectation', ({ line, hll, isLoggedIn, isHover, expectation }) => {
- const classes = utils.classNameMapCell({ line, hll, isLoggedIn, isHover });
- expect(classes).toEqual(expectation);
- });
-});
-
-describe('addCommentTooltip', () => {
- const brokenSymLinkTooltip =
- 'Commenting on symbolic links that replace or are replaced by files is not supported';
- const brokenRealTooltip =
- 'Commenting on files that replace or are replaced by symbolic links is not supported';
- const lineMovedOrRenamedFileTooltip =
- 'Commenting on files that are only moved or renamed is not supported';
- const lineWithNoLineCodeTooltip = 'Commenting on this line is not supported';
- const dragTooltip = 'Add a comment to this line or drag for multiple lines';
-
- it('should return default tooltip', () => {
- expect(utils.addCommentTooltip()).toBeUndefined();
- });
-
- it('should return drag comment tooltip when dragging is enabled', () => {
- expect(utils.addCommentTooltip({ problems: problemsClone() })).toEqual(dragTooltip);
- });
-
- it('should return broken symlink tooltip', () => {
- expect(
- utils.addCommentTooltip({
- problems: problemsClone({ brokenSymlink: { wasSymbolic: true } }),
- }),
- ).toEqual(brokenSymLinkTooltip);
- expect(
- utils.addCommentTooltip({ problems: problemsClone({ brokenSymlink: { isSymbolic: true } }) }),
- ).toEqual(brokenSymLinkTooltip);
- });
-
- it('should return broken real tooltip', () => {
- expect(
- utils.addCommentTooltip({ problems: problemsClone({ brokenSymlink: { wasReal: true } }) }),
- ).toEqual(brokenRealTooltip);
- expect(
- utils.addCommentTooltip({ problems: problemsClone({ brokenSymlink: { isReal: true } }) }),
- ).toEqual(brokenRealTooltip);
- });
-
- it('reports a tooltip when the line is in a file that has only been moved or renamed', () => {
- expect(utils.addCommentTooltip({ problems: problemsClone({ fileOnlyMoved: true }) })).toEqual(
- lineMovedOrRenamedFileTooltip,
+ it('should return true if isCommented is true', () => {
+ const line = { line_code: LINE_CODE };
+ const isCommented = true;
+ expect(utils.isHighlighted('xxx', line, isCommented)).toBe(true);
+ });
+ });
+
+ describe('isContextLine', () => {
+ it('return true if line type is context', () => {
+ expect(utils.isContextLine(CONTEXT_LINE_TYPE)).toBe(true);
+ });
+
+ it('return false if line type is not context', () => {
+ expect(utils.isContextLine('xxx')).toBe(false);
+ });
+ });
+
+ describe('isMatchLine', () => {
+ it('return true if line type is match', () => {
+ expect(utils.isMatchLine(MATCH_LINE_TYPE)).toBe(true);
+ });
+
+ it('return false if line type is not match', () => {
+ expect(utils.isMatchLine('xxx')).toBe(false);
+ });
+ });
+
+ describe('isMetaLine', () => {
+ it.each`
+ type | expectation
+ ${OLD_NO_NEW_LINE_TYPE} | ${true}
+ ${NEW_NO_NEW_LINE_TYPE} | ${true}
+ ${EMPTY_CELL_TYPE} | ${true}
+ ${'xxx'} | ${false}
+ `('should return $expectation if type is $type', ({ type, expectation }) => {
+ expect(utils.isMetaLine(type)).toBe(expectation);
+ });
+ });
+
+ describe('shouldRenderCommentButton', () => {
+ it('should return false if comment button is not rendered', () => {
+ expect(utils.shouldRenderCommentButton(true, false)).toBe(false);
+ });
+
+ it('should return false if not logged in', () => {
+ expect(utils.shouldRenderCommentButton(false, true)).toBe(false);
+ });
+
+ it('should return true logged in and rendered', () => {
+ expect(utils.shouldRenderCommentButton(true, true)).toBe(true);
+ });
+ });
+
+ describe('hasDiscussions', () => {
+ it('should return false if line is undefined', () => {
+ expect(utils.hasDiscussions()).toBe(false);
+ });
+
+ it('should return false if discussions is undefined', () => {
+ expect(utils.hasDiscussions({})).toBe(false);
+ });
+
+ it('should return false if discussions has legnth of 0', () => {
+ expect(utils.hasDiscussions({ discussions: [] })).toBe(false);
+ });
+
+ it('should return true if discussions has legnth > 0', () => {
+ expect(utils.hasDiscussions({ discussions: [1] })).toBe(true);
+ });
+ });
+
+ describe('lineHref', () => {
+ it(`should return #${LINE_CODE}`, () => {
+ expect(utils.lineHref({ line_code: LINE_CODE })).toEqual(`#${LINE_CODE}`);
+ });
+
+ it(`should return '#' if line is undefined`, () => {
+ expect(utils.lineHref()).toEqual('#');
+ });
+
+ it(`should return '#' if line_code is undefined`, () => {
+ expect(utils.lineHref({})).toEqual('#');
+ });
+ });
+
+ describe('lineCode', () => {
+ it(`should return undefined if line_code is undefined`, () => {
+ expect(utils.lineCode()).toEqual(undefined);
+ expect(utils.lineCode({ left: {} })).toEqual(undefined);
+ expect(utils.lineCode({ right: {} })).toEqual(undefined);
+ });
+
+ it(`should return ${LINE_CODE}`, () => {
+ expect(utils.lineCode({ line_code: LINE_CODE })).toEqual(LINE_CODE);
+ expect(utils.lineCode({ left: { line_code: LINE_CODE } })).toEqual(LINE_CODE);
+ expect(utils.lineCode({ right: { line_code: LINE_CODE } })).toEqual(LINE_CODE);
+ });
+ });
+
+ describe('classNameMapCell', () => {
+ it.each`
+ line | highlighted | commented | selectionStart | selectionEnd | isLoggedIn | isHover | expectation
+ ${undefined} | ${true} | ${false} | ${false} | ${false} | ${true} | ${true} | ${[{ 'highlight-top': true, 'highlight-bottom': true, hll: true, commented: false }]}
+ ${undefined} | ${false} | ${true} | ${false} | ${false} | ${true} | ${true} | ${[{ 'highlight-top': false, 'highlight-bottom': false, hll: false, commented: true }]}
+ ${{ type: 'new' }} | ${false} | ${false} | ${false} | ${false} | ${false} | ${false} | ${[{ new: true, 'highlight-top': false, 'highlight-bottom': false, hll: false, commented: false, 'is-over': false, new_line: true, old_line: false }]}
+ ${{ type: 'new' }} | ${true} | ${false} | ${false} | ${false} | ${true} | ${false} | ${[{ new: true, 'highlight-top': true, 'highlight-bottom': true, hll: true, commented: false, 'is-over': false, new_line: true, old_line: false }]}
+ ${{ type: 'new' }} | ${true} | ${false} | ${false} | ${false} | ${false} | ${true} | ${[{ new: true, 'highlight-top': true, 'highlight-bottom': true, hll: true, commented: false, 'is-over': false, new_line: true, old_line: false }]}
+ ${{ type: 'new' }} | ${true} | ${false} | ${false} | ${false} | ${true} | ${true} | ${[{ new: true, 'highlight-top': true, 'highlight-bottom': true, hll: true, commented: false, 'is-over': true, new_line: true, old_line: false }]}
+ `(
+ 'should return $expectation',
+ ({
+ line,
+ highlighted,
+ commented,
+ selectionStart,
+ selectionEnd,
+ isLoggedIn,
+ isHover,
+ expectation,
+ }) => {
+ const classes = utils.classNameMapCell({
+ line,
+ highlighted,
+ commented,
+ selectionStart,
+ selectionEnd,
+ isLoggedIn,
+ isHover,
+ });
+ expect(classes).toEqual(expectation);
+ },
);
});
- it("reports a tooltip when the line doesn't have a line code to leave a comment on", () => {
- expect(utils.addCommentTooltip({ problems: problemsClone({ brokenLineCode: true }) })).toEqual(
- lineWithNoLineCodeTooltip,
+ describe('addCommentTooltip', () => {
+ const brokenSymLinkTooltip =
+ 'Commenting on symbolic links that replace or are replaced by files is not supported';
+ const brokenRealTooltip =
+ 'Commenting on files that replace or are replaced by symbolic links is not supported';
+ const lineMovedOrRenamedFileTooltip =
+ 'Commenting on files that are only moved or renamed is not supported';
+ const lineWithNoLineCodeTooltip = 'Commenting on this line is not supported';
+ const dragTooltip = 'Add a comment to this line or drag for multiple lines';
+
+ it('should return default tooltip', () => {
+ expect(utils.addCommentTooltip()).toBeUndefined();
+ });
+
+ it('should return drag comment tooltip when dragging is enabled', () => {
+ expect(utils.addCommentTooltip({ problems: problemsClone() })).toEqual(dragTooltip);
+ });
+
+ it('should return broken symlink tooltip', () => {
+ expect(
+ utils.addCommentTooltip({
+ problems: problemsClone({ brokenSymlink: { wasSymbolic: true } }),
+ }),
+ ).toEqual(brokenSymLinkTooltip);
+ expect(
+ utils.addCommentTooltip({
+ problems: problemsClone({ brokenSymlink: { isSymbolic: true } }),
+ }),
+ ).toEqual(brokenSymLinkTooltip);
+ });
+
+ it('should return broken real tooltip', () => {
+ expect(
+ utils.addCommentTooltip({ problems: problemsClone({ brokenSymlink: { wasReal: true } }) }),
+ ).toEqual(brokenRealTooltip);
+ expect(
+ utils.addCommentTooltip({ problems: problemsClone({ brokenSymlink: { isReal: true } }) }),
+ ).toEqual(brokenRealTooltip);
+ });
+
+ it('reports a tooltip when the line is in a file that has only been moved or renamed', () => {
+ expect(utils.addCommentTooltip({ problems: problemsClone({ fileOnlyMoved: true }) })).toEqual(
+ lineMovedOrRenamedFileTooltip,
+ );
+ });
+
+ it("reports a tooltip when the line doesn't have a line code to leave a comment on", () => {
+ expect(
+ utils.addCommentTooltip({ problems: problemsClone({ brokenLineCode: true }) }),
+ ).toEqual(lineWithNoLineCodeTooltip);
+ });
+ });
+
+ describe('parallelViewLeftLineType', () => {
+ it(`should return ${OLD_NO_NEW_LINE_TYPE}`, () => {
+ expect(
+ utils.parallelViewLeftLineType({ line: { right: { type: NEW_NO_NEW_LINE_TYPE } } }),
+ ).toEqual(OLD_NO_NEW_LINE_TYPE);
+ });
+
+ it(`should return 'new'`, () => {
+ expect(utils.parallelViewLeftLineType({ line: { left: { type: 'new' } } })[0]).toBe('new');
+ });
+
+ it(`should return ${EMPTY_CELL_TYPE}`, () => {
+ expect(utils.parallelViewLeftLineType({})).toContain(EMPTY_CELL_TYPE);
+ });
+
+ it(`should return hll:true`, () => {
+ expect(utils.parallelViewLeftLineType({ highlighted: true })[1].hll).toBe(true);
+ });
+ });
+
+ describe('shouldShowCommentButton', () => {
+ it.each`
+ hover | context | meta | discussions | expectation
+ ${true} | ${false} | ${false} | ${false} | ${true}
+ ${false} | ${false} | ${false} | ${false} | ${false}
+ ${true} | ${true} | ${false} | ${false} | ${false}
+ ${true} | ${true} | ${true} | ${false} | ${false}
+ ${true} | ${true} | ${true} | ${true} | ${false}
+ `(
+ 'should return $expectation when hover is $hover',
+ ({ hover, context, meta, discussions, expectation }) => {
+ expect(utils.shouldShowCommentButton(hover, context, meta, discussions)).toBe(expectation);
+ },
);
});
-});
-
-describe('parallelViewLeftLineType', () => {
- it(`should return ${OLD_NO_NEW_LINE_TYPE}`, () => {
- expect(utils.parallelViewLeftLineType({ right: { type: NEW_NO_NEW_LINE_TYPE } })).toEqual(
- OLD_NO_NEW_LINE_TYPE,
- );
- });
-
- it(`should return 'new'`, () => {
- expect(utils.parallelViewLeftLineType({ left: { type: 'new' } })).toContain('new');
- });
-
- it(`should return ${EMPTY_CELL_TYPE}`, () => {
- expect(utils.parallelViewLeftLineType({})).toContain(EMPTY_CELL_TYPE);
- });
-
- it(`should return hll:true`, () => {
- expect(utils.parallelViewLeftLineType({}, true)[1]).toEqual({ hll: true });
- });
-});
-
-describe('shouldShowCommentButton', () => {
- it.each`
- hover | context | meta | discussions | expectation
- ${true} | ${false} | ${false} | ${false} | ${true}
- ${false} | ${false} | ${false} | ${false} | ${false}
- ${true} | ${true} | ${false} | ${false} | ${false}
- ${true} | ${true} | ${true} | ${false} | ${false}
- ${true} | ${true} | ${true} | ${true} | ${false}
- `(
- 'should return $expectation when hover is $hover',
- ({ hover, context, meta, discussions, expectation }) => {
- expect(utils.shouldShowCommentButton(hover, context, meta, discussions)).toBe(expectation);
- },
- );
-});
-describe('mapParallel', () => {
- it('should assign computed properties to the line object', () => {
- const side = {
- discussions: [{}],
- discussionsExpanded: true,
- hasForm: true,
- problems: problemsClone(),
- };
- const content = {
- diffFile: {},
- hasParallelDraftLeft: () => false,
- hasParallelDraftRight: () => false,
- draftsForLine: () => [],
- };
- const line = { left: side, right: side };
- const expectation = {
- commentRowClasses: '',
- draftRowClasses: 'js-temp-notes-holder',
- hasDiscussionsLeft: true,
- hasDiscussionsRight: true,
- isContextLineLeft: false,
- isContextLineRight: false,
- isMatchLineLeft: false,
- isMatchLineRight: false,
- isMetaLineLeft: false,
- isMetaLineRight: false,
- };
- const leftExpectation = {
- renderDiscussion: true,
- hasDraft: false,
- lineDrafts: [],
- hasCommentForm: true,
- };
- const rightExpectation = {
- renderDiscussion: false,
- hasDraft: false,
- lineDrafts: [],
- hasCommentForm: false,
- };
- const mapped = utils.mapParallel(content)(line);
-
- expect(mapped).toMatchObject(expectation);
- expect(mapped.left).toMatchObject(leftExpectation);
- expect(mapped.right).toMatchObject(rightExpectation);
+ describe('mapParallel', () => {
+ it('should assign computed properties to the line object', () => {
+ const side = {
+ discussions: [{}],
+ discussionsExpanded: true,
+ hasForm: true,
+ problems: problemsClone(),
+ };
+ const content = {
+ diffFile: {},
+ hasParallelDraftLeft: () => false,
+ hasParallelDraftRight: () => false,
+ draftsForLine: () => [],
+ };
+ const line = { left: side, right: side };
+ const expectation = {
+ commentRowClasses: '',
+ draftRowClasses: 'js-temp-notes-holder',
+ hasDiscussionsLeft: true,
+ hasDiscussionsRight: true,
+ isContextLineLeft: false,
+ isContextLineRight: false,
+ isMatchLineLeft: false,
+ isMatchLineRight: false,
+ isMetaLineLeft: false,
+ isMetaLineRight: false,
+ };
+ const leftExpectation = {
+ renderDiscussion: true,
+ hasDraft: false,
+ lineDrafts: [],
+ hasCommentForm: true,
+ };
+ const rightExpectation = {
+ renderDiscussion: false,
+ hasDraft: false,
+ lineDrafts: [],
+ hasCommentForm: false,
+ };
+ const mapped = utils.mapParallel(content)(line);
+
+ expect(mapped).toMatchObject(expectation);
+ expect(mapped.left).toMatchObject(leftExpectation);
+ expect(mapped.right).toMatchObject(rightExpectation);
+ });
});
});
diff --git a/spec/frontend/gpg_badges_spec.js b/spec/frontend/gpg_badges_spec.js
index 4c2242bae4b..2d961e6872e 100644
--- a/spec/frontend/gpg_badges_spec.js
+++ b/spec/frontend/gpg_badges_spec.js
@@ -28,7 +28,7 @@ describe('GpgBadges', () => {
<input type="search" name="search" value="${search}" id="commits-search"class="form-control search-text-input input-short">
</form>
<div class="parent-container">
- <div class="js-loading-gpg-badge" data-commit-sha="${dummyCommitSha}"></div>
+ <div class="js-loading-signature-badge" data-commit-sha="${dummyCommitSha}"></div>
</div>
`);
};
@@ -105,8 +105,8 @@ describe('GpgBadges', () => {
mock.onGet(dummyUrl).replyOnce(HTTP_STATUS_OK);
await GpgBadges.fetch();
- expect(document.querySelector('.js-loading-gpg-badge:empty')).toBe(null);
- const spinners = document.querySelectorAll('.js-loading-gpg-badge span.gl-spinner');
+ expect(document.querySelector('.js-loading-signature-badge:empty')).toBe(null);
+ const spinners = document.querySelectorAll('.js-loading-signature-badge span.gl-spinner');
expect(spinners.length).toBe(1);
});
@@ -115,7 +115,7 @@ describe('GpgBadges', () => {
mock.onGet(dummyUrl).replyOnce(HTTP_STATUS_OK, dummyResponse);
await GpgBadges.fetch();
- expect(document.querySelector('.js-loading-gpg-badge')).toBe(null);
+ expect(document.querySelector('.js-loading-signature-badge')).toBe(null);
const parentContainer = document.querySelector('.parent-container');
expect(parentContainer.innerHTML.trim()).toEqual(dummyBadgeHtml);
diff --git a/spec/frontend/repository/components/last_commit_spec.js b/spec/frontend/repository/components/last_commit_spec.js
index 964b135bee3..7226e7baa36 100644
--- a/spec/frontend/repository/components/last_commit_spec.js
+++ b/spec/frontend/repository/components/last_commit_spec.js
@@ -20,7 +20,7 @@ const findUserAvatarLink = () => wrapper.findComponent(UserAvatarLink);
const findLastCommitLabel = () => wrapper.findByTestId('last-commit-id-label');
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
const findCommitRowDescription = () => wrapper.find('.commit-row-description');
-const findStatusBox = () => wrapper.find('.gpg-status-box');
+const findStatusBox = () => wrapper.find('.signature-badge');
const findItemTitle = () => wrapper.find('.item-title');
const defaultPipelineEdges = [
@@ -206,7 +206,7 @@ describe('Repository last commit component', () => {
it('renders the signature HTML as returned by the backend', async () => {
createComponent({
signatureHtml: `<a
- class="btn gpg-status-box valid"
+ class="btn signature-badge"
data-content="signature-content"
data-html="true"
data-placement="top"
@@ -214,12 +214,12 @@ describe('Repository last commit component', () => {
data-toggle="popover"
role="button"
tabindex="0"
- >Verified</a>`,
+ ><span class="gl-badge badge badge-pill badge-success md">Verified</span></a>`,
});
await waitForPromises();
expect(findStatusBox().html()).toBe(
- `<a class="btn gpg-status-box valid" data-content="signature-content" data-html="true" data-placement="top" data-title="signature-title" data-toggle="popover" role="button" tabindex="0">Verified</a>`,
+ `<a class="btn signature-badge" data-content="signature-content" data-html="true" data-placement="top" data-title="signature-title" data-toggle="popover" role="button" tabindex="0"><span class="gl-badge badge badge-pill badge-success md">Verified</span></a>`,
);
});
diff --git a/spec/frontend/repository/components/preview/index_spec.js b/spec/frontend/repository/components/preview/index_spec.js
index e4eba65795e..d4c746b67d6 100644
--- a/spec/frontend/repository/components/preview/index_spec.js
+++ b/spec/frontend/repository/components/preview/index_spec.js
@@ -9,9 +9,14 @@ jest.mock('~/lib/utils/common_utils');
let vm;
let $apollo;
-function factory(blob) {
+function factory(blob, loading) {
$apollo = {
- query: jest.fn().mockReturnValue(Promise.resolve({})),
+ queries: {
+ readme: {
+ query: jest.fn().mockReturnValue(Promise.resolve({})),
+ loading,
+ },
+ },
};
vm = shallowMount(Preview, {
@@ -58,14 +63,13 @@ describe('Repository file preview component', () => {
});
it('renders loading icon', async () => {
- factory({
- webPath: 'http://test.com',
- name: 'README.md',
- });
-
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- vm.setData({ loading: 1 });
+ factory(
+ {
+ webPath: 'http://test.com',
+ name: 'README.md',
+ },
+ true,
+ );
await nextTick();
expect(vm.findComponent(GlLoadingIcon).exists()).toBe(true);
diff --git a/spec/frontend/vue_merge_request_widget/components/states/mr_widget_commits_header_spec.js b/spec/frontend/vue_merge_request_widget/components/states/mr_widget_commits_header_spec.js
index 774e2bafed3..a6d3a6286a7 100644
--- a/spec/frontend/vue_merge_request_widget/components/states/mr_widget_commits_header_spec.js
+++ b/spec/frontend/vue_merge_request_widget/components/states/mr_widget_commits_header_spec.js
@@ -58,13 +58,8 @@ describe('Commits header component', () => {
expect(findCommitToggle().attributes('aria-label')).toBe('Expand');
});
- it('has a chevron-right icon', async () => {
+ it('has a chevron-right icon', () => {
createComponent();
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({ expanded: false });
-
- await nextTick();
expect(findCommitToggle().props('icon')).toBe('chevron-right');
});
@@ -110,25 +105,21 @@ describe('Commits header component', () => {
});
describe('when expanded', () => {
- beforeEach(() => {
+ beforeEach(async () => {
createComponent();
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({ expanded: true });
+ findCommitToggle().trigger('click');
+ await nextTick();
});
- it('toggle has aria-label equal to collapse', async () => {
- await nextTick();
+ it('toggle has aria-label equal to collapse', () => {
expect(findCommitToggle().attributes('aria-label')).toBe('Collapse');
});
- it('has a chevron-down icon', async () => {
- await nextTick();
+ it('has a chevron-down icon', () => {
expect(findCommitToggle().props('icon')).toBe('chevron-down');
});
- it('has a collapse text', async () => {
- await nextTick();
+ it('has a collapse text', () => {
expect(findHeaderWrapper().text()).toBe('Collapse');
});
});
diff --git a/spec/frontend/vue_merge_request_widget/components/widget/widget_spec.js b/spec/frontend/vue_merge_request_widget/components/widget/widget_spec.js
index c0cd5503cfc..973866176c2 100644
--- a/spec/frontend/vue_merge_request_widget/components/widget/widget_spec.js
+++ b/spec/frontend/vue_merge_request_widget/components/widget/widget_spec.js
@@ -402,7 +402,7 @@ describe('~/vue_merge_request_widget/components/widget/widget.vue', () => {
isCollapsible: true,
actionButtons: [
{
- fullReport: true,
+ trackFullReportClicked: true,
href: '#',
target: '_blank',
id: 'full-report-button',
diff --git a/spec/frontend/vue_merge_request_widget/test_extensions.js b/spec/frontend/vue_merge_request_widget/test_extensions.js
index ff2dc38442f..e9e5d931323 100644
--- a/spec/frontend/vue_merge_request_widget/test_extensions.js
+++ b/spec/frontend/vue_merge_request_widget/test_extensions.js
@@ -153,7 +153,7 @@ export const fullReportExtension = {
text: 'test',
href: `testref`,
target: '_blank',
- fullReport: true,
+ trackFullReportClicked: true,
},
];
},
diff --git a/spec/frontend/vue_shared/components/dropdown_keyboard_navigation_spec.js b/spec/frontend/vue_shared/components/dropdown_keyboard_navigation_spec.js
index c34041f9305..119d6448507 100644
--- a/spec/frontend/vue_shared/components/dropdown_keyboard_navigation_spec.js
+++ b/spec/frontend/vue_shared/components/dropdown_keyboard_navigation_spec.js
@@ -61,27 +61,8 @@ describe('DropdownKeyboardNavigation', () => {
});
describe('keydown events', () => {
- let incrementSpy;
-
beforeEach(() => {
createComponent();
- incrementSpy = jest.spyOn(wrapper.vm, 'increment');
- });
-
- afterEach(() => {
- incrementSpy.mockRestore();
- });
-
- it('onKeydown-Down calls increment(1)', () => {
- helpers.arrowDown();
-
- expect(incrementSpy).toHaveBeenCalledWith(1);
- });
-
- it('onKeydown-Up calls increment(-1)', () => {
- helpers.arrowUp();
-
- expect(incrementSpy).toHaveBeenCalledWith(-1);
});
it('onKeydown-Tab $emits @tab event', () => {
diff --git a/spec/graphql/types/project_type_spec.rb b/spec/graphql/types/project_type_spec.rb
index ea8018d4413..7f26190830e 100644
--- a/spec/graphql/types/project_type_spec.rb
+++ b/spec/graphql/types/project_type_spec.rb
@@ -4,6 +4,7 @@ require 'spec_helper'
RSpec.describe GitlabSchema.types['Project'] do
include GraphqlHelpers
+ include ProjectForksHelper
specify { expect(described_class).to expose_permissions_using(Types::PermissionTypes::Project) }
@@ -37,7 +38,7 @@ RSpec.describe GitlabSchema.types['Project'] do
ci_template timelogs merge_commit_template squash_commit_template work_item_types
recent_issue_boards ci_config_path_or_default packages_cleanup_policy ci_variables
timelog_categories fork_targets branch_rules ci_config_variables pipeline_schedules languages
- incident_management_timeline_event_tags
+ incident_management_timeline_event_tags visible_forks
]
expect(described_class).to include_graphql_fields(*expected_fields)
@@ -859,4 +860,54 @@ RSpec.describe GitlabSchema.types['Project'] do
end
end
end
+
+ describe 'visible_forks' do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project, :public) }
+ let_it_be(:fork_reporter) { fork_project(project, nil, { repository: true }) }
+ let_it_be(:fork_developer) { fork_project(project, nil, { repository: true }) }
+ let_it_be(:fork_group_developer) { fork_project(project, nil, { repository: true }) }
+ let_it_be(:fork_public) { fork_project(project, nil, { repository: true }) }
+ let_it_be(:fork_private) { fork_project(project, nil, { repository: true }) }
+
+ let(:minimum_access_level) { '' }
+ let(:query) do
+ %(
+ query {
+ project(fullPath: "#{project.full_path}") {
+ visibleForks#{minimum_access_level} {
+ nodes {
+ fullPath
+ }
+ }
+ }
+ }
+ )
+ end
+
+ let(:forks) do
+ subject.dig('data', 'project', 'visibleForks', 'nodes')
+ end
+
+ subject { GitlabSchema.execute(query, context: { current_user: user }).as_json }
+
+ before do
+ fork_reporter.add_reporter(user)
+ fork_developer.add_developer(user)
+ fork_group_developer.group.add_developer(user)
+ end
+
+ it 'contains all forks' do
+ expect(forks.count).to eq(5)
+ end
+
+ context 'with minimum_access_level DEVELOPER' do
+ let(:minimum_access_level) { '(minimumAccessLevel: DEVELOPER)' }
+
+ it 'contains forks with developer access' do
+ expect(forks).to contain_exactly(a_hash_including('fullPath' => fork_developer.full_path),
+a_hash_including('fullPath' => fork_group_developer.full_path))
+ end
+ end
+ end
end
diff --git a/spec/helpers/merge_requests_helper_spec.rb b/spec/helpers/merge_requests_helper_spec.rb
index fb23b5c1dc8..6b43e97a0b4 100644
--- a/spec/helpers/merge_requests_helper_spec.rb
+++ b/spec/helpers/merge_requests_helper_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe MergeRequestsHelper do
+RSpec.describe MergeRequestsHelper, feature_category: :code_review_workflow do
include ProjectForksHelper
describe '#format_mr_branch_names' do
diff --git a/spec/initializers/load_balancing_spec.rb b/spec/initializers/load_balancing_spec.rb
index d9162acd2cd..66aaa52eef2 100644
--- a/spec/initializers/load_balancing_spec.rb
+++ b/spec/initializers/load_balancing_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'load_balancing', :delete, :reestablished_active_record_base do
+RSpec.describe 'load_balancing', :delete, :reestablished_active_record_base, feature_category: :pods do
subject(:initialize_load_balancer) do
load Rails.root.join('config/initializers/load_balancing.rb')
end
diff --git a/spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb b/spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb
index 2dea0aef4cf..ec0bda3c300 100644
--- a/spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb
+++ b/spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::Cache::Ci::ProjectPipelineStatus, :clean_gitlab_redis_cache do
+RSpec.describe Gitlab::Cache::Ci::ProjectPipelineStatus, :clean_gitlab_redis_cache, feature_category: :continuous_integration do
let_it_be(:project) { create(:project, :repository) }
let(:pipeline_status) { described_class.new(project) }
diff --git a/spec/lib/gitlab/ci/trace/archive_spec.rb b/spec/lib/gitlab/ci/trace/archive_spec.rb
index 582c4ad343f..cce6477b91e 100644
--- a/spec/lib/gitlab/ci/trace/archive_spec.rb
+++ b/spec/lib/gitlab/ci/trace/archive_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::Ci::Trace::Archive do
+RSpec.describe Gitlab::Ci::Trace::Archive, feature_category: :scalability do
context 'with transactional fixtures' do
let_it_be_with_reload(:job) { create(:ci_build, :success, :trace_live) }
let_it_be_with_reload(:trace_metadata) { create(:ci_build_trace_metadata, build: job) }
diff --git a/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb b/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb
index 92ffeee8509..f85fb1540d9 100644
--- a/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::CycleAnalytics::StageSummary do
+RSpec.describe Gitlab::CycleAnalytics::StageSummary, feature_category: :devops_reports do
include CycleAnalyticsHelpers
let_it_be(:project) { create(:project, :repository) }
diff --git a/spec/lib/gitlab/database/load_balancing_spec.rb b/spec/lib/gitlab/database/load_balancing_spec.rb
index 1c85abac91c..59e16e6ca8b 100644
--- a/spec/lib/gitlab/database/load_balancing_spec.rb
+++ b/spec/lib/gitlab/database/load_balancing_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::Database::LoadBalancing, :suppress_gitlab_schemas_validate_connection do
+RSpec.describe Gitlab::Database::LoadBalancing, :suppress_gitlab_schemas_validate_connection, feature_category: :pods do
describe '.base_models' do
it 'returns the models to apply load balancing to' do
models = described_class.base_models
diff --git a/spec/lib/gitlab/database/migrations/timeout_helpers_spec.rb b/spec/lib/gitlab/database/migrations/timeout_helpers_spec.rb
index d35211af680..ee63ea7174b 100644
--- a/spec/lib/gitlab/database/migrations/timeout_helpers_spec.rb
+++ b/spec/lib/gitlab/database/migrations/timeout_helpers_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::Database::Migrations::TimeoutHelpers do
+RSpec.describe Gitlab::Database::Migrations::TimeoutHelpers, feature_category: :database do
let(:model) do
ActiveRecord::Migration.new.extend(described_class)
end
diff --git a/spec/lib/gitlab/database/reflection_spec.rb b/spec/lib/gitlab/database/reflection_spec.rb
index 389e93364c8..779bdbe50f0 100644
--- a/spec/lib/gitlab/database/reflection_spec.rb
+++ b/spec/lib/gitlab/database/reflection_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::Database::Reflection do
+RSpec.describe Gitlab::Database::Reflection, feature_category: :database do
let(:database) { described_class.new(ApplicationRecord) }
describe '#username' do
diff --git a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb
index 1edcd890370..2cb84e2f02a 100644
--- a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb
+++ b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameBase, :delete do
+RSpec.describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameBase, :delete, feature_category: :subgroups do
let(:migration) { FakeRenameReservedPathMigrationV1.new }
let(:subject) { described_class.new(['the-path'], migration) }
diff --git a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb
index c507bce634e..5b5661020b0 100644
--- a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb
+++ b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb
@@ -2,7 +2,8 @@
require 'spec_helper'
-RSpec.describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces, :delete do
+RSpec.describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces, :delete,
+feature_category: :subgroups do
let(:migration) { FakeRenameReservedPathMigrationV1.new }
let(:subject) { described_class.new(['the-path'], migration) }
let(:namespace) { create(:group, name: 'the-path') }
diff --git a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb
index aa2a3329477..787c9e87038 100644
--- a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb
+++ b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb
@@ -2,7 +2,8 @@
require 'spec_helper'
-RSpec.describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameProjects, :delete do
+RSpec.describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameProjects, :delete,
+feature_category: :projects do
let(:migration) { FakeRenameReservedPathMigrationV1.new }
let(:subject) { described_class.new(['the-path'], migration) }
let(:project) do
diff --git a/spec/lib/gitlab/database/transaction/observer_spec.rb b/spec/lib/gitlab/database/transaction/observer_spec.rb
index 074c18d406e..d1cb014a594 100644
--- a/spec/lib/gitlab/database/transaction/observer_spec.rb
+++ b/spec/lib/gitlab/database/transaction/observer_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::Database::Transaction::Observer do
+RSpec.describe Gitlab::Database::Transaction::Observer, feature_category: :database do
# Use the delete DB strategy so that the test won't be wrapped in a transaction
describe '.instrument_transactions', :delete do
let(:transaction_context) { ActiveRecord::Base.connection.transaction_manager.transaction_context }
diff --git a/spec/lib/gitlab/database/with_lock_retries_outside_transaction_spec.rb b/spec/lib/gitlab/database/with_lock_retries_outside_transaction_spec.rb
index 836332524a9..9ccae754a92 100644
--- a/spec/lib/gitlab/database/with_lock_retries_outside_transaction_spec.rb
+++ b/spec/lib/gitlab/database/with_lock_retries_outside_transaction_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::Database::WithLockRetriesOutsideTransaction do
+RSpec.describe Gitlab::Database::WithLockRetriesOutsideTransaction, feature_category: :database do
let(:env) { {} }
let(:logger) { Gitlab::Database::WithLockRetries::NULL_LOGGER }
let(:subject) { described_class.new(connection: connection, env: env, logger: logger, timing_configuration: timing_configuration) }
diff --git a/spec/lib/gitlab/database/with_lock_retries_spec.rb b/spec/lib/gitlab/database/with_lock_retries_spec.rb
index 797a01c482d..7fe6362634b 100644
--- a/spec/lib/gitlab/database/with_lock_retries_spec.rb
+++ b/spec/lib/gitlab/database/with_lock_retries_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::Database::WithLockRetries do
+RSpec.describe Gitlab::Database::WithLockRetries, feature_category: :database do
let(:env) { {} }
let(:logger) { Gitlab::Database::WithLockRetries::NULL_LOGGER }
let(:subject) { described_class.new(connection: connection, env: env, logger: logger, allow_savepoints: allow_savepoints, timing_configuration: timing_configuration) }
diff --git a/spec/lib/gitlab/metrics/subscribers/load_balancing_spec.rb b/spec/lib/gitlab/metrics/subscribers/load_balancing_spec.rb
index 7f7efaffd9e..b401b7cc996 100644
--- a/spec/lib/gitlab/metrics/subscribers/load_balancing_spec.rb
+++ b/spec/lib/gitlab/metrics/subscribers/load_balancing_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::Metrics::Subscribers::LoadBalancing, :request_store do
+RSpec.describe Gitlab::Metrics::Subscribers::LoadBalancing, :request_store, feature_category: :pods do
let(:subscriber) { described_class.new }
describe '#caught_up_replica_pick' do
diff --git a/spec/migrations/20221122132812_schedule_prune_stale_project_export_jobs_spec.rb b/spec/migrations/20221122132812_schedule_prune_stale_project_export_jobs_spec.rb
index 5a5bc42a37b..9eaab56de7c 100644
--- a/spec/migrations/20221122132812_schedule_prune_stale_project_export_jobs_spec.rb
+++ b/spec/migrations/20221122132812_schedule_prune_stale_project_export_jobs_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
require_migration!
-RSpec.describe SchedulePruneStaleProjectExportJobs, category: :importers do
+RSpec.describe SchedulePruneStaleProjectExportJobs, feature_category: :importers do
let!(:batched_migration) { described_class::MIGRATION }
it 'schedules a new batched migration' do
diff --git a/spec/migrations/20221205151917_schedule_backfill_environment_tier_spec.rb b/spec/migrations/20221205151917_schedule_backfill_environment_tier_spec.rb
index b76f889d743..e03fd9c9daf 100644
--- a/spec/migrations/20221205151917_schedule_backfill_environment_tier_spec.rb
+++ b/spec/migrations/20221205151917_schedule_backfill_environment_tier_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
require_migration!
-RSpec.describe ScheduleBackfillEnvironmentTier, category: :continuous_delivery do
+RSpec.describe ScheduleBackfillEnvironmentTier, feature_category: :continuous_delivery do
let!(:batched_migration) { described_class::MIGRATION }
it 'schedules a new batched migration' do
diff --git a/spec/migrations/20230214122717_fix_partition_ids_for_ci_job_variables_spec.rb b/spec/migrations/20230214122717_fix_partition_ids_for_ci_job_variables_spec.rb
new file mode 100644
index 00000000000..64275855262
--- /dev/null
+++ b/spec/migrations/20230214122717_fix_partition_ids_for_ci_job_variables_spec.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe FixPartitionIdsForCiJobVariables, migration: :gitlab_ci, feature_category: :continuous_integration do
+ let(:builds) { table(:ci_builds, database: :ci) }
+ let(:job_variables) { table(:ci_job_variables, database: :ci) }
+ let(:connection) { job_variables.connection }
+
+ around do |example|
+ connection.execute "ALTER TABLE #{job_variables.quoted_table_name} DISABLE TRIGGER ALL;"
+
+ example.run
+ ensure
+ connection.execute "ALTER TABLE #{job_variables.quoted_table_name} ENABLE TRIGGER ALL;"
+ end
+
+ before do
+ job = builds.create!(partition_id: 100)
+
+ job_variables.insert_all!([
+ { job_id: job.id, partition_id: 100, key: 'variable-100' },
+ { job_id: job.id, partition_id: 101, key: 'variable-101' }
+ ])
+ end
+
+ describe '#up', :aggregate_failures do
+ context 'when on sass' do
+ before do
+ allow(Gitlab).to receive(:com?).and_return(true)
+ end
+
+ it 'fixes partition_id' do
+ expect { migrate! }.not_to raise_error
+
+ expect(job_variables.where(partition_id: 100).count).to eq(2)
+ expect(job_variables.where(partition_id: 101).count).to eq(0)
+ end
+ end
+
+ context 'when on self managed' do
+ it 'does not change partition_id' do
+ expect { migrate! }.not_to raise_error
+
+ expect(job_variables.where(partition_id: 100).count).to eq(1)
+ expect(job_variables.where(partition_id: 101).count).to eq(1)
+ end
+ end
+ end
+end
diff --git a/spec/models/concerns/pg_full_text_searchable_spec.rb b/spec/models/concerns/pg_full_text_searchable_spec.rb
index 87f1dc5a27b..059df64f7d0 100644
--- a/spec/models/concerns/pg_full_text_searchable_spec.rb
+++ b/spec/models/concerns/pg_full_text_searchable_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe PgFullTextSearchable do
+RSpec.describe PgFullTextSearchable, feature_category: :global_search do
let(:project) { build(:project, project_namespace: build(:project_namespace)) }
let(:model_class) do
diff --git a/spec/models/container_repository_spec.rb b/spec/models/container_repository_spec.rb
index 33d3cabb325..da7b54644bd 100644
--- a/spec/models/container_repository_spec.rb
+++ b/spec/models/container_repository_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe ContainerRepository, :aggregate_failures do
+RSpec.describe ContainerRepository, :aggregate_failures, feature_category: :container_registry do
using RSpec::Parameterized::TableSyntax
let(:group) { create(:group, name: 'group') }
diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb
index e1a08a74ac0..6a52f12553f 100644
--- a/spec/models/member_spec.rb
+++ b/spec/models/member_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Member do
+RSpec.describe Member, feature_category: :subgroups do
include ExclusiveLeaseHelpers
using RSpec::Parameterized::TableSyntax
diff --git a/spec/models/merge_request/cleanup_schedule_spec.rb b/spec/models/merge_request/cleanup_schedule_spec.rb
index 1f1f33db5ed..114413e8880 100644
--- a/spec/models/merge_request/cleanup_schedule_spec.rb
+++ b/spec/models/merge_request/cleanup_schedule_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe MergeRequest::CleanupSchedule do
+RSpec.describe MergeRequest::CleanupSchedule, feature_category: :code_review_workflow do
describe 'associations' do
it { is_expected.to belong_to(:merge_request) }
end
diff --git a/spec/services/groups/destroy_service_spec.rb b/spec/services/groups/destroy_service_spec.rb
index 2791203f395..7c3710aeeb2 100644
--- a/spec/services/groups/destroy_service_spec.rb
+++ b/spec/services/groups/destroy_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Groups::DestroyService do
+RSpec.describe Groups::DestroyService, feature_category: :subgroups do
let!(:user) { create(:user) }
let!(:group) { create(:group) }
let!(:nested_group) { create(:group, parent: group) }
diff --git a/spec/services/issues/move_service_spec.rb b/spec/services/issues/move_service_spec.rb
index 11f4d6a9ed4..12924df3200 100644
--- a/spec/services/issues/move_service_spec.rb
+++ b/spec/services/issues/move_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Issues::MoveService do
+RSpec.describe Issues::MoveService, feature_category: :team_planning do
include DesignManagementTestHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/services/merge_requests/close_service_spec.rb b/spec/services/merge_requests/close_service_spec.rb
index b3c4ed4c544..2c0817550c6 100644
--- a/spec/services/merge_requests/close_service_spec.rb
+++ b/spec/services/merge_requests/close_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe MergeRequests::CloseService do
+RSpec.describe MergeRequests::CloseService, feature_category: :code_review_workflow do
let(:user) { create(:user) }
let(:user2) { create(:user) }
let(:guest) { create(:user) }
diff --git a/spec/services/merge_requests/create_from_issue_service_spec.rb b/spec/services/merge_requests/create_from_issue_service_spec.rb
index 0eefbed252b..7bb0dd723a1 100644
--- a/spec/services/merge_requests/create_from_issue_service_spec.rb
+++ b/spec/services/merge_requests/create_from_issue_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe MergeRequests::CreateFromIssueService do
+RSpec.describe MergeRequests::CreateFromIssueService, feature_category: :code_review_workflow do
include ProjectForksHelper
let(:project) { create(:project, :repository) }
diff --git a/spec/services/merge_requests/create_service_spec.rb b/spec/services/merge_requests/create_service_spec.rb
index 24b15d2b18f..394fc269ac3 100644
--- a/spec/services/merge_requests/create_service_spec.rb
+++ b/spec/services/merge_requests/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe MergeRequests::CreateService, :clean_gitlab_redis_shared_state do
+RSpec.describe MergeRequests::CreateService, :clean_gitlab_redis_shared_state, feature_category: :code_review_workflow do
include ProjectForksHelper
let(:project) { create(:project, :repository) }
diff --git a/spec/services/merge_requests/link_lfs_objects_service_spec.rb b/spec/services/merge_requests/link_lfs_objects_service_spec.rb
index 96cb72baac2..9762b600eab 100644
--- a/spec/services/merge_requests/link_lfs_objects_service_spec.rb
+++ b/spec/services/merge_requests/link_lfs_objects_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe MergeRequests::LinkLfsObjectsService, :sidekiq_inline do
+RSpec.describe MergeRequests::LinkLfsObjectsService, :sidekiq_inline, feature_category: :code_review_workflow do
include ProjectForksHelper
include RepoHelpers
diff --git a/spec/services/merge_requests/pushed_branches_service_spec.rb b/spec/services/merge_requests/pushed_branches_service_spec.rb
index 59424263ec5..cb5d0a6bd25 100644
--- a/spec/services/merge_requests/pushed_branches_service_spec.rb
+++ b/spec/services/merge_requests/pushed_branches_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe MergeRequests::PushedBranchesService do
+RSpec.describe MergeRequests::PushedBranchesService, feature_category: :source_code_management do
let(:project) { create(:project) }
let!(:service) { described_class.new(project: project, current_user: nil, params: { changes: pushed_branches }) }
diff --git a/spec/services/merge_requests/rebase_service_spec.rb b/spec/services/merge_requests/rebase_service_spec.rb
index 316f20d8276..704dc1f9000 100644
--- a/spec/services/merge_requests/rebase_service_spec.rb
+++ b/spec/services/merge_requests/rebase_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe MergeRequests::RebaseService do
+RSpec.describe MergeRequests::RebaseService, feature_category: :source_code_management do
include ProjectForksHelper
let(:user) { create(:user) }
diff --git a/spec/services/merge_requests/retarget_chain_service_spec.rb b/spec/services/merge_requests/retarget_chain_service_spec.rb
index 187dd0cf589..ef8cd0a861e 100644
--- a/spec/services/merge_requests/retarget_chain_service_spec.rb
+++ b/spec/services/merge_requests/retarget_chain_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe MergeRequests::RetargetChainService do
+RSpec.describe MergeRequests::RetargetChainService, feature_category: :code_review_workflow do
include ProjectForksHelper
let_it_be(:user) { create(:user) }
diff --git a/spec/services/pages/migrate_from_legacy_storage_service_spec.rb b/spec/services/pages/migrate_from_legacy_storage_service_spec.rb
index d058324f3bb..4348ce4a271 100644
--- a/spec/services/pages/migrate_from_legacy_storage_service_spec.rb
+++ b/spec/services/pages/migrate_from_legacy_storage_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Pages::MigrateFromLegacyStorageService do
+RSpec.describe Pages::MigrateFromLegacyStorageService, feature_category: :pages do
let(:batch_size) { 10 }
let(:mark_projects_as_not_deployed) { false }
let(:service) { described_class.new(Rails.logger, ignore_invalid_entries: false, mark_projects_as_not_deployed: mark_projects_as_not_deployed) }
diff --git a/spec/services/projects/destroy_service_spec.rb b/spec/services/projects/destroy_service_spec.rb
index 05f699ed357..0689a65c2f4 100644
--- a/spec/services/projects/destroy_service_spec.rb
+++ b/spec/services/projects/destroy_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Projects::DestroyService, :aggregate_failures, :event_store_publisher do
+RSpec.describe Projects::DestroyService, :aggregate_failures, :event_store_publisher, feature_category: :projects do
include ProjectForksHelper
include BatchDestroyDependentAssociationsHelper
diff --git a/spec/support/models/ci/partitioning_testing/schema_helpers.rb b/spec/support/models/ci/partitioning_testing/schema_helpers.rb
index 3a79ed1b5a9..4107bbcb976 100644
--- a/spec/support/models/ci/partitioning_testing/schema_helpers.rb
+++ b/spec/support/models/ci/partitioning_testing/schema_helpers.rb
@@ -24,13 +24,13 @@ module Ci
each_partitionable_table do |table_name|
change_column_default(table_name, from: DEFAULT_PARTITION, to: nil, connection: connection)
change_column_default("p_#{table_name}", from: DEFAULT_PARTITION, to: nil, connection: connection)
- create_test_partition(table_name, connection: connection)
+ create_test_partition("p_#{table_name}", connection: connection)
end
end
def teardown(connection: Ci::ApplicationRecord.connection)
each_partitionable_table do |table_name|
- drop_test_partition(table_name, connection: connection)
+ drop_test_partition("p_#{table_name}", connection: connection)
change_column_default(table_name, from: nil, to: DEFAULT_PARTITION, connection: connection)
change_column_default("p_#{table_name}", from: nil, to: DEFAULT_PARTITION, connection: connection)
end
@@ -54,13 +54,13 @@ module Ci
end
def create_test_partition(table_name, connection:)
- return unless table_available?("p_#{table_name}", connection: connection)
+ return unless table_available?(table_name, connection: connection)
drop_test_partition(table_name, connection: connection)
- connection.execute(<<~SQL)
+ connection.execute(<<~SQL.squish)
CREATE TABLE #{full_partition_name(table_name)}
- PARTITION OF p_#{table_name}
+ PARTITION OF #{table_name}
FOR VALUES IN (#{PartitioningTesting::PartitionIdentifiers.ci_testing_partition_id});
SQL
end
@@ -68,7 +68,7 @@ module Ci
def drop_test_partition(table_name, connection:)
return unless table_available?(table_name, connection: connection)
- connection.execute(<<~SQL)
+ connection.execute(<<~SQL.squish)
DROP TABLE IF EXISTS #{full_partition_name(table_name)};
SQL
end
@@ -79,7 +79,12 @@ module Ci
end
def full_partition_name(table_name)
- "#{Gitlab::Database::DYNAMIC_PARTITIONS_SCHEMA}._test_gitlab_#{table_name}_partition"
+ [
+ Gitlab::Database::DYNAMIC_PARTITIONS_SCHEMA,
+ '._test_gitlab_',
+ table_name.delete_prefix('p_'),
+ '_partition'
+ ].join('')
end
end
end
diff --git a/spec/views/projects/commit/show.html.haml_spec.rb b/spec/views/projects/commit/show.html.haml_spec.rb
index 5fe89102be3..eba54628215 100644
--- a/spec/views/projects/commit/show.html.haml_spec.rb
+++ b/spec/views/projects/commit/show.html.haml_spec.rb
@@ -79,7 +79,7 @@ RSpec.describe 'projects/commit/show.html.haml', feature_category: :source_code_
context 'when commit is signed' do
let(:page) { Nokogiri::HTML.parse(rendered) }
- let(:badge) { page.at('.gpg-status-box') }
+ let(:badge) { page.at('.signature-badge') }
let(:badge_attributes) { badge.attributes }
let(:title) { badge_attributes['data-title'].value }
let(:content) { badge_attributes['data-content'].value }
diff --git a/spec/views/projects/commits/_commit.html.haml_spec.rb b/spec/views/projects/commits/_commit.html.haml_spec.rb
index 4e8a680b6de..90df0d381ed 100644
--- a/spec/views/projects/commits/_commit.html.haml_spec.rb
+++ b/spec/views/projects/commits/_commit.html.haml_spec.rb
@@ -39,7 +39,7 @@ RSpec.describe 'projects/commits/_commit.html.haml' do
commit: commit
}
- within '.gpg-status-box' do
+ within '.signature-badge' do
expect(page).not_to have_css('.gl-spinner')
end
end
diff --git a/spec/views/projects/merge_requests/_commits.html.haml_spec.rb b/spec/views/projects/merge_requests/_commits.html.haml_spec.rb
index 90ee6638142..4ce6755b89d 100644
--- a/spec/views/projects/merge_requests/_commits.html.haml_spec.rb
+++ b/spec/views/projects/merge_requests/_commits.html.haml_spec.rb
@@ -37,6 +37,6 @@ RSpec.describe 'projects/merge_requests/_commits.html.haml', :sidekiq_might_not_
it 'shows signature verification badge' do
render
- expect(rendered).to have_css('.gpg-status-box')
+ expect(rendered).to have_css('.js-loading-signature-badge')
end
end
diff --git a/spec/views/projects/merge_requests/creations/_new_submit.html.haml_spec.rb b/spec/views/projects/merge_requests/creations/_new_submit.html.haml_spec.rb
index feb82e6a2b2..38f4daf7feb 100644
--- a/spec/views/projects/merge_requests/creations/_new_submit.html.haml_spec.rb
+++ b/spec/views/projects/merge_requests/creations/_new_submit.html.haml_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'projects/merge_requests/creations/_new_submit.html.haml' do
+RSpec.describe 'projects/merge_requests/creations/_new_submit.html.haml', feature_category: :code_review_workflow do
let(:merge_request) { create(:merge_request) }
let!(:pipeline) { create(:ci_empty_pipeline) }
diff --git a/spec/workers/ci/external_pull_requests/create_pipeline_worker_spec.rb b/spec/workers/ci/external_pull_requests/create_pipeline_worker_spec.rb
index a637ac088ff..1f20729a821 100644
--- a/spec/workers/ci/external_pull_requests/create_pipeline_worker_spec.rb
+++ b/spec/workers/ci/external_pull_requests/create_pipeline_worker_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Ci::ExternalPullRequests::CreatePipelineWorker do
+RSpec.describe Ci::ExternalPullRequests::CreatePipelineWorker, feature_category: :continuous_integration do
let_it_be(:project) { create(:project, :auto_devops, :repository) }
let_it_be(:user) { project.first_owner }
let_it_be(:external_pull_request) do