summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-05-15 09:08:57 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2023-05-15 09:08:57 +0000
commit45a8c43afe8a17de19a92708b380b29b6ae04ce6 (patch)
tree4104e6ac741fbbdeefe9b8b699650a06c14e9056
parent6bc327a3491069240bd73cc83e17b3078c4148b0 (diff)
downloadgitlab-ce-45a8c43afe8a17de19a92708b380b29b6ae04ce6.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.gitlab/ci/qa-common/main.gitlab-ci.yml11
-rw-r--r--.rubocop_todo/layout/argument_alignment.yml33
-rw-r--r--.rubocop_todo/rails/pluck.yml10
-rw-r--r--Gemfile1
-rw-r--r--Gemfile.checksum1
-rw-r--r--Gemfile.lock2
-rw-r--r--app/assets/javascripts/alerts_settings/constants.js2
-rw-r--r--app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/image_item.vue51
-rw-r--r--app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/job_setup_item.vue1
-rw-r--r--app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/services_item.vue6
-rw-r--r--app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/constants.js23
-rw-r--r--app/assets/javascripts/pages/projects/project.js7
-rw-r--r--app/controllers/groups/milestones_controller.rb28
-rw-r--r--app/controllers/projects/milestones_controller.rb28
-rw-r--r--app/finders/template_finder.rb15
-rw-r--r--app/graphql/mutations/metrics/dashboard/annotations/create.rb2
-rw-r--r--app/graphql/mutations/metrics/dashboard/annotations/delete.rb2
-rw-r--r--app/graphql/resolvers/metrics/dashboards/annotation_resolver.rb1
-rw-r--r--app/graphql/resolvers/projects/branches_tipping_at_commit_resolver.rb20
-rw-r--r--app/graphql/resolvers/projects/commit_parent_names_resolver.rb33
-rw-r--r--app/graphql/resolvers/projects/commit_references_resolver.rb29
-rw-r--r--app/graphql/resolvers/projects/ref_tipping_at_commit_resolver.rb25
-rw-r--r--app/graphql/resolvers/projects/tags_tipping_at_commit_resolver.rb20
-rw-r--r--app/graphql/types/commit_references_type.rb67
-rw-r--r--app/graphql/types/mutation_type.rb10
-rw-r--r--app/graphql/types/permission_types/issue.rb2
-rw-r--r--app/graphql/types/project_statistics_redirect_type.rb27
-rw-r--r--app/graphql/types/project_type.rb32
-rw-r--r--app/graphql/types/projects/commit_parent_names_type.rb1
-rw-r--r--app/helpers/projects_helper.rb8
-rw-r--r--app/models/blob_viewer/metrics_dashboard_yml.rb4
-rw-r--r--app/models/commit.rb35
-rw-r--r--app/models/container_registry/data_repair_detail.rb6
-rw-r--r--app/models/project.rb6
-rw-r--r--app/services/jira_connect/sync_service.rb4
-rw-r--r--app/views/clusters/clusters/_integrations.html.haml2
-rw-r--r--app/views/groups/milestones/_form.html.haml6
-rw-r--r--app/views/projects/mattermosts/_team_selection.html.haml7
-rw-r--r--app/views/projects/milestones/_form.html.haml6
-rw-r--r--app/views/projects/show.html.haml1
-rw-r--r--app/views/shared/_captcha_check.html.haml4
-rw-r--r--app/views/shared/_model_version_conflict.html.haml6
-rw-r--r--app/views/shared/doorkeeper/applications/_form.html.haml2
-rw-r--r--app/views/shared/integrations/prometheus/_custom_metrics.html.haml2
-rw-r--r--app/views/shared/integrations/prometheus/_metrics.html.haml2
-rw-r--r--app/views/shared/issuable/_form.html.haml10
-rw-r--r--app/workers/all_queues.yml9
-rw-r--r--app/workers/container_registry/cleanup_worker.rb24
-rw-r--r--app/workers/container_registry/record_data_repair_detail_worker.rb87
-rw-r--r--config/feature_flags/development/mobile_devops_projects_promo.yml8
-rw-r--r--config/feature_flags/development/registry_data_repair_worker.yml8
-rw-r--r--config/feature_flags/development/remove_monitor_metrics.yml2
-rw-r--r--db/migrate/20230404160131_add_status_to_data_repair_details.rb20
-rw-r--r--db/migrate/20230505122015_add_lock_version_to_milestones.rb9
-rw-r--r--db/post_migrate/20230425521418_drop_merge_request_mentions_temp_index.rb16
-rw-r--r--db/schema_migrations/202304041601311
-rw-r--r--db/schema_migrations/202304255214181
-rw-r--r--db/schema_migrations/202305051220151
-rw-r--r--db/structure.sql10
-rw-r--r--doc/administration/housekeeping.md31
-rw-r--r--doc/administration/raketasks/maintenance.md2
-rw-r--r--doc/api/graphql/reference/index.md120
-rw-r--r--doc/api/packages.md65
-rw-r--r--doc/development/ai_features.md69
-rw-r--r--doc/development/features_inside_dot_gitlab.md1
-rw-r--r--doc/development/internal_users.md2
-rw-r--r--doc/development/sec/CycloneDX_property_taxonomy.md72
-rw-r--r--doc/operations/incident_management/alerts.md25
-rw-r--r--doc/operations/incident_management/incidents.md7
-rw-r--r--doc/operations/incident_management/manage_incidents.md16
-rw-r--r--doc/operations/incident_management/slack.md2
-rw-r--r--doc/operations/index.md26
-rw-r--r--doc/operations/metrics/alerts.md80
-rw-r--r--doc/operations/metrics/dashboards/default.md41
-rw-r--r--doc/operations/metrics/dashboards/develop.md37
-rw-r--r--doc/operations/metrics/dashboards/img/actions_menu_create_add_panel_v13_3.pngbin9982 -> 0 bytes
-rw-r--r--doc/operations/metrics/dashboards/img/actions_menu_create_new_dashboard_v13_3.pngbin14957 -> 0 bytes
-rw-r--r--doc/operations/metrics/dashboards/img/dashboard_external_link_v13_1.pngbin12708 -> 0 bytes
-rw-r--r--doc/operations/metrics/dashboards/img/dashboard_local_timezone_v13_1.pngbin65094 -> 0 bytes
-rw-r--r--doc/operations/metrics/dashboards/img/external_dashboard_link.pngbin20192 -> 0 bytes
-rw-r--r--doc/operations/metrics/dashboards/img/heatmap_chart_too_much_data_v_13_2.pngbin7310 -> 0 bytes
-rw-r--r--doc/operations/metrics/dashboards/img/heatmap_panel_type.pngbin8272 -> 0 bytes
-rw-r--r--doc/operations/metrics/dashboards/img/k8s_pod_health_dashboard_v13_3.pngbin60933 -> 0 bytes
-rw-r--r--doc/operations/metrics/dashboards/img/metrics_dashboard_annotations_ui_v13.0.pngbin31654 -> 0 bytes
-rw-r--r--doc/operations/metrics/dashboards/img/metrics_dashboard_panel_preview_v13_3.pngbin45857 -> 0 bytes
-rw-r--r--doc/operations/metrics/dashboards/img/metrics_dashboard_template_selection_v13_3.pngbin9033 -> 0 bytes
-rw-r--r--doc/operations/metrics/dashboards/img/metrics_dashboard_template_selection_web_ide_v13_3.pngbin26123 -> 0 bytes
-rw-r--r--doc/operations/metrics/dashboards/img/panel_context_menu_v14_0.pngbin11084 -> 0 bytes
-rw-r--r--doc/operations/metrics/dashboards/img/prometheus_dashboard_anomaly_panel_type.pngbin41015 -> 0 bytes
-rw-r--r--doc/operations/metrics/dashboards/img/prometheus_dashboard_area_panel_type_v12_8.pngbin53370 -> 0 bytes
-rw-r--r--doc/operations/metrics/dashboards/img/prometheus_dashboard_bar_chart_panel_type_v12.10.pngbin4761 -> 0 bytes
-rw-r--r--doc/operations/metrics/dashboards/img/prometheus_dashboard_column_panel_type.pngbin13219 -> 0 bytes
-rw-r--r--doc/operations/metrics/dashboards/img/prometheus_dashboard_gauge_panel_type_v13_3.pngbin17303 -> 0 bytes
-rw-r--r--doc/operations/metrics/dashboards/img/prometheus_dashboard_label_variable_shorthand.pngbin3897 -> 0 bytes
-rw-r--r--doc/operations/metrics/dashboards/img/prometheus_dashboard_label_variables.pngbin8076 -> 0 bytes
-rw-r--r--doc/operations/metrics/dashboards/img/prometheus_dashboard_repeated_label.pngbin3116 -> 0 bytes
-rw-r--r--doc/operations/metrics/dashboards/img/prometheus_dashboard_single_stat_panel_type.pngbin6871 -> 0 bytes
-rw-r--r--doc/operations/metrics/dashboards/img/prometheus_dashboard_stacked_column_panel_type_v12_8.pngbin13898 -> 0 bytes
-rw-r--r--doc/operations/metrics/dashboards/img/prometheus_dashboard_yaml_validation_v13_1.pngbin27694 -> 0 bytes
-rw-r--r--doc/operations/metrics/dashboards/img/related_links_v13_1.pngbin4086 -> 0 bytes
-rw-r--r--doc/operations/metrics/dashboards/index.md266
-rw-r--r--doc/operations/metrics/dashboards/panel_types.md315
-rw-r--r--doc/operations/metrics/dashboards/settings.md56
-rw-r--r--doc/operations/metrics/dashboards/templating_variables.md131
-rw-r--r--doc/operations/metrics/dashboards/variables.md76
-rw-r--r--doc/operations/metrics/dashboards/yaml.md178
-rw-r--r--doc/operations/metrics/dashboards/yaml_number_format.md175
-rw-r--r--doc/operations/metrics/embed.md124
-rw-r--r--doc/operations/metrics/embed_grafana.md91
-rw-r--r--doc/operations/metrics/img/copy_link_to_chart_v12_10.pngbin21559 -> 0 bytes
-rw-r--r--doc/operations/metrics/img/embed_metrics_issue_template.pngbin43908 -> 0 bytes
-rw-r--r--doc/operations/metrics/img/embedded_metrics_rendered_v13_4.pngbin24072 -> 0 bytes
-rw-r--r--doc/operations/metrics/img/example-dashboard_v13_3.pngbin64275 -> 0 bytes
-rw-r--r--doc/operations/metrics/img/hide_embedded_metrics_v12_10.pngbin21312 -> 0 bytes
-rw-r--r--doc/operations/metrics/img/prometheus_add_metric.pngbin24607 -> 0 bytes
-rw-r--r--doc/operations/metrics/img/prometheus_cluster_health_embed_v12_9.pngbin50178 -> 0 bytes
-rw-r--r--doc/operations/metrics/img/prometheus_dashboard_edit_metric_link_v_12_9.pngbin29178 -> 0 bytes
-rw-r--r--doc/operations/metrics/img/prometheus_monitoring_dashboard_v13_3.pngbin64275 -> 0 bytes
-rw-r--r--doc/operations/metrics/img/rendered_grafana_embed_v12_5.pngbin61194 -> 0 bytes
-rw-r--r--doc/operations/metrics/img/view_embedded_metrics_v12_10.pngbin36717 -> 0 bytes
-rw-r--r--doc/operations/metrics/index.md165
-rw-r--r--doc/raketasks/restore_gitlab.md1
-rw-r--r--doc/topics/autodevops/requirements.md20
-rw-r--r--doc/topics/autodevops/stages.md3
-rw-r--r--doc/user/ai_features.md32
-rw-r--r--doc/user/application_security/policies/scan-result-policies.md1
-rw-r--r--doc/user/clusters/cost_management.md79
-rw-r--r--doc/user/clusters/integrations.md98
-rw-r--r--doc/user/img/explain_this_vulnerability.pngbin0 -> 371791 bytes
-rw-r--r--doc/user/infrastructure/clusters/manage/clusters_health.md17
-rw-r--r--doc/user/infrastructure/clusters/manage/img/k8s_cluster_monitoring.pngbin43141 -> 0 bytes
-rw-r--r--doc/user/project/integrations/prometheus.md128
-rw-r--r--doc/user/project/integrations/prometheus_library/cloudwatch.md47
-rw-r--r--doc/user/project/integrations/prometheus_library/haproxy.md33
-rw-r--r--doc/user/project/integrations/prometheus_library/index.md42
-rw-r--r--doc/user/project/integrations/prometheus_library/kubernetes.md65
-rw-r--r--doc/user/project/integrations/prometheus_library/nginx.md41
-rw-r--r--doc/user/project/integrations/prometheus_library/nginx_ingress.md47
-rw-r--r--doc/user/project/integrations/prometheus_library/nginx_ingress_vts.md45
-rw-r--r--doc/user/project/integrations/webhook_events.md1
-rw-r--r--doc/user/project/settings/index.md2
-rw-r--r--doc/user/shortcuts.md1
-rw-r--r--lib/api/entities/package.rb6
-rw-r--r--lib/api/metrics/dashboard/annotations.rb2
-rw-r--r--lib/api/project_templates.rb4
-rw-r--r--lib/container_registry/gitlab_api_client.rb27
-rw-r--r--lib/gitlab/data_builder/deployment.rb1
-rw-r--r--lib/gitlab/database/migrations/instrumentation.rb2
-rw-r--r--lib/gitlab/database/migrations/observation.rb2
-rw-r--r--lib/gitlab/database/schema_validation/inconsistency.rb12
-rw-r--r--lib/gitlab/database/schema_validation/track_inconsistency.rb31
-rw-r--r--locale/gitlab.pot38
-rw-r--r--qa/Gemfile6
-rw-r--r--qa/Gemfile.lock14
-rw-r--r--spec/controllers/groups/milestones_controller_spec.rb15
-rw-r--r--spec/controllers/projects/milestones_controller_spec.rb21
-rw-r--r--spec/factories/container_registry/data_repair_detail.rb20
-rw-r--r--spec/features/groups/milestones/milestone_editing_spec.rb18
-rw-r--r--spec/features/issues/user_edits_issue_spec.rb14
-rw-r--r--spec/features/merge_request/user_edits_mr_spec.rb12
-rw-r--r--spec/features/projects/blobs/blob_show_spec.rb13
-rw-r--r--spec/features/projects/integrations/user_activates_mattermost_slash_command_spec.rb4
-rw-r--r--spec/features/projects/milestones/milestone_editing_spec.rb18
-rw-r--r--spec/finders/template_finder_spec.rb14
-rw-r--r--spec/frontend/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/image_item_spec.js8
-rw-r--r--spec/frontend/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/services_item_spec.js2
-rw-r--r--spec/graphql/resolvers/metrics/dashboards/annotation_resolver_spec.rb16
-rw-r--r--spec/graphql/types/permission_types/issue_spec.rb2
-rw-r--r--spec/graphql/types/project_statistics_redirect_type_spec.rb10
-rw-r--r--spec/graphql/types/project_type_spec.rb2
-rw-r--r--spec/helpers/projects_helper_spec.rb28
-rw-r--r--spec/lib/api/entities/package_spec.rb9
-rw-r--r--spec/lib/container_registry/gitlab_api_client_spec.rb155
-rw-r--r--spec/lib/gitlab/background_migration/backfill_cluster_agents_has_vulnerabilities_spec.rb10
-rw-r--r--spec/lib/gitlab/background_migration/backfill_environment_tiers_spec.rb10
-rw-r--r--spec/lib/gitlab/background_migration/backfill_group_features_spec.rb18
-rw-r--r--spec/lib/gitlab/background_migration/backfill_imported_issue_search_data_spec.rb16
-rw-r--r--spec/lib/gitlab/background_migration/backfill_namespace_details_spec.rb43
-rw-r--r--spec/lib/gitlab/background_migration/backfill_namespace_id_for_namespace_route_spec.rb35
-rw-r--r--spec/lib/gitlab/background_migration/backfill_namespace_id_of_vulnerability_reads_spec.rb17
-rw-r--r--spec/lib/gitlab/background_migration/backfill_project_feature_package_registry_access_level_spec.rb17
-rw-r--r--spec/lib/gitlab/background_migration/backfill_project_member_namespace_id_spec.rb70
-rw-r--r--spec/lib/gitlab/background_migration/backfill_project_namespace_details_spec.rb47
-rw-r--r--spec/lib/gitlab/background_migration/backfill_releases_author_id_spec.rb59
-rw-r--r--spec/lib/gitlab/background_migration/backfill_snippet_repositories_spec.rb66
-rw-r--r--spec/lib/gitlab/background_migration/backfill_vulnerability_reads_cluster_agent_spec.rb10
-rw-r--r--spec/lib/gitlab/background_migration/nullify_orphan_runner_id_on_ci_builds_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/prune_stale_project_export_jobs_spec.rb17
-rw-r--r--spec/lib/gitlab/background_migration/remove_backfilled_job_artifacts_expire_at_spec.rb6
-rw-r--r--spec/lib/gitlab/background_migration/remove_occurrence_pipelines_and_duplicate_vulnerabilities_findings_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/remove_self_managed_wiki_notes_spec.rb17
-rw-r--r--spec/lib/gitlab/background_migration/reset_too_many_tags_skipped_registry_imports_spec.rb72
-rw-r--r--spec/lib/gitlab/background_migration/set_correct_vulnerability_state_spec.rb16
-rw-r--r--spec/lib/gitlab/background_migration/set_legacy_open_source_license_available_for_non_public_projects_spec.rb33
-rw-r--r--spec/lib/gitlab/background_migration/update_delayed_project_removal_to_null_for_user_namespaces_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/update_jira_tracker_data_deployment_type_based_on_url_spec.rb10
-rw-r--r--spec/lib/gitlab/data_builder/deployment_spec.rb3
-rw-r--r--spec/lib/gitlab/database/migrations/instrumentation_spec.rb19
-rw-r--r--spec/lib/gitlab/database/schema_validation/inconsistency_spec.rb26
-rw-r--r--spec/lib/gitlab/import_export/all_models.yml1
-rw-r--r--spec/models/blob_viewer/metrics_dashboard_yml_spec.rb16
-rw-r--r--spec/models/commit_spec.rb90
-rw-r--r--spec/models/container_registry/data_repair_detail_spec.rb18
-rw-r--r--spec/models/milestone_spec.rb8
-rw-r--r--spec/models/project_spec.rb14
-rw-r--r--spec/requests/api/graphql/metrics/dashboard/annotations_spec.rb17
-rw-r--r--spec/requests/api/graphql/mutations/metrics/dashboard/annotations/create_spec.rb13
-rw-r--r--spec/requests/api/graphql/mutations/metrics/dashboard/annotations/delete_spec.rb13
-rw-r--r--spec/requests/api/graphql/project/branches_tipping_at_commit_spec.rb67
-rw-r--r--spec/requests/api/graphql/project/commit_references_spec.rb240
-rw-r--r--spec/requests/api/graphql/project/project_statistics_redirect_spec.rb78
-rw-r--r--spec/requests/api/graphql/project/tags_tipping_at_commit_spec.rb67
-rw-r--r--spec/requests/api/metrics/dashboard/annotations_spec.rb13
-rw-r--r--spec/requests/api/project_packages_spec.rb12
-rw-r--r--spec/requests/api/project_templates_spec.rb25
-rw-r--r--spec/services/jira_connect/sync_service_spec.rb10
-rw-r--r--spec/support/import_export/export_file_helper.rb22
-rw-r--r--spec/support/shared_examples/controllers/snippets_sort_order_shared_examples.rb10
-rw-r--r--spec/support/shared_examples/controllers/wiki_actions_shared_examples.rb23
-rw-r--r--spec/support/shared_examples/features/editable_merge_request_shared_examples.rb12
-rw-r--r--spec/support/shared_examples/features/milestone_editing_shared_examples.rb21
-rw-r--r--spec/support/shared_examples/features/search/redacted_search_results_shared_examples.rb202
-rw-r--r--spec/support/shared_examples/features/wiki/user_views_wiki_page_shared_examples.rb8
-rw-r--r--spec/support/shared_examples/graphql/members_shared_examples.rb12
-rw-r--r--spec/support/shared_examples/graphql/mutation_shared_examples.rb4
-rw-r--r--spec/support/shared_examples/graphql/mutations/set_assignees_shared_examples.rb10
-rw-r--r--spec/support/shared_examples/graphql/notes_on_noteables_shared_examples.rb8
-rw-r--r--spec/support/shared_examples/requests/api/container_repositories_shared_examples.rb4
-rw-r--r--spec/support/shared_examples/requests/api/custom_attributes_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/requests/api/graphql/packages/group_and_project_packages_list_shared_examples.rb4
-rw-r--r--spec/support/shared_examples/requests/api/graphql/packages/package_details_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/requests/api/labels_api_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/requests/api/milestones_shared_examples.rb8
-rw-r--r--spec/support/shared_examples/requests/api/notes_shared_examples.rb12
-rw-r--r--spec/support/shared_examples/requests/api/repository_storage_moves_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/services/packages_shared_examples.rb18
-rw-r--r--spec/workers/container_registry/cleanup_worker_spec.rb71
-rw-r--r--spec/workers/container_registry/record_data_repair_detail_worker_spec.rb191
-rw-r--r--spec/workers/every_sidekiq_worker_spec.rb1
239 files changed, 2915 insertions, 3278 deletions
diff --git a/.gitlab/ci/qa-common/main.gitlab-ci.yml b/.gitlab/ci/qa-common/main.gitlab-ci.yml
index 025ea61bcdb..21fd7c77573 100644
--- a/.gitlab/ci/qa-common/main.gitlab-ci.yml
+++ b/.gitlab/ci/qa-common/main.gitlab-ci.yml
@@ -206,6 +206,8 @@ stages:
- .ruby-image
stage: report
when: always
+ variables:
+ QA_RSPEC_JSON_FILE_PATTERN: "${CI_PROJECT_DIR}/gitlab-qa-run-*/**/rspec-*.json"
script:
- |
if [ "$SUITE_FAILED" != "true" ] && [ "$SUITE_RAN" == "true" ]; then
@@ -214,7 +216,7 @@ stages:
fi
- |
bundle exec relate-failure-issue \
- --input-files "${CI_PROJECT_DIR}/gitlab-qa-run-*/**/rspec-*.json" \
+ --input-files "${QA_RSPEC_JSON_FILE_PATTERN}" \
--project "gitlab-org/gitlab" \
--token "${QA_RELATE_FAILURE_ISSUE_TOKEN}"
@@ -224,10 +226,12 @@ stages:
- .ruby-image
stage: report
when: always
+ variables:
+ QA_RSPEC_JSON_FILE_PATTERN: "${CI_PROJECT_DIR}/gitlab-qa-run-*/**/rspec-*.json"
script:
- |
bundle exec generate-test-session \
- --input-files "${CI_PROJECT_DIR}/gitlab-qa-run-*/**/rspec-*.json" \
+ --input-files "${QA_RSPEC_JSON_FILE_PATTERN}" \
--project "gitlab-org/quality/testcase-sessions" \
--token "${QA_TEST_SESSION_TOKEN}" \
--ci-project-token "${GENERATE_TEST_SESSION_READ_API_REPORTER_TOKEN}" \
@@ -245,6 +249,7 @@ stages:
- .ruby-image
stage: notify
variables:
+ QA_RSPEC_XML_FILE_PATTERN: "${CI_PROJECT_DIR}/gitlab-qa-run-*/**/rspec-*.xml"
SLACK_ICON_EMOJI: ci_failing
STATUS_SYM: ☠️
STATUS: failed
@@ -256,7 +261,7 @@ stages:
echo "Test suite passed. Exiting..."
exit 0
fi
- - bundle exec prepare-stage-reports --input-files "${CI_PROJECT_DIR}/gitlab-qa-run-*/**/rspec-*.xml"
+ - bundle exec prepare-stage-reports --input-files "${QA_RSPEC_XML_FILE_PATTERN}"
- !reference [.notify-slack-qa, script]
# ==========================================
diff --git a/.rubocop_todo/layout/argument_alignment.yml b/.rubocop_todo/layout/argument_alignment.yml
index 359b6838873..4e4d3537c9e 100644
--- a/.rubocop_todo/layout/argument_alignment.yml
+++ b/.rubocop_todo/layout/argument_alignment.yml
@@ -1979,19 +1979,6 @@ Layout/ArgumentAlignment:
- 'spec/lib/gitlab/auth/otp/strategies/forti_token_cloud_spec.rb'
- 'spec/lib/gitlab/auth/saml/auth_hash_spec.rb'
- 'spec/lib/gitlab/auth/saml/user_spec.rb'
- - 'spec/lib/gitlab/background_migration/backfill_cluster_agents_has_vulnerabilities_spec.rb'
- - 'spec/lib/gitlab/background_migration/backfill_environment_tiers_spec.rb'
- - 'spec/lib/gitlab/background_migration/backfill_group_features_spec.rb'
- - 'spec/lib/gitlab/background_migration/backfill_imported_issue_search_data_spec.rb'
- - 'spec/lib/gitlab/background_migration/backfill_namespace_details_spec.rb'
- - 'spec/lib/gitlab/background_migration/backfill_namespace_id_for_namespace_route_spec.rb'
- - 'spec/lib/gitlab/background_migration/backfill_namespace_id_of_vulnerability_reads_spec.rb'
- - 'spec/lib/gitlab/background_migration/backfill_project_feature_package_registry_access_level_spec.rb'
- - 'spec/lib/gitlab/background_migration/backfill_project_member_namespace_id_spec.rb'
- - 'spec/lib/gitlab/background_migration/backfill_project_namespace_details_spec.rb'
- - 'spec/lib/gitlab/background_migration/backfill_releases_author_id_spec.rb'
- - 'spec/lib/gitlab/background_migration/backfill_snippet_repositories_spec.rb'
- - 'spec/lib/gitlab/background_migration/backfill_vulnerability_reads_cluster_agent_spec.rb'
- 'spec/lib/gitlab/background_migration/batched_migration_job_spec.rb'
- 'spec/lib/gitlab/background_migration/copy_column_using_background_migration_job_spec.rb'
- 'spec/lib/gitlab/background_migration/delete_orphaned_operational_vulnerabilities_spec.rb'
@@ -2010,16 +1997,6 @@ Layout/ArgumentAlignment:
- 'spec/lib/gitlab/background_migration/fix_incoherent_packages_size_on_project_statistics_spec.rb'
- 'spec/lib/gitlab/background_migration/legacy_upload_mover_spec.rb'
- 'spec/lib/gitlab/background_migration/migrate_shimo_confluence_integration_category_spec.rb'
- - 'spec/lib/gitlab/background_migration/nullify_orphan_runner_id_on_ci_builds_spec.rb'
- - 'spec/lib/gitlab/background_migration/prune_stale_project_export_jobs_spec.rb'
- - 'spec/lib/gitlab/background_migration/remove_backfilled_job_artifacts_expire_at_spec.rb'
- - 'spec/lib/gitlab/background_migration/remove_occurrence_pipelines_and_duplicate_vulnerabilities_findings_spec.rb'
- - 'spec/lib/gitlab/background_migration/remove_self_managed_wiki_notes_spec.rb'
- - 'spec/lib/gitlab/background_migration/reset_too_many_tags_skipped_registry_imports_spec.rb'
- - 'spec/lib/gitlab/background_migration/set_correct_vulnerability_state_spec.rb'
- - 'spec/lib/gitlab/background_migration/set_legacy_open_source_license_available_for_non_public_projects_spec.rb'
- - 'spec/lib/gitlab/background_migration/update_delayed_project_removal_to_null_for_user_namespaces_spec.rb'
- - 'spec/lib/gitlab/background_migration/update_jira_tracker_data_deployment_type_based_on_url_spec.rb'
- 'spec/lib/gitlab/bitbucket_import/importer_spec.rb'
- 'spec/lib/gitlab/bitbucket_import/project_creator_spec.rb'
- 'spec/lib/gitlab/bitbucket_import/wiki_formatter_spec.rb'
@@ -2406,16 +2383,6 @@ Layout/ArgumentAlignment:
- 'spec/services/work_items/task_list_reference_removal_service_spec.rb'
- 'spec/services/work_items/widgets/description_service/update_service_spec.rb'
- 'spec/sidekiq/cron/job_gem_dependency_spec.rb'
- - 'spec/support/import_export/export_file_helper.rb'
- - 'spec/support/redis/redis_shared_examples.rb'
- - 'spec/support/shared_examples/controllers/snippets_sort_order_shared_examples.rb'
- - 'spec/support/shared_examples/controllers/wiki_actions_shared_examples.rb'
- - 'spec/support/shared_examples/features/search/redacted_search_results_shared_examples.rb'
- - 'spec/support/shared_examples/features/wiki/user_views_wiki_page_shared_examples.rb'
- - 'spec/support/shared_examples/graphql/members_shared_examples.rb'
- - 'spec/support/shared_examples/graphql/mutation_shared_examples.rb'
- - 'spec/support/shared_examples/graphql/mutations/set_assignees_shared_examples.rb'
- - 'spec/support/shared_examples/graphql/notes_on_noteables_shared_examples.rb'
- 'spec/support/shared_examples/initializers/uses_gitlab_url_blocker_shared_examples.rb'
- 'spec/support/shared_examples/integrations/integration_settings_form.rb'
- 'spec/support/shared_examples/lib/gitlab/ci/ci_trace_shared_examples.rb'
diff --git a/.rubocop_todo/rails/pluck.yml b/.rubocop_todo/rails/pluck.yml
index 0f8a4d54687..4571e1ae19e 100644
--- a/.rubocop_todo/rails/pluck.yml
+++ b/.rubocop_todo/rails/pluck.yml
@@ -272,15 +272,5 @@ Rails/Pluck:
- 'spec/support/helpers/api_helpers.rb'
- 'spec/support/helpers/graphql_helpers.rb'
- 'spec/support/matchers/background_migrations_matchers.rb'
- - 'spec/support/shared_examples/graphql/mutation_shared_examples.rb'
- - 'spec/support/shared_examples/requests/api/container_repositories_shared_examples.rb'
- - 'spec/support/shared_examples/requests/api/custom_attributes_shared_examples.rb'
- - 'spec/support/shared_examples/requests/api/graphql/packages/group_and_project_packages_list_shared_examples.rb'
- - 'spec/support/shared_examples/requests/api/graphql/packages/package_details_shared_examples.rb'
- - 'spec/support/shared_examples/requests/api/labels_api_shared_examples.rb'
- - 'spec/support/shared_examples/requests/api/milestones_shared_examples.rb'
- - 'spec/support/shared_examples/requests/api/notes_shared_examples.rb'
- - 'spec/support/shared_examples/requests/api/repository_storage_moves_shared_examples.rb'
- - 'spec/support/shared_examples/services/packages_shared_examples.rb'
- 'spec/tooling/docs/deprecation_handling_spec.rb'
- 'tooling/docs/deprecation_handling.rb'
diff --git a/Gemfile b/Gemfile
index 4ae407f0a6e..7447bc5648e 100644
--- a/Gemfile
+++ b/Gemfile
@@ -85,7 +85,6 @@ gem 'invisible_captcha', '~> 2.0.0'
gem 'devise-two-factor', '~> 4.0.2'
gem 'rqrcode-rails3', '~> 0.1.7'
gem 'attr_encrypted', '~> 3.2.4', path: 'vendor/gems/attr_encrypted'
-gem 'u2f', '~> 0.2.1'
# GitLab Pages
gem 'validates_hostname', '~> 1.0.11'
diff --git a/Gemfile.checksum b/Gemfile.checksum
index ebb89765d59..ee74a5c948e 100644
--- a/Gemfile.checksum
+++ b/Gemfile.checksum
@@ -652,7 +652,6 @@
{"name":"tty-screen","version":"0.8.1","platform":"ruby","checksum":"6508657c38f32bdca64880abe201ce237d80c94146e1f9b911cba3c7823659a2"},
{"name":"typhoeus","version":"1.4.0","platform":"ruby","checksum":"fff9880d5dc35950e7706cf132fd297f377c049101794be1cf01c95567f642d4"},
{"name":"tzinfo","version":"2.0.6","platform":"ruby","checksum":"8daf828cc77bcf7d63b0e3bdb6caa47e2272dcfaf4fbfe46f8c3a9df087a829b"},
-{"name":"u2f","version":"0.2.1","platform":"ruby","checksum":"7907b163c00682ce94d82178154af2ec3930e50f342c3502d64929c6370c5553"},
{"name":"uber","version":"0.1.0","platform":"ruby","checksum":"5beeb407ff807b5db994f82fa9ee07cfceaa561dad8af20be880bc67eba935dc"},
{"name":"undercover","version":"0.4.5","platform":"ruby","checksum":"27bb5d708e253e2c1a3f3edd3668a30728f0e59a1e18004b623d5e7b1e86f3b9"},
{"name":"unf","version":"0.1.4","platform":"java","checksum":"49a5972ec0b3d091d3b0b2e00113f2f342b9b212f0db855eb30a629637f6d302"},
diff --git a/Gemfile.lock b/Gemfile.lock
index d26ca466ce6..b85499d79ec 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1569,7 +1569,6 @@ GEM
ethon (>= 0.9.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
- u2f (0.2.1)
uber (0.1.0)
undercover (0.4.5)
imagen (>= 0.1.8)
@@ -1947,7 +1946,6 @@ DEPENDENCIES
toml-rb (~> 2.2.0)
truncato (~> 0.7.12)
typhoeus (~> 1.4.0)
- u2f (~> 0.2.1)
undercover (~> 0.4.4)
unf (~> 0.1.4)
unleash (~> 3.2.2)
diff --git a/app/assets/javascripts/alerts_settings/constants.js b/app/assets/javascripts/alerts_settings/constants.js
index de7240009bc..6d914fe8361 100644
--- a/app/assets/javascripts/alerts_settings/constants.js
+++ b/app/assets/javascripts/alerts_settings/constants.js
@@ -185,6 +185,6 @@ export const I18N_ALERT_SETTINGS_FORM = {
export const NO_ISSUE_TEMPLATE_SELECTED = { value: '', text: __('No template selected') };
export const TAKING_INCIDENT_ACTION_DOCS_LINK =
- '/help/operations/metrics/alerts#trigger-actions-from-alerts';
+ '/help/operations/incident_management/alerts#trigger-actions-from-alerts';
export const ISSUE_TEMPLATES_DOCS_LINK =
'/help/user/project/description_templates#create-an-issue-template';
diff --git a/app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/image_item.vue b/app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/image_item.vue
index c23a0b866d3..b4b468987d8 100644
--- a/app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/image_item.vue
+++ b/app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/image_item.vue
@@ -1,12 +1,14 @@
<script>
-import { GlFormGroup, GlAccordionItem, GlFormInput } from '@gitlab/ui';
+import { GlFormGroup, GlAccordionItem, GlFormInput, GlFormTextarea } from '@gitlab/ui';
import { i18n } from '../constants';
export default {
i18n,
+ placeholderText: i18n.ENTRYPOINT_PLACEHOLDER_TEXT,
components: {
GlAccordionItem,
GlFormInput,
+ GlFormTextarea,
GlFormGroup,
},
props: {
@@ -15,31 +17,34 @@ export default {
required: true,
},
},
+ computed: {
+ imageEntryPoint() {
+ return this.job.image.entrypoint.join('\n');
+ },
+ },
};
</script>
<template>
<gl-accordion-item :title="$options.i18n.IMAGE">
- <div class="gl-display-flex">
- <gl-form-group
- class="gl-flex-grow-1 gl-flex-basis-half gl-mr-3"
- :label="$options.i18n.IMAGE_NAME"
- >
- <gl-form-input
- :value="job.image.name"
- data-testid="image-name-input"
- @input="$emit('update-job', 'image.name', $event)"
- />
- </gl-form-group>
- <gl-form-group
- class="gl-flex-grow-1 gl-flex-basis-half"
- :label="$options.i18n.IMAGE_ENTRYPOINT"
- >
- <gl-form-input
- :value="job.image.entrypoint.join(' ')"
- data-testid="image-entrypoint-input"
- @input="$emit('update-job', 'image.entrypoint', $event.split(' '))"
- />
- </gl-form-group>
- </div>
+ <gl-form-group :label="$options.i18n.IMAGE_NAME">
+ <gl-form-input
+ :value="job.image.name"
+ data-testid="image-name-input"
+ @input="$emit('update-job', 'image.name', $event)"
+ />
+ </gl-form-group>
+ <gl-form-group
+ :label="$options.i18n.IMAGE_ENTRYPOINT"
+ :description="$options.i18n.ARRAY_FIELD_DESCRIPTION"
+ class="gl-mb-0"
+ >
+ <gl-form-textarea
+ :no-resize="false"
+ :placeholder="$options.placeholderText"
+ data-testid="image-entrypoint-input"
+ :value="imageEntryPoint"
+ @input="$emit('update-job', 'image.entrypoint', $event.split('\n'))"
+ />
+ </gl-form-group>
</gl-accordion-item>
</template>
diff --git a/app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/job_setup_item.vue b/app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/job_setup_item.vue
index b49355d539c..511003d3ad4 100644
--- a/app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/job_setup_item.vue
+++ b/app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/job_setup_item.vue
@@ -39,6 +39,7 @@ export default {
availableStages: {
type: Array,
required: true,
+ default: () => [],
},
},
};
diff --git a/app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/services_item.vue b/app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/services_item.vue
index fd669adb077..9bada3ef110 100644
--- a/app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/services_item.vue
+++ b/app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/services_item.vue
@@ -4,7 +4,7 @@ import { i18n } from '../constants';
export default {
i18n,
- placeholderText: i18n.ENTRPOINT_PLACEHOLDER_TEXT,
+ placeholderText: i18n.ENTRYPOINT_PLACEHOLDER_TEXT,
components: {
GlAccordionItem,
GlFormGroup,
@@ -38,7 +38,7 @@ export default {
},
serviceEntryPoint(service) {
const { entrypoint = [''] } = service;
- return entrypoint.join(',');
+ return entrypoint.join('\n');
},
},
};
@@ -75,7 +75,7 @@ export default {
:placeholder="$options.placeholderText"
:data-testid="`service-entrypoint-input-${index}`"
:value="serviceEntryPoint(service)"
- @input="$emit('update-job', `services[${index}].entrypoint`, $event.split(','))"
+ @input="$emit('update-job', `services[${index}].entrypoint`, $event.split('\n'))"
/>
</gl-form-group>
</div>
diff --git a/app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/constants.js b/app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/constants.js
index d9d1a31ab6d..e93a9e84302 100644
--- a/app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/constants.js
+++ b/app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/constants.js
@@ -1,4 +1,4 @@
-import { __, s__, sprintf } from '~/locale';
+import { __, s__ } from '~/locale';
export const DRAWER_CONTAINER_CLASS = '.content-wrapper';
@@ -87,14 +87,8 @@ export const JOB_TEMPLATE = {
],
};
-export const ENTRYPOINT_PLACEHOLDER_EXAMPLE =
- "['/bin/bash','-c','ln -snf /bin/bash /bin/sh && /bin/bash -c $0']";
-
-export const ENTRYPOINT_PLACEHOLDER_INPUT =
- 'bin/bash,-c,ln -snf /bin/bash /bin/sh && /bin/bash -c $0';
-
export const i18n = {
- ARRAY_FIELD_DESCRIPTION: s__('JobAssistant|Please use "," to separate array type fields.'),
+ ARRAY_FIELD_DESCRIPTION: s__('JobAssistant|Please separate array type fields with new lines'),
INPUT_FORMAT: s__('JobAssistant|Input format'),
ADD_JOB: s__('JobAssistant|Add job'),
SCRIPT: s__('JobAssistant|Script'),
@@ -117,17 +111,8 @@ export const i18n = {
ALLOW_FAILURE: s__('JobAssistant|Allow failure'),
INVALID_START_IN: s__('JobAssistant|Error - Valid value is between 1 second and 1 week'),
ADD_SERVICE: s__('JobAssistant|Add service'),
- SERVICE: s__('JobAssistant|Service'),
+ SERVICE: s__('JobAssistant|Services'),
SERVICE_NAME: s__('JobAssistant|Service name (optional)'),
SERVICE_ENTRYPOINT: s__('JobAssistant|Service entrypoint (optional)'),
- ENTRPOINT_PLACEHOLDER_TEXT: sprintf(
- s__(
- 'JobAssistant|Example: %{entrypointPlaceholderExample}, Input format: %{entrypointPlaceholderInput}',
- ),
- {
- entrypointPlaceholderExample: ENTRYPOINT_PLACEHOLDER_EXAMPLE,
- entrypointPlaceholderInput: ENTRYPOINT_PLACEHOLDER_INPUT,
- },
- false,
- ),
+ ENTRYPOINT_PLACEHOLDER_TEXT: s__('JobAssistant|Please enter the parameters.'),
};
diff --git a/app/assets/javascripts/pages/projects/project.js b/app/assets/javascripts/pages/projects/project.js
index e6ee6b702bb..c566490dcb5 100644
--- a/app/assets/javascripts/pages/projects/project.js
+++ b/app/assets/javascripts/pages/projects/project.js
@@ -25,6 +25,13 @@ export default class Project {
$(this).parents('.auto-devops-implicitly-enabled-banner').remove();
return e.preventDefault();
});
+ $('.hide-mobile-devops-promo').on('click', function (e) {
+ const projectId = $(this).data('project-id');
+ const cookieKey = `hide_mobile_devops_promo_${projectId}`;
+ setCookie(cookieKey, 'false');
+ $(this).parents('#mobile-devops-promo-banner').remove();
+ return e.preventDefault();
+ });
}
static changeProject(url) {
diff --git a/app/controllers/groups/milestones_controller.rb b/app/controllers/groups/milestones_controller.rb
index 494b8c5621d..903c8c214ae 100644
--- a/app/controllers/groups/milestones_controller.rb
+++ b/app/controllers/groups/milestones_controller.rb
@@ -45,6 +45,24 @@ class Groups::MilestonesController < Groups::ApplicationController
Milestones::UpdateService.new(@milestone.parent, current_user, milestone_params).execute(@milestone)
redirect_to milestone_path(@milestone)
+ rescue ActiveRecord::StaleObjectError
+ respond_to do |format|
+ format.html do
+ @conflict = true
+ render :edit
+ end
+
+ format.json do
+ render json: {
+ errors: [
+ format(
+ _("Someone edited this %{model_name} at the same time you did. Please refresh your browser and make sure your changes will not unintentionally remove theirs."), # rubocop:disable Layout/LineLength
+ model_name: _('milestone')
+ )
+ ]
+ }, status: :conflict
+ end
+ end
end
def destroy
@@ -63,7 +81,15 @@ class Groups::MilestonesController < Groups::ApplicationController
end
def milestone_params
- params.require(:milestone).permit(:title, :description, :start_date, :due_date, :state_event)
+ params.require(:milestone)
+ .permit(
+ :description,
+ :due_date,
+ :lock_version,
+ :start_date,
+ :state_event,
+ :title
+ )
end
def milestones
diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb
index 78108cf3478..569a514b23b 100644
--- a/app/controllers/projects/milestones_controller.rb
+++ b/app/controllers/projects/milestones_controller.rb
@@ -85,6 +85,24 @@ class Projects::MilestonesController < Projects::ApplicationController
end
end
end
+ rescue ActiveRecord::StaleObjectError
+ respond_to do |format|
+ format.html do
+ @conflict = true
+ render :edit
+ end
+
+ format.json do
+ render json: {
+ errors: [
+ format(
+ _("Someone edited this %{model_name} at the same time you did. Please refresh your browser and make sure your changes will not unintentionally remove theirs."),
+ model_name: _('milestone')
+ )
+ ]
+ }, status: :conflict
+ end
+ end
end
def promote
@@ -152,7 +170,15 @@ class Projects::MilestonesController < Projects::ApplicationController
end
def milestone_params
- params.require(:milestone).permit(:title, :description, :start_date, :due_date, :state_event)
+ params.require(:milestone)
+ .permit(
+ :description,
+ :due_date,
+ :lock_version,
+ :start_date,
+ :state_event,
+ :title
+ )
end
def search_params
diff --git a/app/finders/template_finder.rb b/app/finders/template_finder.rb
index b82b601541c..c6c5c30cbf7 100644
--- a/app/finders/template_finder.rb
+++ b/app/finders/template_finder.rb
@@ -16,16 +16,27 @@ class TemplateFinder
def build(type, project, params = {})
if type.to_s == 'licenses'
LicenseTemplateFinder.new(project, params) # rubocop: disable CodeReuse/Finder
- else
+ elsif type_allowed?(type)
new(type, project, params)
end
end
def all_template_names(project, type)
- return {} if !VENDORED_TEMPLATES.key?(type.to_s) && type.to_s != 'licenses'
+ return {} unless type_allowed?(type)
build(type, project).template_names
end
+
+ def type_allowed?(type)
+ case type.to_s
+ when 'licenses'
+ true
+ when 'metrics_dashboard_ymls'
+ !Feature.enabled?(:remove_monitor_metrics)
+ else
+ VENDORED_TEMPLATES.key?(type)
+ end
+ end
end
attr_reader :type, :project, :params
diff --git a/app/graphql/mutations/metrics/dashboard/annotations/create.rb b/app/graphql/mutations/metrics/dashboard/annotations/create.rb
index 225d313c487..296efa19bb7 100644
--- a/app/graphql/mutations/metrics/dashboard/annotations/create.rb
+++ b/app/graphql/mutations/metrics/dashboard/annotations/create.rb
@@ -75,6 +75,8 @@ module Mutations
private
def ready?(**args)
+ raise_resource_not_available_error! if Feature.enabled?(:remove_monitor_metrics)
+
# Raise error if both cluster_id and environment_id are present or neither is present
unless args[:cluster_id].present? ^ args[:environment_id].present?
raise Gitlab::Graphql::Errors::ArgumentError, ANNOTATION_SOURCE_ARGUMENT_ERROR
diff --git a/app/graphql/mutations/metrics/dashboard/annotations/delete.rb b/app/graphql/mutations/metrics/dashboard/annotations/delete.rb
index 0ee2791f78b..32047cda213 100644
--- a/app/graphql/mutations/metrics/dashboard/annotations/delete.rb
+++ b/app/graphql/mutations/metrics/dashboard/annotations/delete.rb
@@ -14,6 +14,8 @@ module Mutations
description: 'Global ID of the annotation to delete.'
def resolve(id:)
+ raise_resource_not_available_error! if Feature.enabled?(:remove_monitor_metrics)
+
annotation = authorized_find!(id: id)
result = ::Metrics::Dashboard::Annotations::DeleteService.new(context[:current_user], annotation).execute
diff --git a/app/graphql/resolvers/metrics/dashboards/annotation_resolver.rb b/app/graphql/resolvers/metrics/dashboards/annotation_resolver.rb
index 9d6b0486c04..aad9bbebafb 100644
--- a/app/graphql/resolvers/metrics/dashboards/annotation_resolver.rb
+++ b/app/graphql/resolvers/metrics/dashboards/annotation_resolver.rb
@@ -17,6 +17,7 @@ module Resolvers
alias_method :dashboard, :object
def resolve(**args)
+ return if Feature.enabled?(:remove_monitor_metrics)
return [] unless dashboard
::Metrics::Dashboards::AnnotationsFinder.new(dashboard: dashboard, params: args).execute
diff --git a/app/graphql/resolvers/projects/branches_tipping_at_commit_resolver.rb b/app/graphql/resolvers/projects/branches_tipping_at_commit_resolver.rb
deleted file mode 100644
index 7e2661f3f77..00000000000
--- a/app/graphql/resolvers/projects/branches_tipping_at_commit_resolver.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-# frozen_string_literal: true
-
-module Resolvers
- module Projects
- class BranchesTippingAtCommitResolver < RefTippingAtCommitResolver
- MAX_LIMIT = 100
-
- calls_gitaly!
-
- type ::Types::Projects::CommitParentNamesType, null: true
-
- # the methode ref_prefix is implemented
- # because this class is prepending Resolver::CommitParentNamesResolver module
- # through it's parent ::Resolvers::RefTippingAtCommitResolver
- def ref_prefix
- Gitlab::Git::BRANCH_REF_PREFIX
- end
- end
- end
-end
diff --git a/app/graphql/resolvers/projects/commit_parent_names_resolver.rb b/app/graphql/resolvers/projects/commit_parent_names_resolver.rb
deleted file mode 100644
index f52776d715a..00000000000
--- a/app/graphql/resolvers/projects/commit_parent_names_resolver.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-# frozen_string_literal: true
-
-module Resolvers
- module Projects
- module CommitParentNamesResolver
- extend ActiveSupport::Concern
-
- prepended do
- argument :commit_sha, GraphQL::Types::String,
- required: true,
- description: 'Project commit SHA identifier. For example, `287774414568010855642518513f085491644061`.'
-
- argument :limit, GraphQL::Types::Int,
- required: false,
- description: 'Number of branch names to return.'
-
- alias_method :project, :object
- end
-
- def compute_limit(limit)
- max = self.class::MAX_LIMIT
-
- limit ? [limit, max].min : max
- end
-
- def get_tipping_refs(project, sha, limit: 0)
- # the methode ref_prefix needs to be implemented in all classes prepending this module
- refs = project.repository.refs_by_oid(oid: sha, ref_patterns: [ref_prefix], limit: limit)
- refs.map { |n| n.delete_prefix(ref_prefix) }
- end
- end
- end
-end
diff --git a/app/graphql/resolvers/projects/commit_references_resolver.rb b/app/graphql/resolvers/projects/commit_references_resolver.rb
new file mode 100644
index 00000000000..ca25bad468c
--- /dev/null
+++ b/app/graphql/resolvers/projects/commit_references_resolver.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+module Resolvers
+ module Projects
+ class CommitReferencesResolver < BaseResolver
+ include Gitlab::Graphql::Authorize::AuthorizeResource
+
+ argument :commit_sha, GraphQL::Types::String,
+ required: true,
+ description: 'Project commit SHA identifier. For example, `287774414568010855642518513f085491644061`.'
+
+ authorize :read_commit
+
+ alias_method :project, :object
+
+ calls_gitaly!
+
+ type ::Types::CommitReferencesType, null: true
+
+ def resolve(commit_sha:)
+ authorized_find!(oid: commit_sha)
+ end
+
+ def find_object(oid:)
+ project.repository.commit(oid)
+ end
+ end
+ end
+end
diff --git a/app/graphql/resolvers/projects/ref_tipping_at_commit_resolver.rb b/app/graphql/resolvers/projects/ref_tipping_at_commit_resolver.rb
deleted file mode 100644
index 3259a29ac9c..00000000000
--- a/app/graphql/resolvers/projects/ref_tipping_at_commit_resolver.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-# frozen_string_literal: true
-
-module Resolvers
- module Projects
- class RefTippingAtCommitResolver < BaseResolver
- include Gitlab::Graphql::Authorize::AuthorizeResource
- prepend CommitParentNamesResolver
-
- type ::Types::Projects::CommitParentNamesType, null: true
-
- authorize :read_code
-
- def resolve(commit_sha:, limit: nil)
- final_limit = compute_limit(limit)
-
- names = get_tipping_refs(project, commit_sha, limit: final_limit)
-
- {
- names: names,
- total_count: nil
- }
- end
- end
- end
-end
diff --git a/app/graphql/resolvers/projects/tags_tipping_at_commit_resolver.rb b/app/graphql/resolvers/projects/tags_tipping_at_commit_resolver.rb
deleted file mode 100644
index 78ee9c997d5..00000000000
--- a/app/graphql/resolvers/projects/tags_tipping_at_commit_resolver.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-# frozen_string_literal: true
-
-module Resolvers
- module Projects
- class TagsTippingAtCommitResolver < RefTippingAtCommitResolver
- MAX_LIMIT = 100
-
- calls_gitaly!
-
- type ::Types::Projects::CommitParentNamesType, null: true
-
- # the methode ref_prefix is implemented
- # because this class is prepending Resolver::CommitParentNamesResolver module
- # through it's parent ::Resolvers::RefTippingAtCommitResolver
- def ref_prefix
- Gitlab::Git::TAG_REF_PREFIX
- end
- end
- end
-end
diff --git a/app/graphql/types/commit_references_type.rb b/app/graphql/types/commit_references_type.rb
new file mode 100644
index 00000000000..2844a552f3e
--- /dev/null
+++ b/app/graphql/types/commit_references_type.rb
@@ -0,0 +1,67 @@
+# frozen_string_literal: true
+
+module Types
+ class CommitReferencesType < BaseObject
+ graphql_name 'CommitReferences'
+
+ authorize :read_commit
+
+ def self.field_for_tipping_refs(field_name, field_description)
+ field field_name, ::Types::Projects::CommitParentNamesType,
+ null: true,
+ calls_gitaly: true,
+ description: field_description do
+ argument :limit, GraphQL::Types::Int,
+ required: true,
+ default_value: 100,
+ description: 'Number of ref names to return.',
+ validates: { numericality: { within: 1..1000 } }
+ end
+ end
+
+ def self.field_for_containing_refs(field_name, field_description)
+ field field_name, ::Types::Projects::CommitParentNamesType,
+ null: true,
+ calls_gitaly: true,
+ description: field_description do
+ argument :exclude_tipped, GraphQL::Types::Boolean,
+ required: true,
+ default_value: false,
+ description: 'Exclude tipping refs. WARNING: This argument can be confusing, if there is a limit.
+ for example set the limit to 5 and in the 5 out a total of 25 refs there is 2 tipped refs,
+ then the method will only 3 refs, even though there is more.'
+ # rubocop: disable GraphQL/ArgumentUniqueness
+ argument :limit, GraphQL::Types::Int,
+ required: true,
+ default_value: 100,
+ description: 'Number of ref names to return.',
+ validates: { numericality: { within: 1..1000 } }
+ # rubocop: enable GraphQL/ArgumentUniqueness
+ end
+ end
+
+ field_for_tipping_refs :tipping_tags, "Get tag names tipping at a given commit."
+
+ field_for_tipping_refs :tipping_branches, "Get branch names tipping at a given commit."
+
+ field_for_containing_refs :containing_tags, "Get tag names containing a given commit."
+
+ field_for_containing_refs :containing_branches, "Get branch names containing a given commit."
+
+ def tipping_tags(limit:)
+ { names: object.tipping_tags(limit: limit) }
+ end
+
+ def tipping_branches(limit:)
+ { names: object.tipping_branches(limit: limit) }
+ end
+
+ def containing_tags(limit:, exclude_tipped:)
+ { names: object.tags_containing(limit: limit, exclude_tipped: exclude_tipped) }
+ end
+
+ def containing_branches(limit:, exclude_tipped:)
+ { names: object.branches_containing(limit: limit, exclude_tipped: exclude_tipped) }
+ end
+ end
+end
diff --git a/app/graphql/types/mutation_type.rb b/app/graphql/types/mutation_type.rb
index 64f7daf09a8..7e436d74dcf 100644
--- a/app/graphql/types/mutation_type.rb
+++ b/app/graphql/types/mutation_type.rb
@@ -86,8 +86,14 @@ module Types
mount_mutation Mutations::MergeRequests::SetAssignees
mount_mutation Mutations::MergeRequests::SetReviewers
mount_mutation Mutations::MergeRequests::ReviewerRereview
- mount_mutation Mutations::Metrics::Dashboard::Annotations::Create
- mount_mutation Mutations::Metrics::Dashboard::Annotations::Delete
+ mount_mutation Mutations::Metrics::Dashboard::Annotations::Create, deprecated: {
+ reason: 'Underlying feature was removed in 16.0',
+ milestone: '16.0'
+ }
+ mount_mutation Mutations::Metrics::Dashboard::Annotations::Delete, deprecated: {
+ reason: 'Underlying feature was removed in 16.0',
+ milestone: '16.0'
+ }
mount_mutation Mutations::Notes::Create::Note, calls_gitaly: true
mount_mutation Mutations::Notes::Create::DiffNote, calls_gitaly: true
mount_mutation Mutations::Notes::Create::ImageDiffNote, calls_gitaly: true
diff --git a/app/graphql/types/permission_types/issue.rb b/app/graphql/types/permission_types/issue.rb
index b38971b64cd..a76dc88adfc 100644
--- a/app/graphql/types/permission_types/issue.rb
+++ b/app/graphql/types/permission_types/issue.rb
@@ -8,7 +8,7 @@ module Types
abilities :read_issue, :admin_issue, :update_issue, :reopen_issue,
:read_design, :create_design, :destroy_design,
- :create_note
+ :create_note, :update_design
end
end
end
diff --git a/app/graphql/types/project_statistics_redirect_type.rb b/app/graphql/types/project_statistics_redirect_type.rb
new file mode 100644
index 00000000000..c8fec0a54c4
--- /dev/null
+++ b/app/graphql/types/project_statistics_redirect_type.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+module Types
+ # rubocop: disable Graphql/AuthorizeTypes
+ class ProjectStatisticsRedirectType < BaseObject
+ graphql_name 'ProjectStatisticsRedirect'
+
+ field :repository, GraphQL::Types::String, null: false,
+ description: 'Redirection Route for repository.'
+
+ field :wiki, GraphQL::Types::String, null: false,
+ description: 'Redirection Route for wiki.'
+
+ field :build_artifacts, GraphQL::Types::String, null: false,
+ description: 'Redirection Route for job_artifacts.'
+
+ field :packages, GraphQL::Types::String, null: false,
+ description: 'Redirection Route for packages.'
+
+ field :snippets, GraphQL::Types::String, null: false,
+ description: 'Redirection Route for snippets.'
+
+ field :container_registry, GraphQL::Types::String, null: false,
+ description: 'Redirection Route for container_registry.'
+ end
+ # rubocop: enable Graphql/AuthorizeTypes
+end
diff --git a/app/graphql/types/project_type.rb b/app/graphql/types/project_type.rb
index 6dfbdf765c8..f8a516501c3 100644
--- a/app/graphql/types/project_type.rb
+++ b/app/graphql/types/project_type.rb
@@ -214,6 +214,11 @@ module Types
null: true,
description: 'Statistics of the project.'
+ field :statistics_details_paths, Types::ProjectStatisticsRedirectType,
+ null: true,
+ description: 'Redirects for Statistics of the project.',
+ calls_gitaly: true
+
field :repository, Types::RepositoryType,
null: true,
description: 'Git repository of the project.'
@@ -612,15 +617,11 @@ module Types
authorize: :read_cycle_analytics,
alpha: { milestone: '15.10' }
- field :tags_tipping_at_commit, ::Types::Projects::CommitParentNamesType,
- null: true,
- resolver: Resolvers::Projects::TagsTippingAtCommitResolver,
- description: "Get tag names tipping at a given commit."
-
- field :branches_tipping_at_commit, ::Types::Projects::CommitParentNamesType,
- null: true,
- resolver: Resolvers::Projects::BranchesTippingAtCommitResolver,
- description: "Get branch names tipping at a given commit."
+ field :commit_references, ::Types::CommitReferencesType,
+ null: true,
+ resolver: Resolvers::Projects::CommitReferencesResolver,
+ alpha: { milestone: '16.0' },
+ description: "Get tag names containing a given commit."
def timelog_categories
object.project_namespace.timelog_categories if Feature.enabled?(:timelog_categories)
@@ -730,6 +731,19 @@ module Types
end
end
+ def statistics_details_paths
+ root_ref = project.repository.root_ref || project.default_branch_or_main
+
+ {
+ repository: Gitlab::Routing.url_helpers.project_tree_url(project, root_ref),
+ wiki: Gitlab::Routing.url_helpers.project_wikis_pages_url(project),
+ build_artifacts: Gitlab::Routing.url_helpers.project_artifacts_url(project),
+ packages: Gitlab::Routing.url_helpers.project_packages_url(project),
+ snippets: Gitlab::Routing.url_helpers.project_snippets_url(project),
+ container_registry: Gitlab::Routing.url_helpers.project_container_registry_index_url(project)
+ }
+ end
+
private
def project
diff --git a/app/graphql/types/projects/commit_parent_names_type.rb b/app/graphql/types/projects/commit_parent_names_type.rb
index 0aa1ca768e9..39f8f1cdd07 100644
--- a/app/graphql/types/projects/commit_parent_names_type.rb
+++ b/app/graphql/types/projects/commit_parent_names_type.rb
@@ -7,7 +7,6 @@ module Types
graphql_name 'CommitParentNames'
field :names, [GraphQL::Types::String], null: true, description: 'Names of the commit parent (branch or tag).'
- field :total_count, GraphQL::Types::Int, null: true, description: 'Total of parent branches or tags.'
end
# rubocop: enable Graphql/AuthorizeTypes
end
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index 32331136e28..1e87d2861d4 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -259,6 +259,14 @@ module ProjectsHelper
cookies["hide_auto_devops_implicitly_enabled_banner_#{project.id}".to_sym].blank?
end
+ def show_mobile_devops_project_promo?(project)
+ return false unless ::Feature.enabled?(:mobile_devops_projects_promo, project)
+
+ return false unless (project.project_setting.target_platforms & ::ProjectSetting::ALLOWED_TARGET_PLATFORMS).any?
+
+ cookies["hide_mobile_devops_promo_#{project.id}".to_sym].blank?
+ end
+
def no_password_message
push_pull_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('topics/git/terminology', anchor: 'pull-and-push') }
clone_with_https_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('gitlab-basics/start-using-git', anchor: 'clone-with-https') }
diff --git a/app/models/blob_viewer/metrics_dashboard_yml.rb b/app/models/blob_viewer/metrics_dashboard_yml.rb
index 4b7a178566c..b63f3022198 100644
--- a/app/models/blob_viewer/metrics_dashboard_yml.rb
+++ b/app/models/blob_viewer/metrics_dashboard_yml.rb
@@ -11,6 +11,10 @@ module BlobViewer
self.file_types = %i(metrics_dashboard)
self.binary = false
+ def self.can_render?(blob, verify_binary: true)
+ super && !Feature.enabled?(:remove_monitor_metrics)
+ end
+
def valid?
errors.blank?
end
diff --git a/app/models/commit.rb b/app/models/commit.rb
index b618845705c..6d17d7f495d 100644
--- a/app/models/commit.rb
+++ b/app/models/commit.rb
@@ -572,8 +572,43 @@ class Commit
}
end
+ def tipping_branches(limit: 0)
+ tipping_refs(Gitlab::Git::BRANCH_REF_PREFIX, limit: limit)
+ end
+
+ def tipping_tags(limit: 0)
+ tipping_refs(Gitlab::Git::TAG_REF_PREFIX, limit: limit)
+ end
+
+ def branches_containing(limit: 0, exclude_tipped: false)
+ # WARNING: This argument can be confusing, if there is a limit.
+ # for example set the limit to 5 and in the 5 out a total of 25 refs there is 2 tipped refs,
+ # then the method will only 3 refs, even though there is more.
+ excluded = exclude_tipped ? tipping_branches : []
+
+ refs = repository.branch_names_contains(id, limit: limit) || []
+ refs - excluded
+ end
+
+ def tags_containing(limit: 0, exclude_tipped: false)
+ # WARNING: This argument can be confusing, if there is a limit.
+ # for example set the limit to 5 and in the 5 out a total of 25 refs there is 2 tipped refs,
+ # then the method will only 3 refs, even though there is more.
+ excluded = exclude_tipped ? tipping_tags : []
+
+ refs = repository.tag_names_contains(id, limit: limit) || []
+ refs - excluded
+ end
+
private
+ def tipping_refs(ref_prefix, limit: 0)
+ strong_memoize_with(:tipping_tags, ref_prefix, limit) do
+ refs = repository.refs_by_oid(oid: id, ref_patterns: [ref_prefix], limit: limit)
+ refs.map { |n| n.delete_prefix(ref_prefix) }
+ end
+ end
+
def expire_note_etag_cache_for_related_mrs
MergeRequest.includes(target_project: :namespace).by_commit_sha(id).find_each(&:expire_note_etag_cache)
end
diff --git a/app/models/container_registry/data_repair_detail.rb b/app/models/container_registry/data_repair_detail.rb
index 09e617e69f5..a2616490905 100644
--- a/app/models/container_registry/data_repair_detail.rb
+++ b/app/models/container_registry/data_repair_detail.rb
@@ -2,9 +2,15 @@
module ContainerRegistry
class DataRepairDetail < ApplicationRecord
+ include EachBatch
+
self.table_name = 'container_registry_data_repair_details'
self.primary_key = :project_id
belongs_to :project, optional: false
+
+ enum status: { ongoing: 0, completed: 1, failed: 2 }
+
+ scope :ongoing_since, ->(threshold) { where(status: :ongoing).where('updated_at < ?', threshold) }
end
end
diff --git a/app/models/project.rb b/app/models/project.rb
index d8818d9c174..224193fba08 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -188,6 +188,7 @@ class Project < ApplicationRecord
has_one :confluence_integration, class_name: 'Integrations::Confluence'
has_one :custom_issue_tracker_integration, class_name: 'Integrations::CustomIssueTracker'
has_one :datadog_integration, class_name: 'Integrations::Datadog'
+ has_one :container_registry_data_repair_detail, class_name: 'ContainerRegistry::DataRepairDetail'
has_one :discord_integration, class_name: 'Integrations::Discord'
has_one :drone_ci_integration, class_name: 'Integrations::DroneCi'
has_one :emails_on_push_integration, class_name: 'Integrations::EmailsOnPush'
@@ -740,6 +741,11 @@ class Project < ApplicationRecord
topic ? with_topic(topic) : none
end
+ scope :pending_data_repair_analysis, -> do
+ left_outer_joins(:container_registry_data_repair_detail)
+ .where(container_registry_data_repair_details: { project_id: nil })
+ end
+
enum auto_cancel_pending_pipelines: { disabled: 0, enabled: 1 }
chronic_duration_attr :build_timeout_human_readable, :build_timeout,
diff --git a/app/services/jira_connect/sync_service.rb b/app/services/jira_connect/sync_service.rb
index 92255711399..497c282072d 100644
--- a/app/services/jira_connect/sync_service.rb
+++ b/app/services/jira_connect/sync_service.rb
@@ -31,7 +31,9 @@ module JiraConnect
jira_response: response&.to_json
}
- if response && response['errorMessages'].present?
+ has_errors = response && (response['errorMessage'].present? || response['errorMessages'].present?)
+
+ if has_errors
logger.error(message)
else
logger.info(message)
diff --git a/app/views/clusters/clusters/_integrations.html.haml b/app/views/clusters/clusters/_integrations.html.haml
index 0f62b640b97..4d36c5094a3 100644
--- a/app/views/clusters/clusters/_integrations.html.haml
+++ b/app/views/clusters/clusters/_integrations.html.haml
@@ -9,7 +9,7 @@
= prometheus_form.hidden_field :application_type, value: @prometheus_integration.application_type
.form-group.gl-form-group
- help_text = s_('ClusterIntegration|Allows GitLab to query a specifically configured in-cluster Prometheus for metrics.')
- - help_link = link_to(_('More information.'), help_page_path("user/clusters/integrations", anchor: "prometheus-cluster-integration"), target: '_blank', rel: 'noopener noreferrer')
+ - help_link = link_to(_('More information.'), help_page_path("user/clusters/integrations"), target: '_blank', rel: 'noopener noreferrer')
= prometheus_form.gitlab_ui_checkbox_component :enabled,
s_('ClusterIntegration|Enable Prometheus integration'),
help_text: '%{help_text} %{help_link}'.html_safe % { help_text: help_text, help_link: help_link }
diff --git a/app/views/groups/milestones/_form.html.haml b/app/views/groups/milestones/_form.html.haml
index 1fd8e12016c..89f460606cb 100644
--- a/app/views/groups/milestones/_form.html.haml
+++ b/app/views/groups/milestones/_form.html.haml
@@ -1,5 +1,9 @@
= gitlab_ui_form_for [@group, @milestone], html: { class: 'milestone-form common-note-form js-quick-submit js-requires-input' } do |f|
= form_errors(@milestone)
+
+ - if @conflict
+ = render 'shared/model_version_conflict', model_name: _('milestone'), link_path: group_milestone_path(@group, @milestone)
+
.form-group
= f.label :title, _("Title")
= f.text_field :title, maxlength: 255, class: "form-control", data: { qa_selector: "milestone_title_field" }, required: true, autofocus: true
@@ -15,6 +19,8 @@
.clearfix
.error-alert
+ = f.hidden_field :lock_version
+
- if @milestone.new_record?
= f.submit _('Create milestone'), data: { qa_selector: "create_milestone_button" }, class: 'gl-mr-2', pajamas_button: true
= render Pajamas::ButtonComponent.new(href: group_milestones_path(@group)) do
diff --git a/app/views/projects/mattermosts/_team_selection.html.haml b/app/views/projects/mattermosts/_team_selection.html.haml
index 98221125443..397f96d6846 100644
--- a/app/views/projects/mattermosts/_team_selection.html.haml
+++ b/app/views/projects/mattermosts/_team_selection.html.haml
@@ -2,7 +2,7 @@
This service will be installed on the Mattermost instance at
%strong= link_to Gitlab.config.mattermost.host, Gitlab.config.mattermost.host
%hr
-= form_for(:mattermost, method: :post, url: project_mattermost_path(@project), html: { class: 'js-requires-input' }) do |f|
+= gitlab_ui_form_for(:mattermost, method: :post, url: project_mattermost_path(@project), html: { class: 'js-requires-input' }) do |f|
%h4 Team
%p
= @teams.one? ? 'The team' : 'Select the team'
@@ -42,5 +42,6 @@
%hr
.clearfix
.float-right
- = link_to _('Cancel'), edit_project_settings_integration_path(@project, @integration), class: 'gl-button btn btn-lg'
- = f.submit 'Install', class: 'gl-button btn btn-confirm btn-lg'
+ = render Pajamas::ButtonComponent.new(href: edit_project_settings_integration_path(@project, @integration)) do
+ = _('Cancel')
+ = f.submit s_('MattermostService|Install'), pajamas_button: true
diff --git a/app/views/projects/milestones/_form.html.haml b/app/views/projects/milestones/_form.html.haml
index 91c161e8602..be6f9ac83dc 100644
--- a/app/views/projects/milestones/_form.html.haml
+++ b/app/views/projects/milestones/_form.html.haml
@@ -1,5 +1,9 @@
= gitlab_ui_form_for [@project, @milestone], html: { class: 'milestone-form common-note-form js-quick-submit js-requires-input' } do |f|
= form_errors(@milestone)
+
+ - if @conflict
+ = render 'shared/model_version_conflict', model_name: _('milestone'), link_path: project_milestone_path(@project, @milestone)
+
- if @redirect_path.present?
= f.hidden_field(:redirect_path, name: :redirect_path, id: :redirect_path, value: @redirect_path)
.form-group
@@ -18,6 +22,8 @@
.clearfix
.error-alert
+ = f.hidden_field :lock_version
+
- if @milestone.new_record?
= f.submit _('Create milestone'), data: { qa_selector: 'create_milestone_button' }, class: 'gl-mr-2', pajamas_button: true
= link_to _('Cancel'), project_milestones_path(@project), class: 'gl-button btn btn-default btn-cancel'
diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml
index e21bf7d318b..8a35db357ee 100644
--- a/app/views/projects/show.html.haml
+++ b/app/views/projects/show.html.haml
@@ -7,6 +7,7 @@
= auto_discovery_link_tag(:atom, project_path(@project, rss_url_options), title: "#{@project.name} activity")
= render_if_exists 'shared/ultimate_feature_removal_banner', project: @project
+= render_if_exists 'shared/promotions/promote_mobile_devops', project: @project
= render partial: 'flash_messages', locals: { project: @project }
= render 'clusters_deprecation_alert'
diff --git a/app/views/shared/_captcha_check.html.haml b/app/views/shared/_captcha_check.html.haml
index a10ae655ea6..b3b2ae0d969 100644
--- a/app/views/shared/_captcha_check.html.haml
+++ b/app/views/shared/_captcha_check.html.haml
@@ -10,7 +10,7 @@
%p
= _("We detected potential spam in the %{humanized_resource_name}. Please solve the reCAPTCHA to proceed.") % { humanized_resource_name: humanized_resource_name }
-= form_for resource_name, method: method, html: { class: 'recaptcha-form js-recaptcha-form' } do |f|
+= gitlab_ui_form_for resource_name, method: method, html: { class: 'recaptcha-form js-recaptcha-form' } do |f|
.recaptcha
-# Create a hidden field for each param of the resource
- params[resource_name].each do |field, value|
@@ -34,4 +34,4 @@
= yield
.row-content-block.footer-block
- = f.submit _("Create %{humanized_resource_name}") % { humanized_resource_name: humanized_resource_name }, class: 'gl-button btn btn-confirm'
+ = f.submit _("Create %{humanized_resource_name}") % { humanized_resource_name: humanized_resource_name }, pajamas_button: true
diff --git a/app/views/shared/_model_version_conflict.html.haml b/app/views/shared/_model_version_conflict.html.haml
new file mode 100644
index 00000000000..134dcf8db7f
--- /dev/null
+++ b/app/views/shared/_model_version_conflict.html.haml
@@ -0,0 +1,6 @@
+= render Pajamas::AlertComponent.new(variant: :danger,
+ dismissible: false,
+ alert_options: { class: 'gl-mb-5' }) do |c|
+ = c.body do
+ - link_to_model = link_to(model_name, link_path, target: '_blank', rel: 'noopener noreferrer')
+ = _("Someone edited this %{model_name} at the same time you did. Please check out the %{link_to_model} and make sure your changes will not unintentionally remove theirs.").html_safe % { model_name: model_name, link_to_model: link_to_model }
diff --git a/app/views/shared/doorkeeper/applications/_form.html.haml b/app/views/shared/doorkeeper/applications/_form.html.haml
index b40e2630011..628a34e1278 100644
--- a/app/views/shared/doorkeeper/applications/_form.html.haml
+++ b/app/views/shared/doorkeeper/applications/_form.html.haml
@@ -21,4 +21,4 @@
= render 'shared/tokens/scopes_form', prefix: 'doorkeeper_application', token: @application, scopes: @scopes, f: f
.gl-mt-3
- = f.submit _('Save application'), class: "gl-button btn btn-confirm"
+ = f.submit _('Save application'), pajamas_button: true
diff --git a/app/views/shared/integrations/prometheus/_custom_metrics.html.haml b/app/views/shared/integrations/prometheus/_custom_metrics.html.haml
index e5ddc055aef..beeb328aedf 100644
--- a/app/views/shared/integrations/prometheus/_custom_metrics.html.haml
+++ b/app/views/shared/integrations/prometheus/_custom_metrics.html.haml
@@ -3,7 +3,7 @@
.col-lg-3
%p
= s_('PrometheusService|Custom metrics require Prometheus installed on a cluster with environment scope "*" OR a manually configured Prometheus to be available.')
- = link_to s_('PrometheusService|More information'), help_page_path('operations/metrics/index.md', anchor: 'adding-custom-metrics'), target: '_blank', rel: "noopener noreferrer"
+ = link_to s_('PrometheusService|More information'), help_page_path('operations/metrics/index.md'), target: '_blank', rel: "noopener noreferrer"
.col-lg-9
= render Pajamas::CardComponent.new(header_options: { class: 'gl-display-flex gl-align-items-center' }, body_options: { class: 'gl-p-0' }, card_options: { class: 'gl-mb-5 custom-monitored-metrics js-panel-custom-monitored-metrics', data: { active_custom_metrics: project_prometheus_metrics_path(project), environments_data: environments_list_data, service_active: "#{integration.active}" } }) do |c|
diff --git a/app/views/shared/integrations/prometheus/_metrics.html.haml b/app/views/shared/integrations/prometheus/_metrics.html.haml
index 1c54e4bd1de..7cd4eeee5f8 100644
--- a/app/views/shared/integrations/prometheus/_metrics.html.haml
+++ b/app/views/shared/integrations/prometheus/_metrics.html.haml
@@ -34,5 +34,5 @@
.flash-notice
.flash-text
= html_escape(s_("PrometheusService|To set up automatic monitoring, add the environment variable %{variable} to exporter's queries.")) % { variable: "<code>$CI_ENVIRONMENT_SLUG</code>".html_safe }
- = link_to s_('PrometheusService|More information'), help_page_path('operations/metrics/dashboards/variables.md', anchor: 'query-variables')
+ = link_to s_('PrometheusService|More information'), help_page_path('operations/metrics/index.md')
%ul.list-unstyled.metrics-list.js-missing-var-metrics-list
diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml
index 58d0a39578a..b6bd691213c 100644
--- a/app/views/shared/issuable/_form.html.haml
+++ b/app/views/shared/issuable/_form.html.haml
@@ -6,14 +6,8 @@
= form_errors(issuable)
- if @conflict
- = render Pajamas::AlertComponent.new(variant: :danger,
- dismissible: false,
- alert_options: { class: 'gl-mb-5' }) do |c|
- = c.body do
- Someone edited the #{issuable.class.model_name.human.downcase} the same time you did.
- Please check out
- = link_to "the #{issuable.class.model_name.human.downcase}", polymorphic_path([@project, issuable]), target: "_blank", rel: 'noopener noreferrer'
- and make sure your changes will not unintentionally remove theirs
+ - model_name = _(issuable.class.model_name.human.downcase)
+ = render 'shared/model_version_conflict', model_name: model_name, link_path: polymorphic_path([@project, issuable])
= render 'shared/issuable/form/branch_chooser', issuable: issuable, form: form
diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml
index 3eb80292a2f..1149f64314e 100644
--- a/app/workers/all_queues.yml
+++ b/app/workers/all_queues.yml
@@ -165,6 +165,15 @@
:weight: 1
:idempotent: true
:tags: []
+- :name: container_repository:container_registry_record_data_repair_detail
+ :worker_name: ContainerRegistry::RecordDataRepairDetailWorker
+ :feature_category: :container_registry
+ :has_external_dependencies: false
+ :urgency: :low
+ :resource_boundary: :unknown
+ :weight: 1
+ :idempotent: true
+ :tags: []
- :name: container_repository:delete_container_repository
:worker_name: DeleteContainerRepositoryWorker
:feature_category: :container_registry
diff --git a/app/workers/container_registry/cleanup_worker.rb b/app/workers/container_registry/cleanup_worker.rb
index a838b97b35d..448a16ad309 100644
--- a/app/workers/container_registry/cleanup_worker.rb
+++ b/app/workers/container_registry/cleanup_worker.rb
@@ -12,14 +12,17 @@ module ContainerRegistry
feature_category :container_registry
STALE_DELETE_THRESHOLD = 30.minutes.freeze
+ STALE_REPAIR_DETAIL_THRESHOLD = 2.hours.freeze
BATCH_SIZE = 200
def perform
log_counts
reset_stale_deletes
+ delete_stale_ongoing_repair_details
enqueue_delete_container_repository_jobs if ContainerRepository.delete_scheduled.exists?
+ enqueue_record_repair_detail_jobs if should_enqueue_record_detail_jobs?
end
private
@@ -33,10 +36,31 @@ module ContainerRegistry
end
end
+ def delete_stale_ongoing_repair_details
+ # Deleting stale ongoing repair details would put the project back to the analysis pool
+ ContainerRegistry::DataRepairDetail
+ .ongoing_since(STALE_REPAIR_DETAIL_THRESHOLD.ago)
+ .each_batch(of: BATCH_SIZE) do |batch| # rubocop:disable Style/SymbolProc
+ batch.delete_all
+ end
+ end
+
def enqueue_delete_container_repository_jobs
ContainerRegistry::DeleteContainerRepositoryWorker.perform_with_capacity
end
+ def enqueue_record_repair_detail_jobs
+ ContainerRegistry::RecordDataRepairDetailWorker.perform_with_capacity
+ end
+
+ def should_enqueue_record_detail_jobs?
+ return false unless Gitlab.com?
+ return false unless Feature.enabled?(:registry_data_repair_worker)
+ return false unless ContainerRegistry::GitlabApiClient.supports_gitlab_api?
+
+ Project.pending_data_repair_analysis.exists?
+ end
+
def log_counts
::Gitlab::Database::LoadBalancing::Session.current.use_replicas_for_read_queries do
log_extra_metadata_on_done(
diff --git a/app/workers/container_registry/record_data_repair_detail_worker.rb b/app/workers/container_registry/record_data_repair_detail_worker.rb
new file mode 100644
index 00000000000..f400568a3ef
--- /dev/null
+++ b/app/workers/container_registry/record_data_repair_detail_worker.rb
@@ -0,0 +1,87 @@
+# frozen_string_literal: true
+
+module ContainerRegistry
+ class RecordDataRepairDetailWorker
+ include ApplicationWorker
+ include ExclusiveLeaseGuard
+ include LimitedCapacity::Worker
+ include Gitlab::Utils::StrongMemoize
+
+ data_consistency :always # rubocop:disable SidekiqLoadBalancing/WorkerDataConsistency
+ queue_namespace :container_repository
+ feature_category :container_registry
+ urgency :low
+ worker_resource_boundary :unknown
+ idempotent!
+
+ MAX_CAPACITY = 2
+ LEASE_TIMEOUT = 1.hour.to_i
+
+ def perform_work
+ return unless Gitlab.com?
+ return unless next_project
+ return if next_project.container_registry_data_repair_detail
+
+ missing_count = 0
+
+ try_obtain_lease do
+ detail = create_data_repair_detail
+
+ GitlabApiClient.each_sub_repositories_with_tag_page(path: next_project.full_path,
+ page_size: 50) do |repositories|
+ next if repositories.empty?
+
+ paths = repositories.map { |repo| ContainerRegistry::Path.new(repo["path"]) }
+ paths, invalid_paths = paths.partition(&:valid?)
+ unless invalid_paths.empty?
+ log_extra_metadata_on_done(
+ :invalid_paths_parsed_in_container_repository_repair,
+ invalid_paths.join(' ,')
+ )
+ end
+
+ found_repositories = next_project.container_repositories.where(name: paths.map(&:repository_name)) # rubocop:disable CodeReuse/ActiveRecord
+
+ missing_count += repositories.count - found_repositories.count
+ end
+ detail.update!(missing_count: missing_count, status: :completed)
+ end
+ rescue StandardError => exception
+ next_project.reset.container_registry_data_repair_detail&.update(status: :failed)
+ Gitlab::ErrorTracking.log_exception(exception, class: self.class.name)
+ end
+
+ def remaining_work_count
+ return 0 unless Gitlab.com?
+ return 0 unless Feature.enabled?(:registry_data_repair_worker)
+ return 0 unless ContainerRegistry::GitlabApiClient.supports_gitlab_api?
+
+ Project.pending_data_repair_analysis.limit(max_running_jobs + 1).count
+ end
+
+ def max_running_jobs
+ MAX_CAPACITY
+ end
+
+ private
+
+ def next_project
+ Project.pending_data_repair_analysis.first
+ end
+ strong_memoize_attr :next_project
+
+ def create_data_repair_detail
+ ContainerRegistry::DataRepairDetail.create!(project: next_project, status: :ongoing)
+ end
+
+ # Used by ExclusiveLeaseGuard
+ def lease_key
+ "container_registry_data_repair_detail_worker:#{next_project.id}"
+ end
+
+ # Used by ExclusiveLeaseGuard
+ def lease_timeout
+ LEASE_TIMEOUT
+ end
+ end
+end
diff --git a/config/feature_flags/development/mobile_devops_projects_promo.yml b/config/feature_flags/development/mobile_devops_projects_promo.yml
new file mode 100644
index 00000000000..c1fcca28858
--- /dev/null
+++ b/config/feature_flags/development/mobile_devops_projects_promo.yml
@@ -0,0 +1,8 @@
+---
+name: mobile_devops_projects_promo
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/120144
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/410601
+milestone: '16.0'
+type: development
+group: group::mobile devops
+default_enabled: false
diff --git a/config/feature_flags/development/registry_data_repair_worker.yml b/config/feature_flags/development/registry_data_repair_worker.yml
new file mode 100644
index 00000000000..3d8982c3e81
--- /dev/null
+++ b/config/feature_flags/development/registry_data_repair_worker.yml
@@ -0,0 +1,8 @@
+---
+name: registry_data_repair_worker
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/115156
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/397505
+milestone: '16.0'
+type: development
+group: group::container registry
+default_enabled: false
diff --git a/config/feature_flags/development/remove_monitor_metrics.yml b/config/feature_flags/development/remove_monitor_metrics.yml
index a2f082ac977..d1aa57510ce 100644
--- a/config/feature_flags/development/remove_monitor_metrics.yml
+++ b/config/feature_flags/development/remove_monitor_metrics.yml
@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/399248
milestone: '15.11'
type: development
group: group::respond
-default_enabled: false
+default_enabled: true
diff --git a/db/migrate/20230404160131_add_status_to_data_repair_details.rb b/db/migrate/20230404160131_add_status_to_data_repair_details.rb
new file mode 100644
index 00000000000..564b0450752
--- /dev/null
+++ b/db/migrate/20230404160131_add_status_to_data_repair_details.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+class AddStatusToDataRepairDetails < Gitlab::Database::Migration[2.1]
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'index_container_registry_data_repair_details_on_status'
+
+ def up
+ unless column_exists?(:container_registry_data_repair_details, :status)
+ add_column(:container_registry_data_repair_details, :status, :integer, default: 0, null: false, limit: 2)
+ end
+
+ add_concurrent_index :container_registry_data_repair_details, :status, name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name :container_registry_data_repair_details, name: INDEX_NAME
+ remove_column :container_registry_data_repair_details, :status
+ end
+end
diff --git a/db/migrate/20230505122015_add_lock_version_to_milestones.rb b/db/migrate/20230505122015_add_lock_version_to_milestones.rb
new file mode 100644
index 00000000000..f8e34426c39
--- /dev/null
+++ b/db/migrate/20230505122015_add_lock_version_to_milestones.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddLockVersionToMilestones < Gitlab::Database::Migration[2.1]
+ enable_lock_retries!
+
+ def change
+ add_column :milestones, :lock_version, :integer, null: false, default: 0
+ end
+end
diff --git a/db/post_migrate/20230425521418_drop_merge_request_mentions_temp_index.rb b/db/post_migrate/20230425521418_drop_merge_request_mentions_temp_index.rb
new file mode 100644
index 00000000000..a13c994d954
--- /dev/null
+++ b/db/post_migrate/20230425521418_drop_merge_request_mentions_temp_index.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class DropMergeRequestMentionsTempIndex < Gitlab::Database::Migration[2.1]
+ INDEX_NAME = 'merge_request_mentions_temp_index'
+ INDEX_CONDITION = "description like '%@%' OR title like '%@%'"
+
+ disable_ddl_transaction!
+
+ def up
+ remove_concurrent_index(:merge_requests, :id, where: INDEX_CONDITION, name: INDEX_NAME)
+ end
+
+ def down
+ add_concurrent_index(:merge_requests, :id, where: INDEX_CONDITION, name: INDEX_NAME)
+ end
+end
diff --git a/db/schema_migrations/20230404160131 b/db/schema_migrations/20230404160131
new file mode 100644
index 00000000000..089788a185f
--- /dev/null
+++ b/db/schema_migrations/20230404160131
@@ -0,0 +1 @@
+d49adae338b04deee154fd2fcb9bebf4f746eb5e7d1d39402a617ca511a06bfe \ No newline at end of file
diff --git a/db/schema_migrations/20230425521418 b/db/schema_migrations/20230425521418
new file mode 100644
index 00000000000..52d053b6b23
--- /dev/null
+++ b/db/schema_migrations/20230425521418
@@ -0,0 +1 @@
+251e091be6b704a3bcb43d2c9a0b4123dd2ba2f9166161c1fdbe7e7ab3edc57f \ No newline at end of file
diff --git a/db/schema_migrations/20230505122015 b/db/schema_migrations/20230505122015
new file mode 100644
index 00000000000..d08efd284c0
--- /dev/null
+++ b/db/schema_migrations/20230505122015
@@ -0,0 +1 @@
+703e964d90c3758f26ca852b6ca4b62319a1fe30e41cd4cf87f128aef5bf0360 \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 69428063ae6..75087462e3a 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -14486,7 +14486,8 @@ CREATE TABLE container_registry_data_repair_details (
missing_count integer DEFAULT 0,
project_id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
- updated_at timestamp with time zone NOT NULL
+ updated_at timestamp with time zone NOT NULL,
+ status smallint DEFAULT 0 NOT NULL
);
CREATE TABLE container_repositories (
@@ -18364,7 +18365,8 @@ CREATE TABLE milestones (
description_html text,
start_date date,
cached_markdown_version integer,
- group_id integer
+ group_id integer,
+ lock_version integer DEFAULT 0 NOT NULL
);
CREATE SEQUENCE milestones_id_seq
@@ -30344,6 +30346,8 @@ CREATE INDEX index_composer_cache_files_where_namespace_id_is_null ON packages_c
CREATE INDEX index_container_expiration_policies_on_next_run_at_and_enabled ON container_expiration_policies USING btree (next_run_at, enabled);
+CREATE INDEX index_container_registry_data_repair_details_on_status ON container_registry_data_repair_details USING btree (status);
+
CREATE INDEX index_container_repositories_on_greatest_completed_at ON container_repositories USING btree (GREATEST(migration_pre_import_done_at, migration_import_done_at, migration_aborted_at, migration_skipped_at)) WHERE (migration_state = ANY (ARRAY['import_done'::text, 'pre_import_done'::text, 'import_aborted'::text, 'import_skipped'::text]));
CREATE INDEX index_container_repositories_on_migration_state_import_done_at ON container_repositories USING btree (migration_state, migration_import_done_at);
@@ -33032,8 +33036,6 @@ CREATE UNIQUE INDEX issue_user_mentions_on_issue_id_index ON issue_user_mentions
CREATE UNIQUE INDEX kubernetes_namespaces_cluster_and_namespace ON clusters_kubernetes_namespaces USING btree (cluster_id, namespace);
-CREATE INDEX merge_request_mentions_temp_index ON merge_requests USING btree (id) WHERE ((description ~~ '%@%'::text) OR ((title)::text ~~ '%@%'::text));
-
CREATE UNIQUE INDEX merge_request_user_mentions_on_mr_id_and_note_id_index ON merge_request_user_mentions USING btree (merge_request_id, note_id);
CREATE UNIQUE INDEX merge_request_user_mentions_on_mr_id_index ON merge_request_user_mentions USING btree (merge_request_id) WHERE (note_id IS NULL);
diff --git a/doc/administration/housekeeping.md b/doc/administration/housekeeping.md
index d58989db70c..3a2b3657145 100644
--- a/doc/administration/housekeeping.md
+++ b/doc/administration/housekeeping.md
@@ -166,6 +166,10 @@ You can change this default in Gitaly configuration. The following snippet
enables daily background repository maintenance starting at 23:00 for 1 hour
for the `default` storage:
+::Tabs
+
+:::TabTitle Self-compiled (source)
+
```toml
[daily_maintenance]
start_hour = 23
@@ -182,6 +186,33 @@ maintenance:
disabled = true
```
+:::TabTitle Linux package (Omnibus)
+
+```ruby
+gitaly['configuration'] = {
+ daily_maintenance: {
+ disabled: false,
+ start_hour: 23,
+ start_minute: 00,
+ duration: '1h',
+ storages: ['default'],
+ },
+}
+```
+
+Use the following snippet to completely disable background repository
+maintenance:
+
+```ruby
+gitaly['configuration'] = {
+ daily_maintenance: {
+ disabled: true,
+ },
+}
+```
+
+::EndTabs
+
## Object pool repositories
Object pool repositories are used by GitLab to deduplicate objects across forks
diff --git a/doc/administration/raketasks/maintenance.md b/doc/administration/raketasks/maintenance.md
index 055cf944046..06f7203f695 100644
--- a/doc/administration/raketasks/maintenance.md
+++ b/doc/administration/raketasks/maintenance.md
@@ -386,7 +386,7 @@ You can also [enable reindexing as a regular cron job](https://docs.gitlab.com/o
Sometimes you may need to re-import the common metrics that power the Metrics dashboards.
-This could be as a result of [updating existing metrics](../../development/prometheus_metrics.md#update-existing-metrics), or as a [troubleshooting measure](../../operations/metrics/dashboards/index.md#troubleshooting).
+This could be as a result of [updating existing metrics](../../development/prometheus_metrics.md#update-existing-metrics).
To re-import the metrics you can run:
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 50d48a7242f..e3abed66d77 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -1785,6 +1785,10 @@ Input type: `CreateAlertIssueInput`
### `Mutation.createAnnotation`
+WARNING:
+**Deprecated** in 16.0.
+Underlying feature was removed in 16.0.
+
Input type: `CreateAnnotationInput`
#### Arguments
@@ -2593,6 +2597,10 @@ Input type: `DastSiteValidationRevokeInput`
### `Mutation.deleteAnnotation`
+WARNING:
+**Deprecated** in 16.0.
+Underlying feature was removed in 16.0.
+
Input type: `DeleteAnnotationInput`
#### Arguments
@@ -12784,7 +12792,60 @@ four standard [pagination arguments](#connection-pagination-arguments):
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="commitparentnamesnames"></a>`names` | [`[String!]`](#string) | Names of the commit parent (branch or tag). |
-| <a id="commitparentnamestotalcount"></a>`totalCount` | [`Int`](#int) | Total of parent branches or tags. |
+
+### `CommitReferences`
+
+#### Fields with arguments
+
+##### `CommitReferences.containingBranches`
+
+Get branch names containing a given commit.
+
+Returns [`CommitParentNames`](#commitparentnames).
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="commitreferencescontainingbranchesexcludetipped"></a>`excludeTipped` | [`Boolean!`](#boolean) | Exclude tipping refs. WARNING: This argument can be confusing, if there is a limit. for example set the limit to 5 and in the 5 out a total of 25 refs there is 2 tipped refs, then the method will only 3 refs, even though there is more. |
+| <a id="commitreferencescontainingbrancheslimit"></a>`limit` | [`Int!`](#int) | Number of ref names to return. |
+
+##### `CommitReferences.containingTags`
+
+Get tag names containing a given commit.
+
+Returns [`CommitParentNames`](#commitparentnames).
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="commitreferencescontainingtagsexcludetipped"></a>`excludeTipped` | [`Boolean!`](#boolean) | Exclude tipping refs. WARNING: This argument can be confusing, if there is a limit. for example set the limit to 5 and in the 5 out a total of 25 refs there is 2 tipped refs, then the method will only 3 refs, even though there is more. |
+| <a id="commitreferencescontainingtagslimit"></a>`limit` | [`Int!`](#int) | Number of ref names to return. |
+
+##### `CommitReferences.tippingBranches`
+
+Get branch names tipping at a given commit.
+
+Returns [`CommitParentNames`](#commitparentnames).
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="commitreferencestippingbrancheslimit"></a>`limit` | [`Int!`](#int) | Number of ref names to return. |
+
+##### `CommitReferences.tippingTags`
+
+Get tag names tipping at a given commit.
+
+Returns [`CommitParentNames`](#commitparentnames).
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="commitreferencestippingtagslimit"></a>`limit` | [`Int!`](#int) | Number of ref names to return. |
### `ComplianceFramework`
@@ -16346,6 +16407,7 @@ Check permissions for the current user on a issue.
| <a id="issuepermissionsreaddesign"></a>`readDesign` | [`Boolean!`](#boolean) | Indicates the user can perform `read_design` on this resource. |
| <a id="issuepermissionsreadissue"></a>`readIssue` | [`Boolean!`](#boolean) | Indicates the user can perform `read_issue` on this resource. |
| <a id="issuepermissionsreopenissue"></a>`reopenIssue` | [`Boolean!`](#boolean) | Indicates the user can perform `reopen_issue` on this resource. |
+| <a id="issuepermissionsupdatedesign"></a>`updateDesign` | [`Boolean!`](#boolean) | Indicates the user can perform `update_design` on this resource. |
| <a id="issuepermissionsupdateissue"></a>`updateIssue` | [`Boolean!`](#boolean) | Indicates the user can perform `update_issue` on this resource. |
### `IssueStatusCountsType`
@@ -19046,6 +19108,7 @@ Represents a product analytics dashboard visualization.
| <a id="projectsshurltorepo"></a>`sshUrlToRepo` | [`String`](#string) | URL to connect to the project via SSH. |
| <a id="projectstarcount"></a>`starCount` | [`Int!`](#int) | Number of times the project has been starred. |
| <a id="projectstatistics"></a>`statistics` | [`ProjectStatistics`](#projectstatistics) | Statistics of the project. |
+| <a id="projectstatisticsdetailspaths"></a>`statisticsDetailsPaths` | [`ProjectStatisticsRedirect`](#projectstatisticsredirect) | Redirects for Statistics of the project. |
| <a id="projectsuggestioncommitmessage"></a>`suggestionCommitMessage` | [`String`](#string) | Commit message used to apply merge request suggestions. |
| <a id="projecttaglist"></a>`tagList` **{warning-solid}** | [`String`](#string) | **Deprecated** in 13.12. Use `topics`. |
| <a id="projectterraformstates"></a>`terraformStates` | [`TerraformStateConnection`](#terraformstateconnection) | Terraform states associated with the project. (see [Connections](#connections)) |
@@ -19185,19 +19248,6 @@ four standard [pagination arguments](#connection-pagination-arguments):
| ---- | ---- | ----------- |
| <a id="projectboardsid"></a>`id` | [`BoardID`](#boardid) | Find a board by its ID. |
-##### `Project.branchesTippingAtCommit`
-
-Get branch names tipping at a given commit.
-
-Returns [`CommitParentNames`](#commitparentnames).
-
-###### Arguments
-
-| Name | Type | Description |
-| ---- | ---- | ----------- |
-| <a id="projectbranchestippingatcommitcommitsha"></a>`commitSha` | [`String!`](#string) | Project commit SHA identifier. For example, `287774414568010855642518513f085491644061`. |
-| <a id="projectbranchestippingatcommitlimit"></a>`limit` | [`Int`](#int) | Number of branch names to return. |
-
##### `Project.ciConfigVariables`
CI/CD config variable.
@@ -19273,6 +19323,22 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="projectclusteragentshasremotedevelopmentagentconfig"></a>`hasRemoteDevelopmentAgentConfig` | [`Boolean`](#boolean) | Returns only cluster agents which have an associated remote development agent config. |
| <a id="projectclusteragentshasvulnerabilities"></a>`hasVulnerabilities` | [`Boolean`](#boolean) | Returns only cluster agents which have vulnerabilities. |
+##### `Project.commitReferences`
+
+Get tag names containing a given commit.
+
+WARNING:
+**Introduced** in 16.0.
+This feature is an Experiment. It can be changed or removed at any time.
+
+Returns [`CommitReferences`](#commitreferences).
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="projectcommitreferencescommitsha"></a>`commitSha` | [`String!`](#string) | Project commit SHA identifier. For example, `287774414568010855642518513f085491644061`. |
+
##### `Project.containerRepositories`
Container repositories of the project.
@@ -20228,19 +20294,6 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="projectsnippetsids"></a>`ids` | [`[SnippetID!]`](#snippetid) | Array of global snippet IDs. For example, `gid://gitlab/ProjectSnippet/1`. |
| <a id="projectsnippetsvisibility"></a>`visibility` | [`VisibilityScopesEnum`](#visibilityscopesenum) | Visibility of the snippet. |
-##### `Project.tagsTippingAtCommit`
-
-Get tag names tipping at a given commit.
-
-Returns [`CommitParentNames`](#commitparentnames).
-
-###### Arguments
-
-| Name | Type | Description |
-| ---- | ---- | ----------- |
-| <a id="projecttagstippingatcommitcommitsha"></a>`commitSha` | [`String!`](#string) | Project commit SHA identifier. For example, `287774414568010855642518513f085491644061`. |
-| <a id="projecttagstippingatcommitlimit"></a>`limit` | [`Int`](#int) | Number of branch names to return. |
-
##### `Project.terraformState`
Find a single Terraform state by name.
@@ -20561,6 +20614,19 @@ Represents the source of a security policy belonging to a project.
| <a id="projectstatisticsuploadssize"></a>`uploadsSize` | [`Float`](#float) | Uploads size of the project in bytes. |
| <a id="projectstatisticswikisize"></a>`wikiSize` | [`Float`](#float) | Wiki size of the project in bytes. |
+### `ProjectStatisticsRedirect`
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="projectstatisticsredirectbuildartifacts"></a>`buildArtifacts` | [`String!`](#string) | Redirection Route for job_artifacts. |
+| <a id="projectstatisticsredirectcontainerregistry"></a>`containerRegistry` | [`String!`](#string) | Redirection Route for container_registry. |
+| <a id="projectstatisticsredirectpackages"></a>`packages` | [`String!`](#string) | Redirection Route for packages. |
+| <a id="projectstatisticsredirectrepository"></a>`repository` | [`String!`](#string) | Redirection Route for repository. |
+| <a id="projectstatisticsredirectsnippets"></a>`snippets` | [`String!`](#string) | Redirection Route for snippets. |
+| <a id="projectstatisticsredirectwiki"></a>`wiki` | [`String!`](#string) | Redirection Route for wiki. |
+
### `ProjectValueStreamAnalyticsFlowMetrics`
Exposes aggregated value stream flow metrics.
diff --git a/doc/api/packages.md b/doc/api/packages.md
index 58026f5e25f..86eaf3028cf 100644
--- a/doc/api/packages.md
+++ b/doc/api/packages.md
@@ -37,12 +37,6 @@ GET /projects/:id/packages
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/:id/packages"
```
-> **Deprecation:**
->
-> The `pipelines` attribute in the response is deprecated in favor of the package pipelines endpoint, which was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/341950) in GitLab 16.0. The `pipelines` attribute always returns an empty array if the feature flag is enabled.
-> The `pipeline` attribute in the response is deprecated in favor of `pipelines`, which was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/44348) in GitLab 13.6. Both are available until 13.7.
-> The `build_info` attribute in the response is deprecated in favor of `pipeline`, which was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28040) in GitLab 12.10.
-
Example response:
```json
@@ -52,16 +46,14 @@ Example response:
"name": "com/mycompany/my-app",
"version": "1.0-SNAPSHOT",
"package_type": "maven",
- "created_at": "2019-11-27T03:37:38.711Z",
- "pipelines": []
+ "created_at": "2019-11-27T03:37:38.711Z"
},
{
"id": 2,
"name": "@foo/bar",
"version": "1.0.3",
"package_type": "npm",
- "created_at": "2019-11-27T03:37:38.711Z",
- "pipelines": []
+ "created_at": "2019-11-27T03:37:38.711Z"
},
{
"id": 3,
@@ -74,8 +66,7 @@ Example response:
"delete_api_path": "https://gitlab.example.com/api/v4/projects/1/packages/3"
},
"created_at": "2029-12-16T20:33:34.316Z",
- "tags": [],
- "pipelines": []
+ "tags": []
}
]
```
@@ -115,7 +106,6 @@ curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/a
> **Deprecation:**
>
-> The `pipelines` attribute in the response is deprecated in favor of the package pipelines endpoint, which was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/341950) in GitLab 16.0. The `pipelines` attribute always returns an empty array if the feature flag is enabled.
> The `pipeline` attribute in the response is deprecated in favor of `pipelines`, which was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/44348) in GitLab 13.6. Both are available until 13.7.
> The `build_info` attribute in the response is deprecated in favor of `pipeline`, which was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28040) in GitLab 12.10.
@@ -133,7 +123,21 @@ Example response:
"delete_api_path": "/namespace1/project1/-/packages/1"
},
"created_at": "2019-11-27T03:37:38.711Z",
- "pipelines": []
+ "pipelines": [
+ {
+ "id": 123,
+ "status": "pending",
+ "ref": "new-pipeline",
+ "sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a",
+ "web_url": "https://example.com/foo/bar/pipelines/47",
+ "created_at": "2016-08-11T11:28:34.085Z",
+ "updated_at": "2016-08-11T11:32:35.169Z",
+ "user": {
+ "name": "Administrator",
+ "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon"
+ }
+ }
+ ]
},
{
"id": 2,
@@ -145,7 +149,21 @@ Example response:
"delete_api_path": "/namespace1/project1/-/packages/1"
},
"created_at": "2019-11-27T03:37:38.711Z",
- "pipelines": []
+ "pipelines": [
+ {
+ "id": 123,
+ "status": "pending",
+ "ref": "new-pipeline",
+ "sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a",
+ "web_url": "https://example.com/foo/bar/pipelines/47",
+ "created_at": "2016-08-11T11:28:34.085Z",
+ "updated_at": "2016-08-11T11:32:35.169Z",
+ "user": {
+ "name": "Administrator",
+ "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon"
+ }
+ }
+ ]
}
]
```
@@ -179,7 +197,6 @@ curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/a
> **Deprecation:**
>
-> The `pipelines` attribute in the response is deprecated in favor of the package pipelines endpoint, which was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/341950) in GitLab 16.0. The `pipelines` attribute always returns an empty array if the feature flag is enabled.
> The `pipeline` attribute in the response is deprecated in favor of `pipelines`, which was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/44348) in GitLab 13.6. Both are available until 13.7.
> The `build_info` attribute in the response is deprecated in favor of `pipeline`, which was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28040) in GitLab 12.10.
@@ -197,7 +214,21 @@ Example response:
},
"created_at": "2019-11-27T03:37:38.711Z",
"last_downloaded_at": "2022-09-07T07:51:50.504Z"
- "pipelines": [],
+ "pipelines": [
+ {
+ "id": 123,
+ "status": "pending",
+ "ref": "new-pipeline",
+ "sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a",
+ "web_url": "https://example.com/foo/bar/pipelines/47",
+ "created_at": "2016-08-11T11:28:34.085Z",
+ "updated_at": "2016-08-11T11:32:35.169Z",
+ "user": {
+ "name": "Administrator",
+ "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon"
+ }
+ }
+ ],
"versions": [
{
"id":2,
diff --git a/doc/development/ai_features.md b/doc/development/ai_features.md
index 11442755df3..8e2746276a1 100644
--- a/doc/development/ai_features.md
+++ b/doc/development/ai_features.md
@@ -192,7 +192,7 @@ The CircuitBreaker concern is a reusable module that you can include in any clas
### Use CircuitBreaker
-To use the CircuitBreaker concern, you need to include it in a class and define the `service_name` method, which should return the name of the service that the circuit breaker is protecting. For example:
+To use the CircuitBreaker concern, you need to include it in a class. For example:
```ruby
class MyService
@@ -202,22 +202,16 @@ class MyService
run_with_circuit do
# Code that interacts with external service goes here
- raise MyCustomError
+ raise InternalServerError
end
end
-
- private
-
- def service_name
- my_service
- end
end
```
The `call_external_service` method is an example method that interacts with an external service.
By wrapping the code that interacts with the external service with `run_with_circuit`, the method is executed within the circuit breaker.
The circuit breaker is created and configured by the `circuit` method, which is called automatically when the `CircuitBreaker` module is included.
-The method should raise a custom error, that matches the `exceptions` from the concern.
+The method should raise `InternalServerError` error which will be counted towards the error threshold if raised during the execution of the code block.
The circuit breaker tracks the number of errors and the rate of requests,
and opens the circuit if it reaches the configured error threshold or volume threshold.
@@ -231,12 +225,11 @@ The circuit breaker is configured with two constants which control the number of
- `VOLUME_THRESHOLD`
You can adjust these values as needed for the specific service and usage pattern.
-The concern also raises an `InternalServerError` exception, which is counted towards the error threshold if raised during the execution of the code block.
+The `InternalServerError` is the exception class counted towards the error threshold if raised during the execution of the code block.
This is the exception class that triggers the circuit breaker when raised by the code that interacts with the external service.
-By default, the `CircuitBreaker` concern uses `StandardError`.
NOTE:
-The service_name method must be implemented by the including class to provide a unique identifier for the service being protected. The `CircuitBreaker` module depends on the `Circuitbox` gem to provide the circuit breaker implementation.
+The `CircuitBreaker` module depends on the `Circuitbox` gem to provide the circuit breaker implementation. By default, the service name is inferred from the class name where the concern module is included. Override the `service_name` method if the name needs to be different.
### Testing
@@ -413,58 +406,6 @@ end
TODO
-## Circuit Breaker concern
-
-The `CircuitBreaker` concern is a reusable module that can be included in any class that needs to run code with circuit breaker protection. The concern provides a `run_with_circuit` method that wraps a code block with circuit breaker functionality, which can help prevent cascading failures and improve the resilience of the system. Resources about the circuit breaker pattern:
-
-- [What is Circuit breaker](https://martinfowler.com/bliki/CircuitBreaker.html)
-- [How it works](https://github.com/Netflix/Hystrix/wiki/How-it-Works#circuit-breaker)
-
-The CircuitBreaker module depends on the [Circuitbox](https://github.com/yammer/circuitbox) gem to provide the circuit breaker implementation.
-
-### Usage
-
-To use the `CircuitBreaker` concern, include it in a class and define the `service_name` method, which should return the name of the service that the circuit breaker is protecting. For example:
-
-```ruby
-class MyService
- include Gitlab::Llm::Concerns::CircuitBreaker
-
- def call_external_service
- run_with_circuit do
- # Code that interacts with external service goes here
-
- raise InternalServerError
- end
- end
-
- private
-
- def service_name
- :my_service
- end
-end
-```
-
-The `call_external_service` method is an example method that interacts with an external service. By wrapping the code that interacts with the external service with `run_with_circuit`, the method will be executed within the circuit breaker. The circuit breaker is created and configured by the `circuit` method, which is called automatically when the `CircuitBreaker` module is included. The method should raise `InternalServerError` error which will be counted towards the error threshold if raised during the execution of the code block.
-
-The circuit breaker will track the number of errors and the rate of requests, and open the circuit if it reaches the configured error threshold or volume threshold. If the circuit is open, subsequent requests will fail fast without executing the code block, and the circuit breaker will periodically allow a small number of requests through to test the service's availability before closing the circuit again.
-
-### Configuration
-
-The circuit breaker is configured with two constants: `ERROR_THRESHOLD` and `VOLUME_THRESHOLD`, which control the number of errors and requests at which the circuit will open. These values can be adjusted as needed for the specific service and usage pattern. The `InternalServerError` is the exception class that will trigger the circuit breaker when raised by the code that interacts with the external service.
-
-### Testing
-
-To test code that uses the `CircuitBreaker` concern, use RSpec shared examples and pass the `service` and `subject` variables:
-
-```ruby
-it_behaves_like 'has circuit breaker' do
- let(:service) { dummy_class.new }
- let(:subject) { service.dummy_method }
-end
-```
-
## Security
Refer to the [secure coding guidelines for Artificial Intelligence (AI) features](secure_coding_guidelines.md#artificial-intelligence-ai-features).
diff --git a/doc/development/features_inside_dot_gitlab.md b/doc/development/features_inside_dot_gitlab.md
index f35b37db84e..3c988ec6b21 100644
--- a/doc/development/features_inside_dot_gitlab.md
+++ b/doc/development/features_inside_dot_gitlab.md
@@ -9,7 +9,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
We have implemented standard features that depend on configuration files in the `.gitlab/` directory. You can find `.gitlab/` in various GitLab repositories.
When implementing new features, please refer to these existing features to avoid conflicts:
-- [Custom Dashboards](../operations/metrics/dashboards/index.md#add-a-new-dashboard-to-your-project): `.gitlab/dashboards/`.
- [Issue Templates](../user/project/description_templates.md#create-an-issue-template): `.gitlab/issue_templates/`.
- [Merge request Templates](../user/project/description_templates.md#create-a-merge-request-template): `.gitlab/merge_request_templates/`.
- [GitLab agent](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/configuration_repository.md#layout): `.gitlab/agents/`.
diff --git a/doc/development/internal_users.md b/doc/development/internal_users.md
index 541a7117c6a..ce13324507d 100644
--- a/doc/development/internal_users.md
+++ b/doc/development/internal_users.md
@@ -40,7 +40,7 @@ For this bot:
Other examples of internal users:
-- [Alert Bot](../operations/metrics/alerts.md#trigger-actions-from-alerts)
+- [Alert Bot](../operations/incident_management/alerts.md#trigger-actions-from-alerts)
- [Ghost User](../user/profile/account/delete_account.md#associated-records)
- [Support Bot](../user/project/service_desk.md#support-bot-user)
- Visual Review Bot
diff --git a/doc/development/sec/CycloneDX_property_taxonomy.md b/doc/development/sec/CycloneDX_property_taxonomy.md
new file mode 100644
index 00000000000..6d09529a194
--- /dev/null
+++ b/doc/development/sec/CycloneDX_property_taxonomy.md
@@ -0,0 +1,72 @@
+---
+stage: Govern
+group: Threat Insights
+info: BEFORE MAKING CHANGES TO THIS FILE, PLEASE REACH OUT TO THE THREAT INSIGHTS ENGINEERING TEAM, @gitlab-org/govern/threat-insights. To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# GitLab CycloneDX property taxonomy
+
+This document defines the namespaces and properties used by the `gitlab` namespace
+in the [CycloneDX Property Taxonomy](https://github.com/CycloneDX/cyclonedx-property-taxonomy).
+
+## Where properties should be located
+
+The `Property of` column describes what object a property may be attached to.
+
+- Properties attached to the `metadata` apply to all objects in the document.
+- Properties attached to an individual object apply to that object and any others nested underneath it.
+- Objects which may nest themselves (such as `components`) may only have properties applied to the top-level object.
+
+## `gitlab` namespace taxonomy
+
+| Namespace | Description |
+| --------------------- | ----------- |
+| `meta` | Namespace for data about the property schema. |
+| `dependency_scanning` | Namespace for data related to dependency scanning. |
+
+## `gitlab:meta` namespace taxonomy
+
+| Property | Description | Property of |
+| ---------------------------- | ----------- | ----------- |
+| `gitlab:meta:schema_version` | Used by GitLab to determine how to parse the properties in a report. Must be `1`. | `metadata` |
+
+## `gitlab:dependency_scanning` namespace taxonomy
+
+### Properties
+
+| Property | Description | Example values | Property of |
+| ---------------------------------------- | ----------- | -------------- | ----------- |
+| `gitlab:dependency_scanning:category` | The name of the category or dependency group that the dependency belongs to. If no category is specified, `production` is used by default. | `production`, `development`, `test` | `components` |
+
+### Namespaces
+
+| Namespace | Description |
+| -------------------------------------------- | ----------- |
+| `gitlab:dependency_scanning:input_file` | Namespace for information about the input file analyzed to produce the dependency. |
+| `gitlab:dependency_scanning:source_file` | Namespace for information about the file you can edit to manage the dependency. |
+| `gitlab:dependency_scanning:package_manager` | Namespace for information about the package manager associated with the dependency. |
+| `gitlab:dependency_scanning:language` | Namespace for information about the programming language associated with the dependency. |
+
+## `gitlab:dependency_scanning:input_file` namespace taxonomy
+
+| Property | Description | Example values | Property of |
+| --------------------------------------------- | ----------- | -------------- | ----------- |
+| `gitlab:dependency_scanning:input_file:path` | The path, relative to the root of the repository, to the file analyzed to produce the dependency. Usually, the lock file. | `package-lock.json`, `Gemfile.lock`, `go.sum` | `metadata`, `component` |
+
+## `gitlab:dependency_scanning:source_file` namespace taxonomy
+
+| Property | Description | Example values | Property of |
+| -------------------------------------------- | ----------- | -------------- | ----------- |
+| `gitlab:dependency_scanning:source_file:path` | The path, relative to the root of the repository, to the file you can edit to manage the dependency. | `package.json`, `Gemfile`, `go.mod` | `metadata`, `component` |
+
+## `gitlab:dependency_scanning:package_manager` namespace taxonomy
+
+| Property | Description | Example values | Property of |
+| ------------------------------------------------- | ----------- | -------------- | ----------- |
+| `gitlab:dependency_scanning:package_manager:name` | The name of the package manager associated with the dependency | `npm`, `bundler`, `go` | `metadata`, `component` |
+
+## `gitlab:dependency_scanning:language` namespace taxonomy
+
+| Property | Description | Example values | Property of |
+| ------------------------------------------ | ----------- | -------------- | ----------- |
+| `gitlab:dependency_scanning:language:name` | The name of the programming language associated with the dependency | `JavaScript`, `Ruby`, `Go` | `metadata`, `component` |
diff --git a/doc/operations/incident_management/alerts.md b/doc/operations/incident_management/alerts.md
index 6d6fde45de7..74e0ed5f06a 100644
--- a/doc/operations/incident_management/alerts.md
+++ b/doc/operations/incident_management/alerts.md
@@ -205,3 +205,28 @@ You can manually create a [to-do item](../../user/todos.md) for yourself
from an alert, and view it later on your **To-Do List**.
To add a to-do item, on the right sidebar, select **Add a to do**.
+
+### Trigger actions from alerts **(ULTIMATE)**
+
+> - Introduced in GitLab 13.1: incidents are not created automatically by default.
+> - Mapping common severity values from the alert payload [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/50871) in GitLab 13.9.
+
+Turn on creating [incidents](incidents.md) automatically whenever an alert is triggered.
+
+Prerequisites:
+
+- You must have at least the Maintainer role for the project.
+
+To configure the actions:
+
+1. On the top bar, select **Main menu > Projects** and find your project.
+1. On the left sidebar, select **Settings > Monitor**.
+1. Expand the **Alerts** section, then select the **Alert settings** tab.
+1. Select the **Create an incident** checkbox.
+1. Optional. To customize the incident, from the **Incident template**, select a template to be
+ appended to the [incident summary](incidents.md#summary).
+ If the dropdown list is empty,
+ [create an issue template](../../user/project/description_templates.md#create-an-issue-template) first.
+1. Optional. To send [an email notification](paging.md#email-notifications-for-alerts), select the
+ **Send a single email notification to Owners and Maintainers for new alerts** checkbox.
+1. Select **Save changes**.
diff --git a/doc/operations/incident_management/incidents.md b/doc/operations/incident_management/incidents.md
index 9bfaf0efa7e..5f1a2880c4b 100644
--- a/doc/operations/incident_management/incidents.md
+++ b/doc/operations/incident_management/incidents.md
@@ -70,7 +70,7 @@ To filter the incident list by author or assignee, enter these values in the sea
### Summary
The summary section for incidents provides critical details about the
-incident and the contents of the issue template (if [selected](../metrics/alerts.md#trigger-actions-from-alerts)). The highlighted
+incident and the contents of the issue template (if [selected](alerts.md#trigger-actions-from-alerts)). The highlighted
bar at the top of the incident displays from left to right:
- The link to the original alert.
@@ -87,7 +87,7 @@ Below the highlight bar, a summary includes the following fields:
The incident summary can be further customized using
[GitLab Flavored Markdown](../../user/markdown.md).
-If an incident is [created from an alert](../metrics/alerts.md#trigger-actions-from-alerts)
+If an incident is [created from an alert](alerts.md#trigger-actions-from-alerts)
that provided Markdown for the incident, then the Markdown is appended to the summary.
If an incident template is configured for the project, then the template content is appended at the end.
@@ -169,14 +169,13 @@ label to the incident.
## Related topics
- [Create an incident](manage_incidents.md#create-an-incident)
-- [Create an incident automatically](../metrics/alerts.md#trigger-actions-from-alerts)
+- [Create an incident automatically](alerts.md#trigger-actions-from-alerts)
whenever an alert is triggered
- [View incidents list](manage_incidents.md#view-incidents-list)
- [Assign to a user](manage_incidents.md#assign-to-a-user)
- [Change incident severity](manage_incidents.md#change-severity)
- [Change incident status](manage_incidents.md#change-status)
- [Change escalation policy](manage_incidents.md#change-escalation-policy)
-- [Embed metrics](manage_incidents.md#embed-metrics)
- [Close an incident](manage_incidents.md#close-an-incident)
- [Automatically close incidents via recovery alerts](manage_incidents.md#automatically-close-incidents-via-recovery-alerts)
- [Add a to-do item](../../user/todos.md#create-a-to-do-item)
diff --git a/doc/operations/incident_management/manage_incidents.md b/doc/operations/incident_management/manage_incidents.md
index 9d0c8075ff9..187a398b1ee 100644
--- a/doc/operations/incident_management/manage_incidents.md
+++ b/doc/operations/incident_management/manage_incidents.md
@@ -70,7 +70,7 @@ You are then credited with the alert's status change.
### Automatically, when an alert is triggered **(ULTIMATE)**
-In the project settings, you can turn on [creating an incident automatically](../metrics/alerts.md#trigger-actions-from-alerts)
+In the project settings, you can turn on [creating an incident automatically](alerts.md#trigger-actions-from-alerts)
whenever an alert is triggered.
### Using the PagerDuty webhook
@@ -201,18 +201,14 @@ In GitLab 15.1 and earlier, the escalation policy for [incidents created from al
reflects the alert's escalation policy and cannot be changed. In [GitLab 15.2 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/356057),
the incident escalation policy is independent and can be changed.
-## Embed metrics
+<!--- start_remove The following content will be removed on remove_date: '2023-08-22' -->
-You can embed metrics anywhere [GitLab Flavored Markdown](../../user/markdown.md) is
-used, like descriptions or comments. Embedding
-metrics helps you share them when discussing incidents or performance issues.
+## Embed metrics (removed)
-To embed metrics in a Markdown text box in GitLab,
-[paste the link to the dashboard](../metrics/embed.md#embedding-gitlab-managed-kubernetes-metrics).
+This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7
+and [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/399231) in 16.0.
-You can embed both [GitLab-hosted metrics](../metrics/embed.md) (deprecated) and
-[Grafana metrics](../metrics/embed_grafana.md) in incidents and issue
-templates.
+<!--- end_remove -->
## Close an incident
diff --git a/doc/operations/incident_management/slack.md b/doc/operations/incident_management/slack.md
index 62f77ec9f06..1f6097ccbdb 100644
--- a/doc/operations/incident_management/slack.md
+++ b/doc/operations/incident_management/slack.md
@@ -69,7 +69,7 @@ To declare a GitLab incident from Slack:
- The project where the incident should be created.
- The severity of the incident.
- If there is an existing [incident template](../metrics/alerts.md#trigger-actions-from-alerts) for your
+ If there is an existing [incident template](alerts.md#trigger-actions-from-alerts) for your
project, that template is automatically applied to the description text box. The template is applied
only if the description text box is empty.
diff --git a/doc/operations/index.md b/doc/operations/index.md
index 56b27af316b..922ec557c4c 100644
--- a/doc/operations/index.md
+++ b/doc/operations/index.md
@@ -9,27 +9,14 @@ info: To determine the technical writer assigned to the Stage/Group associated w
GitLab provides a variety of tools to help operate and maintain
your applications.
-## Measure reliability and stability with metrics (deprecated)
+<!--- start_remove The following content will be removed on remove_date: '2023-08-22' -->
-> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7.
+## Measure reliability and stability with metrics (removed)
-WARNING:
-This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541)
-for use in GitLab 14.7, and is planned for removal in GitLab 16.0.
+This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7
+and [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/399231) in 16.0.
-Metrics help you understand the health and performance of your infrastructure,
-applications, and systems by providing insights into your application's reliability,
-stability, and performance. GitLab provides a default dashboard that you
-can extend with custom metrics, and augment with additional custom dashboards. You
-can track the metrics that matter most to your team, generate automated alerts when
-performance degrades, and manage those alerts - all within GitLab.
-
-- Collect [Prometheus metrics](../user/project/integrations/prometheus_library/index.md).
-- Monitor application status with the [out-of-the-box metrics dashboard](metrics/index.md),
- which you can [customize](metrics/dashboards/settings.md).
-- Create [custom performance alerts](metrics/alerts.md).
-- Create [custom metrics](metrics/index.md#adding-custom-metrics) and
- [custom dashboards](metrics/dashboards/index.md).
+<!--- end_remove -->
## Manage alerts and incidents
@@ -38,11 +25,10 @@ issues across multiple systems and aggregate alerts in a centralized place. Your
team needs a single, central interface where they can investigate alerts
and promote the critical alerts to incidents.
-Are your alerts too noisy? Alerts configured on GitLab metrics can configured
+Are your alerts too noisy? Alerts can be configured
and fine-tuned in GitLab immediately following a fire-fight.
- [Manage alerts and incidents](incident_management/index.md) in GitLab.
-- [Configure alerts for metrics](metrics/alerts.md) in GitLab. (deprecated)
- Create a [status page](incident_management/status_page.md)
to communicate efficiently to your users during an incident.
diff --git a/doc/operations/metrics/alerts.md b/doc/operations/metrics/alerts.md
index 44cd683bc4f..44a257f532b 100644
--- a/doc/operations/metrics/alerts.md
+++ b/doc/operations/metrics/alerts.md
@@ -2,81 +2,11 @@
stage: Monitor
group: Respond
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
+remove_date: '2023-08-22'
+redirect_to: '../index.md'
---
-# Set up alerts for Prometheus metrics **(FREE)**
+# Set up alerts for Prometheus metrics (removed) **(FREE)**
-After [configuring metrics for your CI/CD environment](index.md), you can set up
-alerting for Prometheus metrics, and
-[trigger actions from alerts](#trigger-actions-from-alerts) to notify
-your team when environment performance falls outside of the boundaries you set.
-
-## Prometheus cluster integrations
-
-Alerts are not supported for [Prometheus cluster integrations](../../user/clusters/integrations.md).
-
-## Trigger actions from alerts **(ULTIMATE)**
-
-> - Introduced in GitLab 13.1: incidents are not created automatically by default .
-> - Mapping common severity values from the alert payload ([introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/50871) in GitLab 13.9.
-
-Turn on creating [incidents](../incident_management/incidents.md) automatically whenever an alert is triggered.
-
-Prerequisites:
-
-- You must have at least the Maintainer role for the project.
-
-To configure the actions:
-
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **Settings > Monitor**.
-1. Expand the **Alerts** section, then select the **Alert settings** tab.
-1. Select the **Create an incident** checkbox.
-1. Optional. To customize the incident, from the **Incident template**, select a template to be
- appended to the [incident summary](../incident_management/incidents.md#summary).
- If the dropdown list is empty,
- [create an issue template](../../user/project/description_templates.md#create-an-issue-template) first.
-1. Optional. To send [an email notification](../incident_management/paging.md#email-notifications-for-alerts), select the
- **Send a single email notification to Owners and Maintainers for new alerts** checkbox.
-1. Select **Save changes**.
-
-### Fields in automatically created incidents
-
-Incidents [created automatically from an alert](#trigger-actions-from-alerts) are filled with
-values extracted from the `alerts` field in the
-[webhook payload](https://prometheus.io/docs/alerting/latest/configuration/#webhook_config):
-
-- Incident author: `GitLab Alert Bot`
-- Incident title: Extracted from the alert payload fields `annotations/title`, `annotations/summary`, or `labels/alertname`.
-- Incident description: Extracted from alert payload field `annotations/description`.
-- Alert `Summary`: A list of properties from the alert's payload.
- - `starts_at`: Alert start time from the payload's `startsAt` field
- - `full_query`: Alert query extracted from the payload's `generatorURL` field
- - Optional list of attached annotations extracted from `annotations/*`
-- Alert [GLFM](../../user/markdown.md): GitLab Flavored Markdown from the payload's `annotations/gitlab_incident_markdown` field.
-- Alert severity:
- Extracted from the alert payload field `labels/severity`. Maps case-insensitive
- value to [Alert's severity](../incident_management/alerts.md#alert-severity):
-
- | Alert payload | Mapped to alert severity |
- | ------------- | --------------------------------------------------------------------------- |
- | Critical | `critical`, `s1`, `p1`, `emergency`, `fatal`, or any value not in this list |
- | High | `high`, `s2`, `p2`, `major`, `page` |
- | Medium | `medium`, `s3`, `p3`, `error`, `alert` |
- | Low | `low`, `s4`, `p4`, `warn`, `warning` |
- | Info | `info`, `s5`, `p5`, `debug`, `information`, `notice` |
-
-To further customize the incident, you can add labels, mentions, or any other supported
-[quick action](../../user/project/quick_actions.md) in the selected issue template,
-which applies to all incidents. To limit quick actions or other information to
-only specific types of alerts, use the `annotations/gitlab_incident_markdown` field.
-
-GitLab tags each incident issue with the `incident` label automatically. If the label
-does not yet exist, it's created automatically.
-
-### Recovery alerts
-
-The alert in GitLab is automatically resolved when Prometheus
-sends a payload with the field `status` set to `resolved`.
-
-You can also configure the associated [incident to be closed automatically](../incident_management/manage_incidents.md#automatically-close-incidents-via-recovery-alerts) when the alert resolves.
+This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7
+and [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/399231) in 16.0.
diff --git a/doc/operations/metrics/dashboards/default.md b/doc/operations/metrics/dashboards/default.md
index 2ff9e558c48..28a3adc5051 100644
--- a/doc/operations/metrics/dashboards/default.md
+++ b/doc/operations/metrics/dashboards/default.md
@@ -2,42 +2,11 @@
stage: Monitor
group: Respond
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
+remove_date: '2023-08-22'
+redirect_to: '../../index.md'
---
-# GitLab-defined metrics dashboards (deprecated) **(FREE)**
+# GitLab-defined metrics dashboards (removed) **(FREE)**
-> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7.
-
-WARNING:
-This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541)
-in GitLab 14.7, and is planned for removal in GitLab 16.0.
-
-GitLab provides some dashboards out-of-the-box for any project with
-[Prometheus available](../../../user/project/integrations/prometheus.md). You can
-[duplicate these GitLab-defined dashboards](index.md#duplicate-a-gitlab-defined-dashboard):
-
-- [Overview dashboard](#overview-dashboard).
-- [Kubernetes pod health dashboard](#kubernetes-pod-health-dashboard).
-
-To learn about the components of a dashboard, read
-[Metrics dashboard for your CI/CD environment](../index.md).
-
-## Overview dashboard
-
-This dashboard is the default metrics dashboard. It displays a large number of
-metrics about the [deployed application](../index.md#configure-prometheus-to-gather-metrics).
-
-![Example of metrics dashboard](../img/example-dashboard_v13_3.png)
-
-## Kubernetes pod health dashboard
-
-This dashboard requires Kubernetes v1.14 or later, due to the
-[change in metric labels](https://github.com/kubernetes/kubernetes/pull/69099)
-in Kubernetes 1.14.
-
-This dashboard displays CPU, memory, network and disk metrics for the pods in your
-[connected Kubernetes cluster](../../../user/infrastructure/clusters/index.md). It provides a
-[variable selector](templating_variables.md#metric_label_values-variable-type)
-at the top of the dashboard to select which pod's metrics to display.
-
-![Kubernetes pod health dashboard](img/k8s_pod_health_dashboard_v13_3.png)
+This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7
+and [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/399231) in 16.0.
diff --git a/doc/operations/metrics/dashboards/develop.md b/doc/operations/metrics/dashboards/develop.md
index af76c09ca80..b7912e164d7 100644
--- a/doc/operations/metrics/dashboards/develop.md
+++ b/doc/operations/metrics/dashboards/develop.md
@@ -2,38 +2,11 @@
stage: Monitor
group: Respond
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
+remove_date: '2023-08-22'
+redirect_to: '../../index.md'
---
-# Developing templates for custom dashboards (deprecated) **(FREE)**
+# Developing templates for custom dashboards (removed) **(FREE)**
-> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7.
-
-WARNING:
-This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541)
-in GitLab 14.7, and is planned for removal in GitLab 16.0.
-
-GitLab provides a template to make it easier for you to create templates for
-[custom dashboards](index.md). Templates provide helpful guidance and
-commented-out examples you can use.
-
-## Apply a dashboard template
-
-Go to the browser-based editor of your choice:
-
-- In the **Repository view**:
-
- 1. Go to **Repository > Files**.
- 1. Select **Add to tree** and select **New file**,
- then select **Select a template type** to see a list of available templates:
- ![Metrics dashboard template selection](img/metrics_dashboard_template_selection_v13_3.png)
-
-- In the **[Web IDE](../../../user/project/web_ide/index.md)**:
-
- 1. Select **Web IDE** when viewing your repository.
- 1. Select **New file**, then select **Choose a template** to see a list of available templates:
- ![Metrics dashboard template selection WebIDE](img/metrics_dashboard_template_selection_web_ide_v13_3.png)
-
-## Custom dashboard templates **(PREMIUM SELF)**
-
-To enable and use a custom dashboard templates on your GitLab instance, read the
-[guide for creating custom templates](../../../user/admin_area/settings/instance_template_repository.md).
+This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7
+and [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/399231) in 16.0.
diff --git a/doc/operations/metrics/dashboards/img/actions_menu_create_add_panel_v13_3.png b/doc/operations/metrics/dashboards/img/actions_menu_create_add_panel_v13_3.png
deleted file mode 100644
index e03fbef3b35..00000000000
--- a/doc/operations/metrics/dashboards/img/actions_menu_create_add_panel_v13_3.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/dashboards/img/actions_menu_create_new_dashboard_v13_3.png b/doc/operations/metrics/dashboards/img/actions_menu_create_new_dashboard_v13_3.png
deleted file mode 100644
index ba4780b730b..00000000000
--- a/doc/operations/metrics/dashboards/img/actions_menu_create_new_dashboard_v13_3.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/dashboards/img/dashboard_external_link_v13_1.png b/doc/operations/metrics/dashboards/img/dashboard_external_link_v13_1.png
deleted file mode 100644
index 3e8d792c53e..00000000000
--- a/doc/operations/metrics/dashboards/img/dashboard_external_link_v13_1.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/dashboards/img/dashboard_local_timezone_v13_1.png b/doc/operations/metrics/dashboards/img/dashboard_local_timezone_v13_1.png
deleted file mode 100644
index 8d45607a940..00000000000
--- a/doc/operations/metrics/dashboards/img/dashboard_local_timezone_v13_1.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/dashboards/img/external_dashboard_link.png b/doc/operations/metrics/dashboards/img/external_dashboard_link.png
deleted file mode 100644
index 82c5e05e467..00000000000
--- a/doc/operations/metrics/dashboards/img/external_dashboard_link.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/dashboards/img/heatmap_chart_too_much_data_v_13_2.png b/doc/operations/metrics/dashboards/img/heatmap_chart_too_much_data_v_13_2.png
deleted file mode 100644
index c3a391b06c7..00000000000
--- a/doc/operations/metrics/dashboards/img/heatmap_chart_too_much_data_v_13_2.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/dashboards/img/heatmap_panel_type.png b/doc/operations/metrics/dashboards/img/heatmap_panel_type.png
deleted file mode 100644
index a2b3911ec68..00000000000
--- a/doc/operations/metrics/dashboards/img/heatmap_panel_type.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/dashboards/img/k8s_pod_health_dashboard_v13_3.png b/doc/operations/metrics/dashboards/img/k8s_pod_health_dashboard_v13_3.png
deleted file mode 100644
index dc0bc951500..00000000000
--- a/doc/operations/metrics/dashboards/img/k8s_pod_health_dashboard_v13_3.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/dashboards/img/metrics_dashboard_annotations_ui_v13.0.png b/doc/operations/metrics/dashboards/img/metrics_dashboard_annotations_ui_v13.0.png
deleted file mode 100644
index a042fbbcf4e..00000000000
--- a/doc/operations/metrics/dashboards/img/metrics_dashboard_annotations_ui_v13.0.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/dashboards/img/metrics_dashboard_panel_preview_v13_3.png b/doc/operations/metrics/dashboards/img/metrics_dashboard_panel_preview_v13_3.png
deleted file mode 100644
index 3c3203265e1..00000000000
--- a/doc/operations/metrics/dashboards/img/metrics_dashboard_panel_preview_v13_3.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/dashboards/img/metrics_dashboard_template_selection_v13_3.png b/doc/operations/metrics/dashboards/img/metrics_dashboard_template_selection_v13_3.png
deleted file mode 100644
index 1571ab9de90..00000000000
--- a/doc/operations/metrics/dashboards/img/metrics_dashboard_template_selection_v13_3.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/dashboards/img/metrics_dashboard_template_selection_web_ide_v13_3.png b/doc/operations/metrics/dashboards/img/metrics_dashboard_template_selection_web_ide_v13_3.png
deleted file mode 100644
index 650f66e9a30..00000000000
--- a/doc/operations/metrics/dashboards/img/metrics_dashboard_template_selection_web_ide_v13_3.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/dashboards/img/panel_context_menu_v14_0.png b/doc/operations/metrics/dashboards/img/panel_context_menu_v14_0.png
deleted file mode 100644
index 78cce5d30b7..00000000000
--- a/doc/operations/metrics/dashboards/img/panel_context_menu_v14_0.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/dashboards/img/prometheus_dashboard_anomaly_panel_type.png b/doc/operations/metrics/dashboards/img/prometheus_dashboard_anomaly_panel_type.png
deleted file mode 100644
index 5cba6fa9038..00000000000
--- a/doc/operations/metrics/dashboards/img/prometheus_dashboard_anomaly_panel_type.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/dashboards/img/prometheus_dashboard_area_panel_type_v12_8.png b/doc/operations/metrics/dashboards/img/prometheus_dashboard_area_panel_type_v12_8.png
deleted file mode 100644
index 8c5663fef12..00000000000
--- a/doc/operations/metrics/dashboards/img/prometheus_dashboard_area_panel_type_v12_8.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/dashboards/img/prometheus_dashboard_bar_chart_panel_type_v12.10.png b/doc/operations/metrics/dashboards/img/prometheus_dashboard_bar_chart_panel_type_v12.10.png
deleted file mode 100644
index 593e31477f4..00000000000
--- a/doc/operations/metrics/dashboards/img/prometheus_dashboard_bar_chart_panel_type_v12.10.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/dashboards/img/prometheus_dashboard_column_panel_type.png b/doc/operations/metrics/dashboards/img/prometheus_dashboard_column_panel_type.png
deleted file mode 100644
index 985f2b04ef3..00000000000
--- a/doc/operations/metrics/dashboards/img/prometheus_dashboard_column_panel_type.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/dashboards/img/prometheus_dashboard_gauge_panel_type_v13_3.png b/doc/operations/metrics/dashboards/img/prometheus_dashboard_gauge_panel_type_v13_3.png
deleted file mode 100644
index 547c565c6f9..00000000000
--- a/doc/operations/metrics/dashboards/img/prometheus_dashboard_gauge_panel_type_v13_3.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/dashboards/img/prometheus_dashboard_label_variable_shorthand.png b/doc/operations/metrics/dashboards/img/prometheus_dashboard_label_variable_shorthand.png
deleted file mode 100644
index 15111a97464..00000000000
--- a/doc/operations/metrics/dashboards/img/prometheus_dashboard_label_variable_shorthand.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/dashboards/img/prometheus_dashboard_label_variables.png b/doc/operations/metrics/dashboards/img/prometheus_dashboard_label_variables.png
deleted file mode 100644
index 9b94d0c6afa..00000000000
--- a/doc/operations/metrics/dashboards/img/prometheus_dashboard_label_variables.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/dashboards/img/prometheus_dashboard_repeated_label.png b/doc/operations/metrics/dashboards/img/prometheus_dashboard_repeated_label.png
deleted file mode 100644
index d43a890f0fa..00000000000
--- a/doc/operations/metrics/dashboards/img/prometheus_dashboard_repeated_label.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/dashboards/img/prometheus_dashboard_single_stat_panel_type.png b/doc/operations/metrics/dashboards/img/prometheus_dashboard_single_stat_panel_type.png
deleted file mode 100644
index 2d7dfb27b49..00000000000
--- a/doc/operations/metrics/dashboards/img/prometheus_dashboard_single_stat_panel_type.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/dashboards/img/prometheus_dashboard_stacked_column_panel_type_v12_8.png b/doc/operations/metrics/dashboards/img/prometheus_dashboard_stacked_column_panel_type_v12_8.png
deleted file mode 100644
index ba67509bcf3..00000000000
--- a/doc/operations/metrics/dashboards/img/prometheus_dashboard_stacked_column_panel_type_v12_8.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/dashboards/img/prometheus_dashboard_yaml_validation_v13_1.png b/doc/operations/metrics/dashboards/img/prometheus_dashboard_yaml_validation_v13_1.png
deleted file mode 100644
index 08d7d6603d2..00000000000
--- a/doc/operations/metrics/dashboards/img/prometheus_dashboard_yaml_validation_v13_1.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/dashboards/img/related_links_v13_1.png b/doc/operations/metrics/dashboards/img/related_links_v13_1.png
deleted file mode 100644
index 4dc141f0e7f..00000000000
--- a/doc/operations/metrics/dashboards/img/related_links_v13_1.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/dashboards/index.md b/doc/operations/metrics/dashboards/index.md
index b2fc7397d17..a4cf12cc64a 100644
--- a/doc/operations/metrics/dashboards/index.md
+++ b/doc/operations/metrics/dashboards/index.md
@@ -2,267 +2,11 @@
stage: Monitor
group: Respond
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
+remove_date: '2023-08-22'
+redirect_to: '../../index.md'
---
-# Custom dashboards (deprecated) **(FREE)**
+# Custom dashboards (removed) **(FREE)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/59974) in GitLab 12.1.
-> - [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7.
-
-WARNING:
-This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541)
-in GitLab 14.7, and is planned for removal in GitLab 16.0.
-
-By default, all projects include a [GitLab-defined Prometheus dashboard](default.md), which
-includes a few key metrics, but you can also define your own custom dashboards.
-
-You may create a [new dashboard from scratch](#add-a-new-dashboard-to-your-project)
-or [duplicate a GitLab-defined Prometheus dashboard](#duplicate-a-gitlab-defined-dashboard).
-
-## Add a new dashboard to your project
-
-> UI option [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/228856) in GitLab 13.3.
-
-You can configure a custom dashboard by adding a new YAML file into your project's
-`.gitlab/dashboards/` directory. For the dashboard to display on your project's
-**Monitor > Metrics** page, the files must have a `.yml`
-extension and be present in your project's **default** branch.
-
-To create a new dashboard from the GitLab user interface:
-
-1. Sign in to GitLab as a user with Maintainer or Owner
- [permissions](../../../user/permissions.md#project-members-permissions).
-1. Navigate to your dashboard at **Monitor > Metrics**.
-1. In the upper-right corner of your dashboard, select the **{ellipsis_v}** **More actions** menu,
- and select **Create new**:
- ![Monitoring Dashboard actions menu with create new item](img/actions_menu_create_new_dashboard_v13_3.png)
-1. In the modal window, select **Open Repository**, then follow the instructions
- for creating a new dashboard from the command line.
-
-To create a new dashboard from the command line:
-
-1. Create `.gitlab/dashboards/prom_alerts.yml` under your repository's root
- directory. Each YAML file should define the layout of the dashboard and the
- Prometheus queries used to populate data. This example dashboard displays a
- single area chart:
-
- ```yaml
- dashboard: 'Dashboard Title'
- panel_groups:
- - group: 'Group Title'
- panels:
- - type: area-chart
- title: 'Chart Title'
- y_label: 'Y-Axis'
- y_axis:
- format: number
- precision: 0
- metrics:
- - id: my_metric_id
- query_range: 'http_requests_total'
- label: 'Instance: {{instance}}, method: {{method}}'
- unit: 'count'
- ```
-
-1. Save the file, commit, and push to your repository. The file must be present in your **default** branch.
-1. Navigate to your project's **Monitor > Metrics** and choose the custom
- dashboard from the dropdown list.
-
-Your custom dashboard is available at `https://example.com/project/-/metrics/custom_dashboard_name.yml`.
-
-NOTE:
-Configuration files nested under subdirectories of `.gitlab/dashboards` aren't
-supported or available in the UI.
-
-## Add a new metrics panel to a dashboard
-
-> UI option [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/228761) in GitLab 13.3.
-
-The metrics dashboard supports various [multiple panel types](../../../operations/metrics/dashboards/panel_types.md).
-You can quickly test how a panel configuration would display in your metrics dashboard
-with the **Add Panel** page:
-
-1. Sign in to GitLab as a user with Maintainer or Owner
- [permissions](../../../user/permissions.md#project-members-permissions).
-1. Select **Add panel** in the **{ellipsis_v}** **More actions** menu.
-
- NOTE:
- You can only add panels to custom dashboards.
-
- ![Monitoring Dashboard actions menu with add panel item](img/actions_menu_create_add_panel_v13_3.png)
-1. In the **Define and preview panel** section, paste in the YAML you want to
- preview in the **Panel YAML** field.
-1. Select **Preview panel**, and GitLab displays a preview of the chart below the
- `Define and preview panel` section:
- ![Monitoring Dashboard Add Panel page](img/metrics_dashboard_panel_preview_v13_3.png)
-
-## Duplicate a GitLab-defined dashboard
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/37238) in GitLab 12.7.
-> - [GitLab versions 12.8 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/39505), custom metrics are also duplicated when you duplicate a dashboard.
-
-You can save a complete copy of a GitLab-defined dashboard along with all custom metrics added to it.
-The resulting `.yml` file can be customized and adapted to your project.
-You can decide to save the dashboard `.yml` file in the project's **default** branch or in a
-new branch. To duplicate a GitLab-defined dashboard:
-
-1. Select **Duplicate current dashboard** in the **{ellipsis_v}** **More actions** menu.
-1. Enter the filename and other information, such as the new commit's message, and select **Duplicate**.
-1. Select a branch to add your dashboard to:
- - *If you select your **default** branch,* the new dashboard becomes immediately available.
- - *If you select another branch,* this branch should be merged to your **default** branch first.
-
-Your custom dashboard is available at `https://example.com/project/-/metrics/custom_dashboard_name.yml`.
-
-## Manage the metrics dashboard settings
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/223204) in GitLab 13.2.
-
-Users with project Maintainer or Administrator
-[permissions](../../../user/permissions.md#project-members-permissions)
-can manage [the settings](settings.md) for your metrics dashboard.
-
-## Chart Context Menu
-
-To take action related to a chart's data:
-
-- In the upper-right corner of the chart, select **More actions** (**{ellipsis_v}**).
-
-![Context Menu](img/panel_context_menu_v14_0.png)
-
-The options are:
-
-- **Expand panel** - Displays a larger version of a visualization. To return to
- the dashboard, select the **Back** button in your browser, or press the <kbd>Escape</kbd> key.
- ([Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3100) in GitLab 13.0.)
-- **Download CSV** - Data from Prometheus charts on the metrics dashboard can be downloaded as CSV.
-- [Copy link to chart](../embed.md#embedding-gitlab-managed-kubernetes-metrics)
-
-### Timeline zoom and URL sharing
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/198910) in GitLab 12.8.
-
-You can use the **Timeline zoom** function at the bottom of a chart to zoom in
-on a date and time of your choice. When you select and drag the sliders to select
-a different beginning or end date of data to display, GitLab adds your selected start
-and end times to the URL, enabling you to share specific time frames more easily.
-
-## Dashboard Annotations
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/211330) in GitLab 12.10 (enabled by feature flag `metrics_dashboard_annotations`).
-> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/215224) in GitLab 13.0.
-
-You can use **Metrics Dashboard Annotations** to mark any important events on
-every metrics dashboard by adding annotations to it. While viewing a dashboard,
-annotation entries assigned to the selected time range are automatically
-fetched and displayed on every chart within that dashboard. On mouse hover, each
-annotation presents additional details, including the exact time of an event and
-its description.
-
-You can create annotations by making requests to the
-[Metrics dashboard annotations API](../../../api/metrics_dashboard_annotations.md)
-
-![Annotations UI](img/metrics_dashboard_annotations_ui_v13.0.png)
-
-### Annotation retention policy
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/211433) in GitLab 13.01.
-
-To avoid excessive storage space consumption by stale annotations, records attached
-to time periods older than two weeks are removed daily. This recurring background
-job runs at 1:00 a.m. local server time.
-
-## Add related links to custom dashboards
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/216385) in GitLab 13.1.
-
-You can embed links to other dashboards or external services in your custom
-dashboard by adding **Related links** to your dashboard's YAML file. Related links
-open in the same tab as the dashboard. Related links can be displayed in the
-following locations on your dashboard:
-
-- At the top of your dashboard as the top level [`links` dashboard property](../../../operations/metrics/dashboards/yaml.md#dashboard-top-level-properties).
-- In charts context menus as the [`links` property of a panel](../../../operations/metrics/dashboards/yaml.md#panel-panels-properties).
-
-Related links can contain the following attributes:
-
-- `url`: The full URL to the link. Required.
-- `title`: A phrase describing the link. Optional. If this attribute is not set,
- the full URL is used for the link title.
-- `type`: A string declaring the type of link. Optional. If set to `grafana`, the
- dashboard's time range values are converted to the Grafana time range format and
- appended to the `url`.
-
-The dashboard's time range is appended to the `url` as URL parameters.
-
-The following example shows two related links (`GitLab.com` and `GitLab Documentation`)
-added to a dashboard:
-
-![Links UI](img/related_links_v13_1.png)
-
-### Links Syntax
-
-```yaml
-links:
- - title: GitLab.com
- url: https://gitlab.com
- - title: GitLab Documentation
- url: https://docs.gitlab.com
- - title: Public Grafana playground dashboard
- url: https://play.grafana.org/d/000000012/grafana-play-home?orgId=1
- type: grafana
-```
-
-## Troubleshooting
-
-### Accessing the UI of Prometheus in Kubernetes
-
-When troubleshooting issues with an in-cluster Prometheus, it can help to
-view the Prometheus UI. In the example below, we assume the Prometheus
-server to be the pod `prometheus-prometheus-server` in the `gitlab-managed-apps`
-namespace:
-
-1. Find the name of the Prometheus pod in the user interface of your Kubernetes
- provider, such as GKE, or by running the following `kubectl` command in your
- terminal. For example:
-
- ```shell
- kubectl get pods -n gitlab-managed-apps | grep 'prometheus-prometheus-server'
- ```
-
- The command should return a result like the following example, where
- `prometheus-prometheus-server-55b4bd64c9-dpc6b` is the name of the Prometheus pod:
-
- ```plaintext
- gitlab-managed-apps prometheus-prometheus-server-55b4bd64c9-dpc6b 2/2 Running 0 71d
- ```
-
-1. Run a `kubectl port-forward` command. In the following example, `9090` is the
- Prometheus server's listening port:
-
- ```shell
- kubectl port-forward prometheus-prometheus-server-55b4bd64c9-dpc6b 9090:9090 -n gitlab-managed-apps
- ```
-
- The `port-forward` command forwards all requests sent to your system's `9090` port
- to the `9090` port of the Prometheus pod. If the `9090` port on your system is used
- by another application, you can change the port number before the colon to your
- desired port. For example, to forward port `8080` of your local system, change the
- command to:
-
- ```shell
- kubectl port-forward prometheus-prometheus-server-55b4bd64c9-dpc6b 8080:9090 -n gitlab-managed-apps
- ```
-
-1. Open `localhost:9090` in your browser to display the Prometheus user interface.
-
-### "No data found" error on Metrics dashboard page
-
-If the "No data found" screen continues to appear, it could be due to:
-
-- No successful deployments have occurred to this environment.
-- Prometheus does not have performance data for this environment, or the metrics
- are not labeled correctly. To test this, connect to the Prometheus server and
- [run a query](../../../user/project/integrations/prometheus_library/kubernetes.md#metrics-supported), replacing `$CI_ENVIRONMENT_SLUG`
- with the name of your environment.
-- You may need to re-add the GitLab predefined common metrics. This can be done by running the [import common metrics Rake task](../../../administration/raketasks/maintenance.md#import-common-metrics).
+This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7
+and [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/399231) in 16.0.
diff --git a/doc/operations/metrics/dashboards/panel_types.md b/doc/operations/metrics/dashboards/panel_types.md
index 0ab78dc0228..c789e99052c 100644
--- a/doc/operations/metrics/dashboards/panel_types.md
+++ b/doc/operations/metrics/dashboards/panel_types.md
@@ -2,316 +2,11 @@
stage: Monitor
group: Respond
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
+remove_date: '2023-08-22'
+redirect_to: '../../index.md'
---
-# Panel types for dashboards (deprecated) **(FREE)**
+# Panel types for dashboards (removed) **(FREE)**
-> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7.
-
-WARNING:
-This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541)
-in GitLab 14.7, and is planned for removal in GitLab 16.0.
-
-The below panel types are supported in monitoring dashboards.
-
-## Area or Line Chart
-
-To add an area chart panel type to a dashboard, look at the following sample dashboard file:
-
-```yaml
-dashboard: 'Dashboard Title'
-panel_groups:
- - group: 'Group Title'
- panels:
- - type: area-chart # or line-chart
- title: 'Area Chart Title'
- y_label: 'Y-Axis'
- y_axis:
- format: number
- precision: 0
- metrics:
- - id: area_http_requests_total
- query_range: 'http_requests_total'
- label: 'Instance: {{instance}}, Method: {{method}}'
- unit: "count"
-```
-
-Note the following properties:
-
-| Property | Type | Required | Description |
-| ------ | ------ | ------ | ------ |
-| `type` | string | no | Type of panel to be rendered. Optional for area panel types |
-| `query_range` | string | required | For area panel types, you must use a [range query](https://prometheus.io/docs/prometheus/latest/querying/api/#range-queries) |
-
-![area panel chart](img/prometheus_dashboard_area_panel_type_v12_8.png)
-
-Starting in [version 12.8](https://gitlab.com/gitlab-org/gitlab/-/issues/202696), the y-axis values scale according to the data. Previously, it always started from 0.
-
-## Anomaly chart
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/16530) in GitLab 12.5.
-
-To add an anomaly chart panel type to a dashboard, add a panel with *exactly* 3 metrics.
-
-The first metric represents the current state, and the second and third metrics represent the upper and lower limit:
-
-```yaml
-dashboard: 'Dashboard Title'
-panel_groups:
- - group: 'Group Title'
- panels:
- - type: anomaly-chart
- title: 'Chart Title'
- y_label: "Y-Axis"
- metrics:
- - id: anomaly_requests_normal
- query_range: 'http_requests_total'
- label: '# of Requests'
- unit: 'count'
- - id: anomaly_requests_upper_limit
- query_range: 10000
- label: 'Max # of requests'
- unit: 'count'
- - id: anomaly_requests_lower_limit
- query_range: 2000
- label: 'Min # of requests'
- unit: 'count'
-```
-
-Note the following properties:
-
-| Property | Type | Required | Description |
-| ------ | ------ | ------ | ------ |
-| `type` | string | required | Must be `anomaly-chart` for anomaly panel types |
-| `query_range` | yes | required | For anomaly panel types, you must use a [range query](https://prometheus.io/docs/prometheus/latest/querying/api/#range-queries) in every metric. |
-
-![anomaly panel type](img/prometheus_dashboard_anomaly_panel_type.png)
-
-## Bar chart
-
-To add a bar chart to a dashboard, look at the following sample dashboard file:
-
-```yaml
-dashboard: 'Dashboard Title'
-panel_groups:
- - group: 'Group title'
- panels:
- - type: bar
- title: 'HTTP Handlers'
- x_label: 'Response Size'
- y_axis:
- name: 'Handlers'
- metrics:
- - id: prometheus_http_response_size_bytes_bucket
- query_range: 'sum(increase(prometheus_http_response_size_bytes_bucket[1d])) by (handler)'
- unit: 'Bytes'
-```
-
-Note the following properties:
-
-| Property | Type | Required | Description |
-| ------ | ------ | ------ | ------ |
-| `type` | string | yes | Type of panel to be rendered. For bar chart types, set to `bar` |
-| `query_range` | yes | yes | For bar chart, you must use a [range query](https://prometheus.io/docs/prometheus/latest/querying/api/#range-queries)
-
-![bar chart panel type](img/prometheus_dashboard_bar_chart_panel_type_v12.10.png)
-
-## Column chart
-
-To add a column panel type to a dashboard, look at the following sample dashboard file:
-
-```yaml
-dashboard: 'Dashboard Title'
-panel_groups:
- - group: 'Group title'
- panels:
- - title: 'Column'
- type: 'column'
- metrics:
- - id: 1024_memory
- query: 'avg(sum(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-([^c].*|c([^a]|a([^n]|n([^a]|a([^r]|r[^y])))).*|)-(.*)",namespace="%{kube_namespace}"}) by (job)) without (job) / count(avg(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-([^c].*|c([^a]|a([^n]|n([^a]|a([^r]|r[^y])))).*|)-(.*)",namespace="%{kube_namespace}"}) without (job)) /1024/1024'
- unit: MB
- label: 'Memory Usage'
-```
-
-Note the following properties:
-
-| Property | Type | Required | Description |
-| ------ | ------ | ------ | ------ |
-| `type` | string | yes | Type of panel to be rendered. For column panel types, set to `column` |
-| `query_range` | yes | yes | For column panel types, you must use a [range query](https://prometheus.io/docs/prometheus/latest/querying/api/#range-queries) |
-
-![anomaly panel type](img/prometheus_dashboard_column_panel_type.png)
-
-## Stacked column
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30583) in GitLab 12.8.
-
-To add a stacked column panel type to a dashboard, look at the following sample dashboard file:
-
-```yaml
-dashboard: 'Dashboard title'
-priority: 1
-panel_groups:
- - group: 'Group Title'
- priority: 5
- panels:
- - type: 'stacked-column'
- title: 'Stacked column'
- y_label: 'y label'
- x_label: 'x label'
- metrics:
- - id: memory_1
- query_range: 'memory_query'
- label: 'memory query 1'
- unit: 'count'
- series_name: 'group 1'
- - id: memory_2
- query_range: 'memory_query_2'
- label: 'memory query 2'
- unit: 'count'
- series_name: 'group 2'
-```
-
-![stacked column panel type](img/prometheus_dashboard_stacked_column_panel_type_v12_8.png)
-
-| Property | Type | Required | Description |
-| ------ | ------ | ------ | ------ |
-| `type` | string | yes | Type of panel to be rendered. For stacked column panel types, set to `stacked-column` |
-| `query_range` | yes | yes | For stacked column panel types, you must use a [range query](https://prometheus.io/docs/prometheus/latest/querying/api/#range-queries) |
-
-## Single Stat
-
-To add a single stat panel type to a dashboard, look at the following sample dashboard file:
-
-```yaml
-dashboard: 'Dashboard Title'
-panel_groups:
- - group: 'Group Title'
- panels:
- - title: 'Single Stat'
- type: 'single-stat'
- metrics:
- - id: 10
- query: 'max(go_memstats_alloc_bytes{job="prometheus"})'
- unit: MB
- label: 'Total'
-```
-
-Note the following properties:
-
-| Property | Type | Required | Description |
-| ------- | ------ | ------ | ------ |
-| `type` | string | yes | Type of panel to be rendered. For single stat panel types, set to `single-stat` |
-| `field` | string | no | Panels display the value of a metric. For a panel to display the value of a label instead, put the name of the label in this key. |
-| `query` | string | yes | For single stat panel types, you must use an [instant query](https://prometheus.io/docs/prometheus/latest/querying/api/#instant-queries). |
-
-![single stat panel type](img/prometheus_dashboard_single_stat_panel_type.png)
-
-## Percentile based results
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/201946) in GitLab 12.8.
-
-Query results sometimes need to be represented as a percentage value out of 100. You can use the `max_value` property at the root of the panel definition:
-
-```yaml
-dashboard: 'Dashboard Title'
-panel_groups:
- - group: 'Group Title'
- panels:
- - title: 'Single Stat'
- type: 'single-stat'
- max_value: 100
- metrics:
- - id: 10
- query: 'max(go_memstats_alloc_bytes{job="prometheus"})'
- unit: '%'
- label: 'Total'
-```
-
-For example, if you have a query value of `53.6`, adding `%` as the unit results in a single stat value of `53.6%`, but if the maximum expected value of the query is `120`, the value would be `44.6%`. Adding the `max_value` causes the correct percentage value to display.
-
-## Gauge
-
-WARNING:
-This panel type is an [Experiment](../../../policy/alpha-beta-support.md#experiment) and is subject to change at any time
-without prior notice!
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/207044) in GitLab 13.3.
-
-To add a gauge panel type to a dashboard, look at the following sample dashboard file:
-
-```yaml
-dashboard: 'Dashboard Title'
-panel_groups:
- - group: 'Group Title'
- panels:
- - title: 'Gauge'
- type: 'gauge'
- min_value: 0
- max_value: 1000
- split: 5
- thresholds:
- values: [60, 90]
- mode: 'percentage'
- format: 'kilobytes'
- metrics:
- - id: 10
- query: 'floor(max(prometheus_http_response_size_bytes_bucket)/1000)'
- unit: 'kb'
-```
-
-Note the following properties:
-
-| Property | Type | Required | Description |
-| ------------ | ------ | ------ | ------ |
-| `type` | string | yes | Type of panel to be rendered. For gauge panel types, set to `gauge`. |
-| `min_value` | number | no, defaults to `0` | The minimum value of the gauge chart axis. If either of `min_value` or `max_value` are not set, they both get their default values. |
-| `max_value` | number | no, defaults to `100` | The maximum value of the gauge chart axis. If either of `min_value` or `max_value` are not set, they both get their default values. |
-| `split` | number | no, defaults to `10` | The amount of split segments on the gauge chart axis. |
-| `thresholds` | object | no | Thresholds configuration for the gauge chart axis. |
-| `format` | string | no, defaults to `engineering` | Unit format used. See the [full list of units](yaml_number_format.md). |
-| `query` | string | yes | For gauge panel types, you must use an [instant query](https://prometheus.io/docs/prometheus/latest/querying/api/#instant-queries). |
-
-### Thresholds properties
-
-| Property | Type | Required | Description |
-| ------ | ------ | ------ | ------ |
-| values | array | no, defaults to 95% of the range between `min_value` and `max_value`| An array of gauge chart axis threshold values. |
-| mode | string | no, defaults to `absolute` | The mode in which the thresholds are interpreted in relation to `min_value` and `max_value`. Can be either `percentage` or `absolute`. |
-
-![gauge panel type](img/prometheus_dashboard_gauge_panel_type_v13_3.png)
-
-## Heatmaps
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30581) in GitLab 12.5.
-
-To add a heatmap panel type to a dashboard, look at the following sample dashboard file:
-
-```yaml
-dashboard: 'Dashboard Title'
-panel_groups:
- - group: 'Group Title'
- panels:
- - title: 'Heatmap'
- type: 'heatmap'
- metrics:
- - id: 10
- query: 'sum(rate(nginx_upstream_responses_total{upstream=~"%{kube_namespace}-%{ci_environment_slug}-.*"}[60m])) by (status_code)'
- unit: req/sec
- label: 'Status code'
-```
-
-Note the following properties:
-
-| Property | Type | Required | Description |
-| ------ | ------ | ------ | ------ |
-| `type` | string | yes | Type of panel to be rendered. For heatmap panel types, set to `heatmap` |
-| `query_range` | yes | yes | For area panel types, you must use a [range query](https://prometheus.io/docs/prometheus/latest/querying/api/#range-queries) |
-
-![heatmap panel type](img/heatmap_panel_type.png)
-
-WARNING:
-When a query returns too many data points, the heatmap data bucket dimensions tend downwards to 0, making the chart's data invisible, as shown in the image below. To fix this problem, limit the amount of data returned by changing the time range filter on the metrics dashboard UI, or adding the **step** property to your dashboard's YAML file.
-
-![heatmap chart with too much data](img/heatmap_chart_too_much_data_v_13_2.png)
+This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7
+and [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/399231) in 16.0.
diff --git a/doc/operations/metrics/dashboards/settings.md b/doc/operations/metrics/dashboards/settings.md
index 6ddedd98fcb..5572dfa360f 100644
--- a/doc/operations/metrics/dashboards/settings.md
+++ b/doc/operations/metrics/dashboards/settings.md
@@ -2,57 +2,11 @@
stage: Monitor
group: Respond
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
+remove_date: '2023-08-22'
+redirect_to: '../../index.md'
---
-# Dashboard settings (deprecated) **(FREE)**
+# Dashboard settings (removed) **(FREE)**
-> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7.
-
-WARNING:
-This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541)
-in GitLab 14.7, and is planned for removal in GitLab 16.0.
-
-You can configure your [Monitoring dashboard](../index.md) to
-display the time zone of your choice, and the links of your choice.
-
-To configure these settings you must have Manage Project
-Operations [permissions](../../../user/permissions.md).
-
-## Change the dashboard time zone
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/214370) in GitLab 13.1.
-
-By default, your monitoring dashboard displays dates and times in your local
-time zone, but you can display dates and times in UTC format. To change the
-time zone:
-
-1. Sign in as a user with Manage Project Operations [permissions](../../../user/permissions.md).
-1. Navigate to **Settings > Monitor**.
-1. Scroll to **Metrics Dashboard** and select **Expand**.
-1. In the **Dashboard timezone** select box, select *User's local timezone*
- or *UTC*:
-
- ![Dashboard timezone setting](img/dashboard_local_timezone_v13_1.png)
-1. Select **Save changes**.
-
-## Link to an external dashboard
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/57171) in GitLab 12.0.
-
-You can add a button on your monitoring dashboard that links directly to your
-existing external dashboards:
-
-1. Sign in as a user with Manage Project Operations [permissions](../../../user/permissions.md).
-1. Navigate to **Settings > Monitor**.
-1. Scroll to **Metrics Dashboard** and select **Expand**.
-1. In **External dashboard URL**, provide the URL to your external dashboard:
-
- ![External Dashboard Setting](img/dashboard_external_link_v13_1.png)
-
-1. Select **Save changes**.
-
-GitLab displays a **View full dashboard** button in the upper-right corner of your
-[monitoring dashboard](../../../ci/environments/index.md#monitor-environments)
-which opens the URL you provided:
-
-![External Dashboard Link](img/external_dashboard_link.png)
+This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7
+and [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/399231) in 16.0.
diff --git a/doc/operations/metrics/dashboards/templating_variables.md b/doc/operations/metrics/dashboards/templating_variables.md
index 7af4b9a9e43..a93c559c98c 100644
--- a/doc/operations/metrics/dashboards/templating_variables.md
+++ b/doc/operations/metrics/dashboards/templating_variables.md
@@ -2,132 +2,11 @@
stage: Monitor
group: Respond
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
+remove_date: '2023-08-22'
+redirect_to: '../../index.md'
---
-# Templating variables for metrics dashboards (deprecated) **(FREE)**
+# Templating variables for metrics dashboards (removed) **(FREE)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/214539) in GitLab 13.0.
-> - [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7.
-
-WARNING:
-This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541)
-in GitLab 14.7, and is planned for removal in GitLab 16.0.
-
-Templating variables can be used to make your metrics dashboard more versatile.
-
-`templating` is a top-level key in the
-[dashboard YAML](yaml.md#dashboard-top-level-properties).
-Define your variables in the `variables` key, under `templating`. The value of
-the `variables` key should be a hash, and each key under `variables`
-defines a templating variable on the dashboard, and may contain alphanumeric and underscore characters.
-
-A variable can be used in a Prometheus query in the same dashboard using the syntax
-described [in Using Variables](variables.md).
-
-## `text` variable type
-
-WARNING:
-This variable type is an [Experiment](../../../policy/alpha-beta-support.md#experiment), and is subject to change at any time
-without prior notice!
-
-For each `text` variable defined in the dashboard YAML, a free text field displays
-on the dashboard UI, allowing you to enter a value for each variable.
-
-The `text` variable type supports a simple and a full syntax.
-
-### Simple syntax
-
-This example creates a variable called `variable1`, with a default value
-of `default value`:
-
-```yaml
-templating:
- variables:
- variable1: 'default value' # `text` type variable with `default value` as its default.
-```
-
-### Full syntax
-
-This example creates a variable called `variable1`, with a default value of `default`.
-The label for the text box on the UI is the value of the `label` key:
-
-```yaml
-templating:
- variables:
- variable1: # The variable name that can be used in queries.
- label: 'Variable 1' # (Optional) label that will appear in the UI for this text box.
- type: text
- options:
- default_value: 'default' # (Optional) default value.
-```
-
-## `custom` variable type
-
-WARNING:
-This variable type is an [Experiment](../../../policy/alpha-beta-support.md#experiment), and is subject to change at any time
-without prior notice!
-
-Each `custom` variable defined in the dashboard YAML creates a dropdown list
-selector on the dashboard UI, allowing you to select a value for each variable.
-
-The `custom` variable type supports a simple and a full syntax.
-
-### Simple syntax
-
-This example creates a variable called `variable1`, with a default value of `value1`.
-The dashboard UI displays a dropdown list with `value1`, `value2` and `value3`
-as the choices.
-
-```yaml
-templating:
- variables:
- variable1: ['value1', 'value2', 'value3']
-```
-
-### Full syntax
-
-This example creates a variable called `variable1`, with a default value of `value_option_2`.
-The label for the text box on the UI is the value of the `label` key.
-The dashboard UI displays a dropdown list with `Option 1` and `Option 2`
-as the choices.
-
-If you select `Option 1` from the dropdown list, the variable is replaced with `value option 1`.
-Similarly, if you select `Option 2`, the variable is replaced with `value_option_2`:
-
-```yaml
-templating:
- variables:
- variable1: # The variable name that can be used in queries.
- label: 'Variable 1' # (Optional) label that will appear in the UI for this dropdown.
- type: custom
- options:
- values:
- - value: 'value option 1' # The value that will replace the variable in queries.
- text: 'Option 1' # (Optional) Text that will appear in the UI dropdown.
- - value: 'value_option_2'
- text: 'Option 2'
- default: true # (Optional) This option should be the default value of this variable.
-```
-
-## `metric_label_values` variable type
-
-WARNING:
-This variable type is an [Experiment](../../../policy/alpha-beta-support.md#experiment), and is subject to change at any time
-without prior notice!
-
-### Full syntax
-
-This example creates a variable called `variable2`. The values of the dropdown list are
-all the different values of the `backend` label in the Prometheus series described by
-`up{env="production"}`.
-
-```yaml
-templating:
- variables:
- variable2: # The variable name that can be interpolated in queries.
- label: 'Variable 2' # (Optional) label that will appear in the UI for this dropdown.
- type: metric_label_values
- options:
- series_selector: 'up{env="production"}'
- label: 'backend'
-```
+This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7
+and [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/399231) in 16.0.
diff --git a/doc/operations/metrics/dashboards/variables.md b/doc/operations/metrics/dashboards/variables.md
index 152f7522c4e..45e13aa731a 100644
--- a/doc/operations/metrics/dashboards/variables.md
+++ b/doc/operations/metrics/dashboards/variables.md
@@ -2,77 +2,11 @@
stage: Monitor
group: Respond
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
+remove_date: '2023-08-22'
+redirect_to: '../../index.md'
---
-# Using variables (deprecated) **(FREE)**
+# Using variables (removed) **(FREE)**
-> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7.
-
-WARNING:
-This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541)
-in GitLab 14.7, and is planned for removal in GitLab 16.0.
-
-## Query variables
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20793) in GitLab 12.7.
-
-Variables can be specified using double curly braces, such as `"{{ci_environment_slug}}"`.
-
-Support for the `"%{ci_environment_slug}"` format was
-[removed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31581) in GitLab 13.0.
-Queries that continue to use the old format display no data.
-
-## Predefined variables
-
-GitLab supports a limited set of [CI/CD variables](../../../ci/variables/index.md)
-in the Prometheus query. This is particularly useful for identifying a specific
-environment, for example with `ci_environment_slug`. Variables for Prometheus queries
-must be lowercase. The supported variables are:
-
-- `environment_filter`
-- `ci_environment_slug`
-- `kube_namespace`
-- `ci_project_name`
-- `ci_project_namespace`
-- `ci_project_path`
-- `ci_environment_name`
-- `__range`
-
-### `environment_filter`
-
-`environment_filter` is automatically expanded to `container_name!="POD",environment="ENVIRONMENT_NAME"`
-where `ENVIRONMENT_NAME` is the name of the current environment.
-
-For example, a Prometheus query like `container_memory_usage_bytes{ {{environment_filter}} }`
-becomes `container_memory_usage_bytes{ container_name!="POD",environment="production" }`.
-
-### `__range`
-
-The `__range` variable is useful in Prometheus
-[range vector selectors](https://prometheus.io/docs/prometheus/latest/querying/basics/#range-vector-selectors).
-Its value is the total number of seconds in the dashboard's time range.
-For example, if the dashboard time range is set to 8 hours, the value of
-`__range` is `28800s`.
-
-## User-defined variables
-
-[Variables can be defined](../../../operations/metrics/dashboards/yaml.md#templating-templating-properties) in a custom dashboard YAML file.
-
-Variable names are case-sensitive.
-
-## Query variables from URL
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/214500) in GitLab 13.0.
-
-GitLab supports setting custom variables through URL parameters. Surround the variable
-name with double curly braces (`{{example}}`) to interpolate the variable in a query:
-
-```plaintext
-avg(sum(container_memory_usage_bytes{container_name!="{{pod}}"}) by (job)) without (job) /1024/1024/1024'
-```
-
-The URL for this query would be:
-
-```plaintext
-https://gitlab.com/<user>/<project>/-/environments/<environment_id>/metrics?dashboard=.gitlab%2Fdashboards%2Fcustom.yml&pod=POD
-```
+This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7
+and [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/399231) in 16.0.
diff --git a/doc/operations/metrics/dashboards/yaml.md b/doc/operations/metrics/dashboards/yaml.md
index e8bba4b6e42..7807f713773 100644
--- a/doc/operations/metrics/dashboards/yaml.md
+++ b/doc/operations/metrics/dashboards/yaml.md
@@ -2,179 +2,11 @@
stage: Monitor
group: Respond
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
+remove_date: '2023-08-22'
+redirect_to: '../../index.md'
---
-# Dashboard YAML properties (deprecated) **(FREE)**
+# Dashboard YAML properties (removed) **(FREE)**
-> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7.
-
-WARNING:
-This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541)
-in GitLab 14.7, and is planned for removal in GitLab 16.0.
-
-Dashboards have several components:
-
-- Templating variables.
-- Panel groups, which consist of panels.
-- Panels, which support one or more metrics.
-
-The following tables outline the details of expected properties.
-
-## Dashboard (top-level) properties
-
-| Property | Type | Required | Description |
-| ------ | ------ | ------ | ------ |
-| `dashboard` | string | yes | Heading for the dashboard. Only one dashboard should be defined per file. |
-| `panel_groups` | array | yes | The panel groups which should be on the dashboard. |
-| `templating` | hash | no | Top level key under which templating related options can be added. |
-| `links` | array | no | Add links to display on the dashboard. |
-
-## Templating (`templating`) properties
-
-| Property | Type | Required | Description |
-| -------- | ---- | -------- | ----------- |
-| `variables` | hash | yes | Variables can be defined here. |
-
-Read the documentation on [templating](templating_variables.md).
-
-## Links (`links`) properties
-
-| Property | Type | Required | Description |
-| -------- | ---- | -------- | ----------- |
-| `url` | string | yes | The address of the link. |
-| `title` | string | no | Display title for the link. |
-| `type` | string | no | Type of the link. Specifies the link type, can be: `grafana` |
-
-Read the documentation on [links](index.md#add-related-links-to-custom-dashboards).
-
-## Panel group (`panel_groups`) properties
-
-Dashboards display panel groups in the order they are listed in the dashboard YAML file.
-
-In GitLab versions 13.3 and below, panel groups were ordered by a `priority` key, which
-is no longer used.
-
-| Property | Type | Required | Description |
-| ------ | ------ | ------ | ------ |
-| `group` | string | required | Heading for the panel group. |
-| `panels` | array | required | The panels which should be in the panel group. |
-
-Panels in a panel group are laid out in rows consisting of two panels per row. An exception to this rule are single panels on a row: these panels take the full width of their containing row.
-
-## Panel (`panels`) properties
-
-Dashboards display panels in the order they are listed in the dashboard YAML file.
-
-In GitLab versions 13.3 and below, panels were ordered by a `weight` key, which
-is no longer used.
-
-| Property | Type | Required | Description |
-| ------ | ------ | ------ | ------- |
-| `type` | string | no, defaults to `area-chart` | Specifies the panel type to use, for example `area-chart`, `line-chart` or `anomaly-chart`. Only types listed among [all panel types](panel_types.md) are allowed. |
-| `title` | string | yes | Heading for the panel. |
-| `y_label` | string | no, but highly encouraged | Y-Axis label for the panel. |
-| `y_axis` | string | no | Y-Axis configuration for the panel. |
-| `max_value` | number | no | Denominator value used for calculating [percentile based results](panel_types.md#percentile-based-results) |
-| `metrics` | array | yes | The metrics which should be displayed in the panel. Any number of metrics can be displayed when `type` is `area-chart` or `line-chart`, whereas only 3 can be displayed when `type` is `anomaly-chart`. |
-| `links` | array | no | Add links to display on the chart's [context menu](index.md#chart-context-menu). |
-
-## Axis (`panels[].y_axis`) properties
-
-| Property | Type | Required | Description |
-| ----------- | ------ | ----------------------------- | -------------------------------------------------------------------- |
-| `name` | string | no, but highly encouraged | Y-Axis label for the panel. Replaces `y_label` if set. |
-| `format` | string | no, defaults to `engineering` | Unit format used. See the [full list of units](yaml_number_format.md). |
-| `precision` | number | no, defaults to `2` | Number of decimal places to display in the number. | |
-
-## Metrics (`metrics`) properties
-
-| Property | Type | Required | Description |
-| ------ | ------ | ------ | ------ |
-| `id` | string | no | Used for associating dashboard metrics with database records. Must be unique across dashboard configuration files. Required for [alerting](../alerts.md) (support not yet enabled, see [relevant issue](https://gitlab.com/gitlab-org/gitlab/-/issues/27980)). |
-| `unit` | string | yes | Defines the unit of the query's return data. |
-| `label` | string | no, but highly encouraged | Defines the legend-label for the query. Should be unique within the panel's metrics. Can contain time series labels as interpolated variables. |
-| `query` | string/number | yes if `query_range` is not defined | Defines the Prometheus query to be used to populate the chart/panel. If defined, the `query` endpoint of the [Prometheus API](https://prometheus.io/docs/prometheus/latest/querying/api/) is used. |
-| `query_range` | string/number | yes if `query` is not defined | Defines the Prometheus query to be used to populate the chart/panel. If defined, the `query_range` endpoint of the [Prometheus API](https://prometheus.io/docs/prometheus/latest/querying/api/) is used. |
-| `step` | number | no, value is calculated if not defined | Defines query resolution step width in float number of seconds. Metrics on the same panel should use the same `step` value. |
-
-## Dynamic labels
-
-Dynamic labels are useful when multiple time series are returned from a Prometheus query.
-
-When a static label is used and a query returns multiple time series, then all the legend items are labeled the same, which makes identifying each time series difficult:
-
-```yaml
-metrics:
- - id: my_metric_id
- query_range: 'http_requests_total'
- label: 'Time Series'
- unit: 'count'
-```
-
-This may render a legend like this:
-
-![repeated legend label chart](img/prometheus_dashboard_repeated_label.png)
-
-For labels to be more explicit, using variables that reflect time series labels is a good practice. The variables are replaced by the values of the time series labels when the legend is rendered:
-
-```yaml
-metrics:
- - id: my_metric_id
- query_range: 'http_requests_total'
- label: 'Instance: {{instance}}, method: {{method}}'
- unit: 'count'
-```
-
-The resulting rendered legend looks like this:
-
-![legend with label variables](img/prometheus_dashboard_label_variables.png)
-
-There is also a shorthand value for dynamic dashboard labels that make use of only one time series label:
-
-```yaml
-metrics:
- - id: my_metric_id
- query_range: 'http_requests_total'
- label: 'Method'
- unit: 'count'
-```
-
-This works by converting the value of `label` to lower-case and, if there are more words separated by spaces, replacing those spaces with an underscore (`_`). The transformed value is then checked against the labels of the time series returned by the Prometheus query. If a time series label is found that is equal to the transformed value, then the label value renders in the legend like this:
-
-![legend with label shorthand variable](img/prometheus_dashboard_label_variable_shorthand.png)
-
-## Dashboard YAML syntax validation
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33202) in GitLab 13.1.
-
-To confirm your dashboard definition contains valid YAML syntax:
-
-1. Go to **Repository > Files**.
-1. Go to your dashboard file in your repository.
-1. Review the information pane about the file, displayed above the file contents.
-
-Files with valid syntax display **Metrics Dashboard YAML definition is valid**,
-and files with invalid syntax display **Metrics Dashboard YAML definition is invalid**.
-
-![Metrics dashboard YAML syntax validation](img/prometheus_dashboard_yaml_validation_v13_1.png)
-
-When **Metrics Dashboard YAML definition is invalid** at least one of the following messages is displayed:
-
-1. `dashboard: can't be blank` [learn more](#dashboard-top-level-properties)
-1. `panel_groups: should be an array of panel_groups objects` [learn more](#dashboard-top-level-properties)
-1. `group: can't be blank` [learn more](#panel-group-panel_groups-properties)
-1. `panels: should be an array of panels objects` [learn more](#panel-group-panel_groups-properties)
-1. `title: can't be blank` [learn more](#panel-panels-properties)
-1. `metrics: should be an array of metrics objects` [learn more](#panel-panels-properties)
-1. `query: can't be blank` [learn more](#metrics-metrics-properties)
-1. `query_range: can't be blank` [learn more](#metrics-metrics-properties)
-1. `unit: can't be blank` [learn more](#metrics-metrics-properties)
-1. `YAML syntax: The parsed YAML is too big`
-
- This is displayed when the YAML file is larger than 1 MB.
-
-1. `YAML syntax: Invalid configuration format`
-
- This is displayed when the YAML file is empty or does not contain valid YAML.
-
-Metrics Dashboard YAML definition validation information is also available as a [GraphQL API field](../../../api/graphql/reference/index.md#metricsdashboard)
+This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7
+and [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/399231) in 16.0.
diff --git a/doc/operations/metrics/dashboards/yaml_number_format.md b/doc/operations/metrics/dashboards/yaml_number_format.md
index 99e6be96a3c..90e7f67b153 100644
--- a/doc/operations/metrics/dashboards/yaml_number_format.md
+++ b/doc/operations/metrics/dashboards/yaml_number_format.md
@@ -2,176 +2,11 @@
stage: Monitor
group: Respond
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
+remove_date: '2023-08-22'
+redirect_to: '../../index.md'
---
-# Unit formats reference **(FREE)**
+# Unit formats reference (removed) **(FREE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/201999) in GitLab 12.9.
-
-Format the data in your dashboard panels.
-
-You can select units to format your charts by adding `format` to your
-[axis configuration](yaml.md).
-
-## Internationalization and localization
-
-Currently, your [internationalization and localization options](https://en.wikipedia.org/wiki/Internationalization_and_localization) for number formatting are dependent on the system you are using (that is, your OS or browser).
-
-## Engineering Notation
-
-For generic or default data, numbers are formatted according to the current locale in [engineering notation](https://en.wikipedia.org/wiki/Engineering_notation).
-
-While an [engineering notation exists for the web](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat), GitLab uses a version based off the [scientific notation](https://en.wikipedia.org/wiki/Scientific_notation). GitLab formatting acts in accordance with SI prefixes. For example, using GitLab notation, `1500.00` becomes `1.5k` instead of `1.5E3`. Keep this distinction in mind when using the engineering notation for your metrics.
-
-Formats: `engineering`
-
-SI prefixes:
-
-| Name | Symbol | Value |
-| ---------- | ------- | -------------------------- |
-| `yotta` | Y | 1000000000000000000000000 |
-| `zetta` | Z | 1000000000000000000000 |
-| `exa` | E | 1000000000000000000 |
-| `peta` | P | 1000000000000000 |
-| `tera` | T | 1000000000000 |
-| `giga` | G | 1000000000 |
-| `mega` | M | 1000000 |
-| `kilo` | k | 1000 |
-| `milli` | m | 0.001 |
-| `micro` | μ | 0.000001 |
-| `nano` | n | 0.000000001 |
-| `pico` | p | 0.000000000001 |
-| `femto` | f | 0.000000000000001 |
-| `atto` | a | 0.000000000000000001 |
-| `zepto` | z | 0.000000000000000000001 |
-| `yocto` | y | 0.000000000000000000000001 |
-
-**Examples:**
-
-| Data | Displayed |
-| --------------------------------- | --------- |
-| `0.000000000000000000000008` | 8y |
-| `0.000000000000000000008` | 8z |
-| `0.000000000000000008` | 8a |
-| `0.000000000000008` | 8f |
-| `0.000000000008` | 8p |
-| `0.000000008` | 8n |
-| `0.000008` | 8μ |
-| `0.008` | 8m |
-| `10` | 10 |
-| `1080` | 1.08k |
-| `18000` | 18k |
-| `18888` | 18.9k |
-| `188888` | 189k |
-| `18888888` | 18.9M |
-| `1888888888` | 1.89G |
-| `1888888888888` | 1.89T |
-| `1888888888888888` | 1.89P |
-| `1888888888888888888` | 1.89E |
-| `1888888888888888888888` | 1.89Z |
-| `1888888888888888888888888` | 1.89Y |
-| `1888888888888888888888888888` | 1.89e+27 |
-
-## Numbers
-
-For number data, numbers are formatted according to the current locale.
-
-Formats: `number`
-
-**Examples:**
-
-| Data | Displayed |
-| ---------- | --------- |
-| `10` | 1 |
-| `1000` | 1,000 |
-| `1000000` | 1,000,000 |
-
-## Percentage
-
-For percentage data, format numbers in the chart with a `%` symbol.
-
-Formats supported: `percent`, `percentHundred`
-
-**Examples:**
-
-| Format | Data | Displayed |
-| ---------------- | ----- | --------- |
-| `percent` | `0.5` | 50% |
-| `percent` | `1` | 100% |
-| `percent` | `2` | 200% |
-| `percentHundred` | `50` | 50% |
-| `percentHundred` | `100` | 100% |
-| `percentHundred` | `200` | 200% |
-
-## Duration
-
-For time durations, format numbers in the chart with a time unit symbol.
-
-Formats supported: `milliseconds`, `seconds`
-
-**Examples:**
-
-| Format | Data | Displayed |
-| -------------- | ------ | --------- |
-| `milliseconds` | `10` | 10 ms |
-| `milliseconds` | `500` | 100 ms |
-| `milliseconds` | `1000` | 1000 ms |
-| `seconds` | `10` | 10 s |
-| `seconds` | `500` | 500 s |
-| `seconds` | `1000` | 1000 s |
-
-## Digital (Metric)
-
-Converts a number of bytes using metric prefixes. It scales to
-use the unit that's the best fit.
-
-Formats supported:
-
-- `decimalBytes`
-- `kilobytes`
-- `megabytes`
-- `gigabytes`
-- `terabytes`
-- `petabytes`
-
-**Examples:**
-
-| Format | Data | Displayed |
-| -------------- | --------- | --------- |
-| `decimalBytes` | `1` | 1 B |
-| `decimalBytes` | `1000` | 1 kB |
-| `decimalBytes` | `1000000` | 1 MB |
-| `kilobytes` | `1` | 1 kB |
-| `kilobytes` | `1000` | 1 MB |
-| `kilobytes` | `1000000` | 1 GB |
-| `megabytes` | `1` | 1 MB |
-| `megabytes` | `1000` | 1 GB |
-| `megabytes` | `1000000` | 1 TB |
-
-## Digital (IEC)
-
-Converts a number of bytes using binary prefixes. It scales to
-use the unit that's the best fit.
-
-Formats supported:
-
-- `bytes`
-- `kibibytes`
-- `mebibytes`
-- `gibibytes`
-- `tebibytes`
-- `pebibytes`
-
-**Examples:**
-
-| Format | Data | Displayed |
-| ----------- | ------------- | --------- |
-| `bytes` | `1` | 1 B |
-| `bytes` | `1024` | 1 KiB |
-| `bytes` | `1024 * 1024` | 1 MiB |
-| `kibibytes` | `1` | 1 KiB |
-| `kibibytes` | `1024` | 1 MiB |
-| `kibibytes` | `1024 * 1024` | 1 GiB |
-| `mebibytes` | `1` | 1 MiB |
-| `mebibytes` | `1024` | 1 GiB |
-| `mebibytes` | `1024 * 1024` | 1 TiB |
+This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7
+and [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/399231) in 16.0.
diff --git a/doc/operations/metrics/embed.md b/doc/operations/metrics/embed.md
index 987f1dc019d..00c145adee3 100644
--- a/doc/operations/metrics/embed.md
+++ b/doc/operations/metrics/embed.md
@@ -2,125 +2,11 @@
stage: Monitor
group: Respond
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
+remove_date: '2023-08-22'
+redirect_to: '../index.md'
---
-# Embedding metric charts within GitLab Flavored Markdown **(FREE)**
+# Embedding metric charts within GitLab Flavored Markdown (removed) **(FREE)**
-> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7.
-
-WARNING:
-This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541)
-for use in GitLab 14.7, and is planned for removal in GitLab 16.0.
-
-You can display metrics charts within
-[GitLab Flavored Markdown (GLFM)](../../user/markdown.md)
-fields such as issue or merge request descriptions. The maximum number of embedded
-charts allowed in a GitLab Flavored Markdown field is 100.
-Embedding charts is useful when sharing an application incident or performance
-metrics to others, and you want to have relevant information directly available.
-
-## Embedding GitLab-managed Kubernetes metrics
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/29691) in GitLab 12.2.
-
-This feature requires [Kubernetes](../../user/project/integrations/prometheus_library/kubernetes.md) metrics.
-
-NOTE:
-In GitLab versions 13.3 and earlier, metrics dashboard links were in the form
-`https://<root_url>/<project>/-/environments/<environment_id>/metrics`. These links
-are still supported, and can be used to embed metric charts.
-
-To display metric charts, include a link of the form
-`https://<root_url>/<project>/-/metrics?environment=<environment_id>` in a field
-that supports GitLab Flavored Markdown:
-
-```markdown
-### Summary
-
-**Start time:** 2020-01-21T12:00:31+00:00
-
-### Metrics
-
-https://gitlab.com/gitlab-org/monitor/tanuki-inc/-/metrics?environment=1118134
-```
-
-GitLab unfurls the link as an embedded metrics panel:
-
-![Embedded Metrics Rendered](img/embedded_metrics_rendered_v13_4.png)
-
-You can also embed a single chart. To get a link to a chart, in the upper-right corner of the chart,
-select **More actions** (**{ellipsis_v}**), then select **Copy link to chart** as shown in this example.
-
-![Copy Link To Chart](img/copy_link_to_chart_v12_10.png)
-
-The following requirements must be met for the metric to unfurl:
-
-- The `<environment_id>` must correspond to a real environment.
-- Prometheus must be monitoring the environment.
-- The GitLab instance must be configured to receive data from the environment.
-- The user must have at least the Reporter role for the monitoring dashboard for the environment.
-- The dashboard must have data within the last 8 hours.
-
- If all of the above are true, then the metric unfurls as seen below:
-
-![Embedded Metrics](img/view_embedded_metrics_v12_10.png)
-
-Metric charts may also be hidden:
-
-![Show Hide](img/hide_embedded_metrics_v12_10.png)
-
-You can open the link directly into your browser for a
-[detailed view of the data](dashboards/index.md#chart-context-menu).
-
-## Embedding metrics in issue templates
-
-You can also embed either the overview dashboard metrics or individual metrics in
-issue templates. For charts to render side-by-side, separate links to the entire metrics
-dashboard or individual metrics by either a comma or a space.
-
-![Embedded Metrics in issue templates](img/embed_metrics_issue_template.png)
-
-## Embedding metrics based on alerts in incident issues
-
-For [GitLab-managed alerting rules](alerts.md), the issue includes an embedded
-chart for the query corresponding to the alert. The chart displays an hour of data
-surrounding the starting point of the incident, 30 minutes before and after.
-
-For [manually configured Prometheus instances](../../user/project/integrations/prometheus.md#manual-configuration-of-prometheus),
-a chart corresponding to the query can be included if these requirements are met:
-
-- The alert corresponds to an environment managed through GitLab.
-- The alert corresponds to a [range query](https://prometheus.io/docs/prometheus/latest/querying/api/#range-queries).
-- The alert contains the required attributes listed in the chart below.
-
-| Attributes | Required | Description |
-| ---------- | -------- | ----------- |
-| `annotations/gitlab_environment_name` | Yes | Name of the GitLab-managed environment corresponding to the alert |
-| One of `annotations/title`, `annotations/summary`, `labels/alertname` | Yes | Used as the chart title |
-| `annotations/gitlab_y_label` | No | Used as the chart's y-axis label |
-
-## Embedding cluster health charts
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/40997) in GitLab 12.9.
-> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/208224) from GitLab Ultimate to GitLab Free in 13.2.
-
-[Cluster Health Metrics](../../user/infrastructure/clusters/manage/clusters_health.md)
-can also be embedded in [GitLab Flavored Markdown](../../user/markdown.md).
-
-To embed a metric chart, include a link to that chart in the form
-`https://<root_url>/<project>/-/cluster/<cluster_id>?<query_params>` anywhere that
-GitLab Flavored Markdown is supported. To generate and copy a link to the chart,
-follow the instructions in the
-[Cluster Health Metric documentation](../../user/infrastructure/clusters/manage/clusters_health.md).
-
-The following requirements must be met for the metric to unfurl:
-
-- The `<cluster_id>` must correspond to a real cluster.
-- Prometheus must be monitoring the cluster.
-- The user must be allowed access to the project cluster metrics.
-- The dashboards must be reporting data on the
- [Cluster Health Page](../../user/infrastructure/clusters/manage/clusters_health.md)
-
- If the above requirements are met, then the metric unfurls as seen below.
-
-![Embedded Cluster Metric in issue descriptions](img/prometheus_cluster_health_embed_v12_9.png)
+This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7
+and [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/399231) in 16.0.
diff --git a/doc/operations/metrics/embed_grafana.md b/doc/operations/metrics/embed_grafana.md
index 7bc88165b95..e14b4b5a893 100644
--- a/doc/operations/metrics/embed_grafana.md
+++ b/doc/operations/metrics/embed_grafana.md
@@ -2,90 +2,11 @@
stage: Monitor
group: Respond
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
+remove_date: '2023-08-22'
+redirect_to: '../index.md'
---
-<!--- start_remove The following content will be removed on remove_date: '2023-08-22' -->
-# Embed Grafana panels in Markdown (deprecated) **(FREE)**
+# Embed Grafana panels in Markdown (removed) **(FREE)**
-WARNING:
-This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/110290) in GitLab 15.9
-and is planned for removal in 16.0. We intend to replace this feature with the ability to [embed charts](https://gitlab.com/groups/gitlab-org/opstrace/-/epics/33) with the [GitLab Observability UI](https://gitlab.com/gitlab-org/opstrace/opstrace-ui).
-This change is a breaking change.
-
-Grafana panels can be embedded in [GitLab Flavored Markdown](../../user/markdown.md). You can
-embed Grafana panels using either:
-
-- [Grafana-rendered images](#use-grafana-rendered-images).
-- [Grafana API](#use-integration-with-grafana-api).
-
-## Use Grafana-rendered images
-
-You can embed live [Grafana](https://docs.gitlab.com/omnibus/settings/grafana.html) panels as
-[a direct link](https://grafana.com/docs/grafana/v7.5/sharing/share-panel/#use-direct-link).
-Your Grafana instance must:
-
-- Be available to the target user, either as a public dashboard or on the same network.
-- Have [Grafana Image Renderer](https://grafana.com/grafana/plugins/grafana-image-renderer/) installed.
-
-To use Grafana-rendered images:
-
-1. Go to the dashboard containing the panel in Grafana.
-1. From the panel's menu, select **Share**.
-1. Select **Direct link rendered image**, which provides the link.
-1. Copy the link and add an image tag as [inline HTML](../../user/markdown.md#inline-html) in your
- Markdown in the format `<img src="your_link"/>`. You can tweak the query parameters to meet your needs, such as removing the `&from=`
- and `&to=` parameters to display a live panel.
-
-## Use integration with Grafana API
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/31376) in GitLab 12.5.
-
-Each project can support integration with one Grafana instance. This enables you to copy a link to a
-panel in Grafana, then paste it into a GitLab Markdown field. The panel renders in the GitLab panel
-format. To embed panels from a Grafana instance, the data source must be:
-
-- A Prometheus instance.
-- Proxyable, so the **HTTP > Access** setting for the Grafana data source should be set to
- **Server (default)**.
-
-### Set up Grafana integration
-
-To set up the Grafana API in Grafana:
-
-1. In Grafana, [generate an Admin-level API Token](https://grafana.com/docs/grafana/next/developers/http_api/auth/#create-api-token).
-1. In your GitLab project, go to **Settings > Monitor** and expand the **Grafana authentication**
- section.
-1. To enable the integration, check the **Active** checkbox.
-1. For **Grafana URL**, enter the base URL of the Grafana instance.
-1. For **API Token**, enter the Administrator API token you just generated.
-1. Select **Save Changes**.
-
-NOTE:
-If the Grafana integration is enabled, users with the Reporter role on public
-projects and the Guest role on non-public projects can query metrics from the
-Prometheus instance. All requests proxied through GitLab are authenticated with
-the same Grafana Administrator API token.
-
-### Generate a link to a panel
-
-To generate a link to a panel:
-
-1. In Grafana, go to the dashboard you wish to embed a panel from.
-1. In the upper-left corner of the page, select a specific value for each variable required for the
- queries in the dashboard.
-1. In Grafana select a panel's title, then select **Share** to open the panel's sharing dialog to
- the **Link** tab.
-
- If you select the dashboard's share button instead, GitLab attempts to embed the first supported
- panel on the dashboard (if available).
-1. If your Prometheus queries use the Grafana custom template variables, ensure the
- **Template variables** option is set to on. Only the Grafana global template variables
- `$__interval`, `$__from`, and `$__to` are supported.
-1. Set the **Current time range** option to on, to specify the time range of the panel. Otherwise,
- the default range is the last 8 hours.
-1. Select **Copy** to copy the URL to the clipboard.
-1. In GitLab, paste the URL into a Markdown field and save. The panel takes a few moments to render.
-
-See the following example of a rendered panel.
-
-![GitLab Rendered Grafana Panel](img/rendered_grafana_embed_v12_5.png)
-<!--- end_remove -->
+This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7
+and [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/399231) in 16.0.
+Use [embed charts](https://gitlab.com/groups/gitlab-org/opstrace/-/epics/33) instead.
diff --git a/doc/operations/metrics/img/copy_link_to_chart_v12_10.png b/doc/operations/metrics/img/copy_link_to_chart_v12_10.png
deleted file mode 100644
index fc205240ea5..00000000000
--- a/doc/operations/metrics/img/copy_link_to_chart_v12_10.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/img/embed_metrics_issue_template.png b/doc/operations/metrics/img/embed_metrics_issue_template.png
deleted file mode 100644
index ca39a738d5f..00000000000
--- a/doc/operations/metrics/img/embed_metrics_issue_template.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/img/embedded_metrics_rendered_v13_4.png b/doc/operations/metrics/img/embedded_metrics_rendered_v13_4.png
deleted file mode 100644
index 876972dc721..00000000000
--- a/doc/operations/metrics/img/embedded_metrics_rendered_v13_4.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/img/example-dashboard_v13_3.png b/doc/operations/metrics/img/example-dashboard_v13_3.png
deleted file mode 100644
index 1178b4a9be7..00000000000
--- a/doc/operations/metrics/img/example-dashboard_v13_3.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/img/hide_embedded_metrics_v12_10.png b/doc/operations/metrics/img/hide_embedded_metrics_v12_10.png
deleted file mode 100644
index 1213029d1d1..00000000000
--- a/doc/operations/metrics/img/hide_embedded_metrics_v12_10.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/img/prometheus_add_metric.png b/doc/operations/metrics/img/prometheus_add_metric.png
deleted file mode 100644
index 32a7cbf3a73..00000000000
--- a/doc/operations/metrics/img/prometheus_add_metric.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/img/prometheus_cluster_health_embed_v12_9.png b/doc/operations/metrics/img/prometheus_cluster_health_embed_v12_9.png
deleted file mode 100644
index c669467757f..00000000000
--- a/doc/operations/metrics/img/prometheus_cluster_health_embed_v12_9.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/img/prometheus_dashboard_edit_metric_link_v_12_9.png b/doc/operations/metrics/img/prometheus_dashboard_edit_metric_link_v_12_9.png
deleted file mode 100644
index b66b1a9f39b..00000000000
--- a/doc/operations/metrics/img/prometheus_dashboard_edit_metric_link_v_12_9.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/img/prometheus_monitoring_dashboard_v13_3.png b/doc/operations/metrics/img/prometheus_monitoring_dashboard_v13_3.png
deleted file mode 100644
index 1178b4a9be7..00000000000
--- a/doc/operations/metrics/img/prometheus_monitoring_dashboard_v13_3.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/img/rendered_grafana_embed_v12_5.png b/doc/operations/metrics/img/rendered_grafana_embed_v12_5.png
deleted file mode 100644
index 6cabe4193bd..00000000000
--- a/doc/operations/metrics/img/rendered_grafana_embed_v12_5.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/img/view_embedded_metrics_v12_10.png b/doc/operations/metrics/img/view_embedded_metrics_v12_10.png
deleted file mode 100644
index 95bb148ba71..00000000000
--- a/doc/operations/metrics/img/view_embedded_metrics_v12_10.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/index.md b/doc/operations/metrics/index.md
index d6a9190be1e..98ed9aba0da 100644
--- a/doc/operations/metrics/index.md
+++ b/doc/operations/metrics/index.md
@@ -2,166 +2,11 @@
stage: Monitor
group: Respond
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
+remove_date: '2023-08-22'
+redirect_to: '../index.md'
---
-# Monitor your environment's metrics (deprecated) **(FREE)**
+# Monitor your environment's metrics (removed) **(FREE)**
-> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7.
-
-WARNING:
-This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541)
-for use in GitLab 14.7, and is planned for removal in GitLab 16.0.
-
-GitLab helps your team monitor the health and performance of your applications
-and infrastructure by turning statistics and log files into charts and graphs
-that are easy to understand, especially when time is short and decisions are
-critical. For GitLab to display your information in charts, you must:
-
-1. **Instrument your application** - Collect accurate and complete measurements.
- <I class="fa fa-youtube-play youtube" aria-hidden="true"></I>
- For an overview, see [How to instrument Prometheus metrics in GitLab](https://www.youtube.com/watch?v=tuI2oJ3TTB4).
-1. **Expose metrics for capture** - Make logs, metrics, and traces available for capture.
-1. [**Configure Prometheus to gather metrics**](#configure-prometheus-to-gather-metrics) -
- Use applications like Elasticsearch, Prometheus, and Jaeger to gather
- the data you've exposed.
-1. **GitLab collects metrics** - GitLab uses Prometheus to scrape the data you've
- captured in your applications, and prepares the data for display. For more information, see
- [Collect and process metrics](#collect-and-process-metrics).
-1. **Display charts in the GitLab user interface** - GitLab converts your metrics
- into easy-to-read charts on a default dashboard. You can create as many custom charts
- and custom dashboards as needed so your team has full insight into your
- application's health.
-
-## Configure Prometheus to gather metrics
-
-You must connect a Prometheus instance to GitLab to collect metrics. How you configure
-your Prometheus integration depends on where your apps are running:
-
-- **For manually-configured Prometheus** -
- [Specify your Prometheus server](../../user/project/integrations/prometheus.md#manual-configuration-of-prometheus),
- and define at least one environment.
-- **For a cluster integrated Prometheus** - GitLab can query
- [an in-cluster Prometheus](../../user/clusters/integrations.md#prometheus-cluster-integration).
- You must also complete a code deployment to your cluster for the **Monitor > Metrics**
- page to contain data. You can do this using [Auto DevOps](../../topics/autodevops/cloud_deployments/auto_devops_with_gke.md).
-
-![Monitoring Dashboard](img/prometheus_monitoring_dashboard_v13_3.png)
-
-## Collect and process metrics
-
-After [configuring Prometheus for a cluster](../../user/project/integrations/prometheus.md),
-GitLab attempts to retrieve performance metrics for any [environment](../../ci/environments/index.md) with
-a successful deployment.
-
-GitLab scans the Prometheus server for metrics from known servers like Kubernetes
-and NGINX, and attempts to identify individual environments. For more information about
-the supported metrics and scan processes, see
-[Prometheus Metrics library](../../user/project/integrations/prometheus_library/index.md).
-
-To view the [default metrics dashboard](dashboards/default.md) for an environment that is
-[configured to gather metrics](#configure-prometheus-to-gather-metrics):
-
-1. *If the metrics dashboard is only visible to project members,* sign in to
- GitLab as a member of a project. Learn more about [metrics dashboard visibility](#metrics-dashboard-visibility).
-1. In your project, navigate to **Monitor > Metrics**.
-
-GitLab displays the [default metrics dashboard](dashboards/default.md) for the environment,
-like the following example:
-
-![Example of metrics dashboard](img/example-dashboard_v13_3.png)
-
-The top of the dashboard contains a navigation bar. From left to right, the
-navigation bar contains:
-
-- **Dashboard** - A dropdown list of all dashboards available for the project,
- with starred dashboards listed first.
-- **Environment** - A dropdown list of all [environments](../index.md) that searches
- through all environments as you type.
-- **Range** - The time period of data to display.
-- **Refresh dashboard** **{retry}** - Reload the dashboard with current data.
-- **Set refresh rate** - Set a time frame for refreshing the data displayed.
-- **More actions** **{ellipsis_v}** - More dashboard actions
- - **Add metric** - Adds a [custom metric](#adding-custom-metrics). Only available on GitLab-defined dashboards.
- ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/34779) in GitLab 12.5.)
- - **Edit dashboard YAML** - Edit the source YAML file of a custom dashboard. Only available on
- [custom dashboards](dashboards/index.md).
- ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/34779) in GitLab 12.5.)
- - **Duplicate current dashboard** - Save a [complete copy of a dashboard](dashboards/index.md#duplicate-a-gitlab-defined-dashboard). Only available on GitLab-defined dashboards.
- - **Star dashboard** **{star-o}** - Mark a dashboard as a favorite.
- Starred dashboards display a solid star **{star}** button, and display first
- in the **Dashboard** dropdown list.
- ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/214582) in GitLab 13.0.)
- - **Create new dashboard** - Create a [new custom dashboard for your project](dashboards/index.md#add-a-new-dashboard-to-your-project).
- ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/228856) in GitLab 13.3.)
-- **Metrics settings** - Configure the
- [settings for this dashboard](dashboards/index.md#manage-the-metrics-dashboard-settings).
-
-## Customize your metrics dashboard
-
-After creating your dashboard, you can customize it to meet your needs:
-
-- **Add custom metrics**: In addition to the GitLab default metrics, you can
- [create custom metrics](#adding-custom-metrics) and display them on your metrics dashboard.
-- **Configure alerts for metrics**: [Configure custom alerts](alerts.md) for your team when
- environment performance falls outside of the boundaries you set.
-- **Trigger actions from alerts**: [Open new issues for your team](alerts.md#trigger-actions-from-alerts) **(ULTIMATE)**
- when environment performance falls outside of the boundaries you set.
-
-## Metrics dashboard visibility
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/201924) in GitLab 13.0.
-
-You can set the visibility of the metrics dashboard to **Only Project Members**
-or **Everyone With Access**. When set to **Everyone with Access**, the metrics
-dashboard is visible to authenticated and non-authenticated users.
-
-## Adding custom metrics
-
-> [Moved](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28527) from GitLab Premium to GitLab Free in 12.10.
-
-Custom metrics can be monitored by adding them on the monitoring dashboard page.
-After saving them, they display on the environment metrics dashboard provided that either:
-
-- A [connected Kubernetes cluster](../../user/clusters/agent/index.md)
- with the matching [environment scope](../../ci/environments/index.md#limit-the-environment-scope-of-a-cicd-variable) is used and
- [Prometheus installed on the cluster](../../user/project/integrations/prometheus.md#enabling-the-prometheus-integration).
-- Prometheus is [manually configured](../../user/project/integrations/prometheus.md#manual-configuration-of-prometheus).
-
-![Add New Metric](img/prometheus_add_metric.png)
-
-A few fields are required:
-
-- **Name**: Chart title
-- **Type**: Type of metric. Metrics of the same type are shown together.
-- **Query**: Valid [PromQL query](https://prometheus.io/docs/prometheus/latest/querying/basics/).
-- **Y-axis label**: Y axis title to display on the dashboard.
-- **Unit label**: Query units, for example `req / sec`. Shown next to the value.
-
-Multiple metrics can be displayed on the same chart if the fields **Name**, **Type**,
-and **Y-axis label** match between metrics. For example, a metric with **Name**
-`Requests Rate`, **Type** `Business`, and **Y-axis label** `rec / sec` would display
-on the same chart as a second metric with the same values. A **Legend label** is
-suggested if this feature is used.
-
-## Editing additional metrics from the dashboard
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/208976) in GitLab 12.9.
-
-You can edit existing additional custom metrics for your dashboard by selecting the
-**{ellipsis_v}** **More actions** dropdown list and selecting **Edit metric**.
-
-![Edit metric](img/prometheus_dashboard_edit_metric_link_v_12_9.png)
-
-## Keyboard shortcuts for charts
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/202146) in GitLab 13.2.
-
-You can use keyboard shortcuts to interact more quickly with your currently-focused
-chart panel. To activate keyboard shortcuts, use keyboard tabs to highlight the
-**{ellipsis_v}** **More actions** dropdown list, or hover over the dropdown list
-with your mouse, then press the key corresponding to your desired action:
-
-- **Expand panel** - <kbd>e</kbd>
-- **Download CSV** - <kbd>d</kbd>
-- **Copy link to chart** - <kbd>c</kbd>
-- **Alerts** - <kbd>a</kbd>
+This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7
+and [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/399231) in 16.0.
diff --git a/doc/raketasks/restore_gitlab.md b/doc/raketasks/restore_gitlab.md
index 1a8a95f8b42..c7abc7ac562 100644
--- a/doc/raketasks/restore_gitlab.md
+++ b/doc/raketasks/restore_gitlab.md
@@ -105,6 +105,7 @@ restore:
```shell
# This command will overwrite the contents of your GitLab database!
+# NOTE: "_gitlab_backup.tar" is omitted from the name
sudo gitlab-backup restore BACKUP=11493107454_2018_04_25_10.6.4-ce
```
diff --git a/doc/topics/autodevops/requirements.md b/doc/topics/autodevops/requirements.md
index 7d008b67639..dc126edf1aa 100644
--- a/doc/topics/autodevops/requirements.md
+++ b/doc/topics/autodevops/requirements.md
@@ -108,10 +108,7 @@ To make full use of Auto DevOps with Kubernetes, you need:
or manually by using the [`ingress-nginx`](https://github.com/kubernetes/ingress-nginx/tree/master/charts/ingress-nginx)
Helm chart.
- NOTE:
- For metrics to appear when using the [Prometheus cluster integration](../../user/clusters/integrations.md#prometheus-cluster-integration), you must [enable Prometheus metrics](https://github.com/kubernetes/ingress-nginx/tree/master/charts/ingress-nginx#prometheus-metrics).
-
- When deploying [using custom charts](customize.md#custom-helm-chart), you must also
+ When deploying [using custom charts](customize.md#custom-helm-chart), you must
[annotate](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/)
the Ingress manifest to be scraped by Prometheus using
`prometheus.io/scrape: "true"` and `prometheus.io/port: "10254"`.
@@ -142,21 +139,6 @@ To make full use of Auto DevOps with Kubernetes, you need:
for the entire GitLab instance, or [project runners](../../ci/runners/runners_scope.md#project-runners)
that are assigned to specific projects.
-- **Prometheus** (for [Auto Monitoring](stages.md#auto-monitoring))
-
- To enable Auto Monitoring, you need Prometheus installed either inside or
- outside your cluster, and configured to scrape your Kubernetes cluster.
- If you've configured the GitLab integration with Kubernetes, you can
- instruct GitLab to query an in-cluster Prometheus by enabling
- the [Prometheus cluster integration](../../user/clusters/integrations.md#prometheus-cluster-integration).
-
- The [Prometheus integration](../../user/project/integrations/prometheus.md)
- integration must be activated for the project, or activated at the group or instance level.
- For more information, see [Project integration management](../../user/admin_area/settings/project_integration_management.md).
-
- To get response metrics (in addition to system metrics), you must
- [configure Prometheus to monitor NGINX](../../user/project/integrations/prometheus_library/nginx_ingress.md#configuring-nginx-ingress-monitoring).
-
- **cert-manager** (optional, for TLS/HTTPS)
To enable HTTPS endpoints for your application, you can [install cert-manager](https://cert-manager.io/docs/installation/supported-releases/),
diff --git a/doc/topics/autodevops/stages.md b/doc/topics/autodevops/stages.md
index af0ccc514de..c95426b03e6 100644
--- a/doc/topics/autodevops/stages.md
+++ b/doc/topics/autodevops/stages.md
@@ -614,8 +614,7 @@ To use Auto Monitoring:
1. Select **Run pipeline**.
1. After the pipeline finishes successfully, open the
[monitoring dashboard for a deployed environment](../../ci/environments/index.md#monitor-environments)
- to view the metrics of your deployed application. To view the metrics of the
- whole Kubernetes cluster, on the left sidebar, select **Monitor > Metrics**.
+ to view the metrics of your deployed application.
![Auto Metrics](img/auto_monitoring.png)
diff --git a/doc/user/ai_features.md b/doc/user/ai_features.md
index d335cdabd56..7c9480d308f 100644
--- a/doc/user/ai_features.md
+++ b/doc/user/ai_features.md
@@ -81,6 +81,38 @@ To explain your code:
We cannot guarantee that the large language model produces results that are correct. Use the explanation with caution.
+### Explain this Vulnerability in the Web UI **(ULTIMATE SAAS)**
+
+> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/10368) in GitLab 16.0 as an [Experiment](../policy/alpha-beta-support.md#experiment) on GitLab.com.
+
+This feature is an [Experiment](../policy/alpha-beta-support.md) on GitLab.com that is powered by Google AI.
+
+GitLab can help you with your vulnerability by using a large language model to:
+
+- Summarize the vulnerability.
+- Help developers and security analysts get started understanding the vulnerability, how it could be exploited, and how to fix it.
+- Provide a suggested mitigation.
+
+Prerequisites:
+
+- You must have the GitLab Ultimate subscription tier.
+- You must be a member of the project.
+- The vulnerability must be a SAST finding.
+
+To explain your vulnerability:
+
+1. On the top bar, select **Main menu > Projects** and find your project.
+1. On the left sidebar, select **Security and Compliance > Vulnerability report**.
+1. Find a SAST vulnerability.
+1. Open the vulnerability.
+1. Select **Try it out**.
+
+Review the drawer on the right-hand side of your screen.
+
+![How to use Explain this Vulnerability Experiment](img/explain_this_vulnerability.png)
+
+We cannot guarantee that the large language model produces results that are correct. Use the explanation with caution.
+
### GitLab Chat **(ULTIMATE SAAS)**
> Introduced in GitLab 16.0 as an [Experiment](../policy/alpha-beta-support.md#experiment).
diff --git a/doc/user/application_security/policies/scan-result-policies.md b/doc/user/application_security/policies/scan-result-policies.md
index d0a736d0277..ecbbf4703b0 100644
--- a/doc/user/application_security/policies/scan-result-policies.md
+++ b/doc/user/application_security/policies/scan-result-policies.md
@@ -121,6 +121,7 @@ Requirements and limitations:
Otherwise, scan result policies do not have any effect.
- The maximum number of policies is five.
- Each policy can have a maximum of five rules.
+- All configured scanners must be present in the merge request's latest pipeline. If not, approvals are required even if some vulnerability criteria have not been met.
## Example security scan result policies project
diff --git a/doc/user/clusters/cost_management.md b/doc/user/clusters/cost_management.md
index 6f00466bc7e..6ed0f08c4a7 100644
--- a/doc/user/clusters/cost_management.md
+++ b/doc/user/clusters/cost_management.md
@@ -2,80 +2,11 @@
stage: Deploy
group: Environments
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
+remove_date: '2023-08-22'
+redirect_to: '../index.md'
---
-# Cluster cost management (deprecated) **(ULTIMATE)**
+# Cluster cost management (removed) **(ULTIMATE)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/216737) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.5.
-> - [Deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5.
-> - [Disabled on self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/353410) in GitLab 15.0.
-
-WARNING:
-This feature was [deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5.
-
-FLAG:
-On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to [enable the feature flag](../../administration/feature_flags.md) named `certificate_based_clusters`.
-
-Cluster cost management provides insights into cluster resource usage. GitLab provides an example
-[`kubecost-cost-model`](https://gitlab.com/gitlab-examples/kubecost-cost-model/)
-project that uses the GitLab Prometheus integration and
-[OpenCost `cost-model`](https://github.com/opencost/opencost) to provide cluster cost
-insights within GitLab:
-
-![Example dashboard](img/kubecost_v13_5.png)
-
-## Configure cluster cost management
-
-To get started with cluster cost management, you need the Maintainer role for a project or group.
-
-1. Clone the [`kubecost-cost-model`](https://gitlab.com/gitlab-examples/kubecost-cost-model/)
- example repository, which contains minor modifications to the upstream Kubecost
- `cost-model` project:
- - Configures your Prometheus endpoint to the GitLab-managed Prometheus. You may
- need to change this value if you use a non-managed Prometheus.
- - Adds the necessary annotations to the deployment manifest to be scraped by
- GitLab-managed Prometheus.
- - Changes the Google Pricing API access key to the GitLab access key.
- - Contains definitions for a custom GitLab Metrics dashboard to show the cost insights.
-1. Connect GitLab with Prometheus, depending on your configuration:
- - *If Prometheus is already configured,* navigate to **Settings > Integrations > Prometheus**
- to provide the API endpoint of your Prometheus server.
- - *To use the Prometheus cluster integration,* navigate to your cluster's **Details** page,
- select the **Integrations** tab, and follow the instructions to enable the Prometheus
- cluster integration.
-1. Set up the Prometheus integration on the cloned example project.
-1. Add the Kubecost `cost-model` to your cluster:
- - *For non-managed clusters*, deploy it with GitLab CI/CD.
- - *To deploy it manually*, use the following commands:
-
- ```shell
- kubectl create namespace cost-model
- kubectl apply -f kubernetes/ --namespace cost-model
- ```
-
-To access the cost insights, navigate to **Monitor > Metrics** and select
-the `default_costs.yml` dashboard. You can [customize](#customize-the-cost-dashboard)
-this dashboard.
-
-### Customize the cost dashboard
-
-You can customize the cost dashboard by editing the `.gitlab/dashboards/default_costs.yml`
-file or creating similar dashboard configuration files. For more information, see
-[Custom dashboards](../../operations/metrics/dashboards/index.md).
-
-#### Available metrics
-
-Metrics contain both instance and node labels. The instance label is scheduled for deprecation in a future version.
-
-- `node_cpu_hourly_cost` - Hourly cost per vCPU on this node.
-- `node_gpu_hourly_cost` - Hourly cost per GPU on this node.
-- `node_ram_hourly_cost` - Hourly cost per gigabyte of memory on this node.
-- `node_total_hourly_cost` - Total node cost per hour.
-- `container_cpu_allocation` - Average number of CPUs requested/used over the previous minute.
-- `container_gpu_allocation` - Average number of GPUs requested over the previous minute.
-- `container_memory_allocation_bytes` - Average bytes of RAM requested/used over the previous minute.
-- `pod_pvc_allocation` - Bytes provisioned for a PVC attached to a pod.
-- `pv_hourly_cost` - Hourly cost per GB on a persistent volume.
-
-Some examples are provided in the
-[`kubecost-cost-model` repository](https://gitlab.com/gitlab-examples/kubecost-cost-model/-/blob/master/PROMETHEUS.md#example-queries).
+This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7
+and [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/399231) in 16.0.
diff --git a/doc/user/clusters/integrations.md b/doc/user/clusters/integrations.md
index 2c67afefd98..3076730b10f 100644
--- a/doc/user/clusters/integrations.md
+++ b/doc/user/clusters/integrations.md
@@ -2,99 +2,11 @@
stage: Deploy
group: Environments
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
+remove_date: '2023-08-22'
+redirect_to: '../index.md'
---
-# Cluster integrations (deprecated) **(FREE)**
+# Cluster integrations (removed) **(FREE)**
-> - [Deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5.
-> - [Disabled on self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/353410) in GitLab 15.0.
-
-WARNING:
-This feature was [deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5.
-
-FLAG:
-On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to [enable the feature flag](../../administration/feature_flags.md) named `certificate_based_clusters`.
-
-GitLab provides several ways to integrate applications to your
-Kubernetes cluster.
-
-To enable cluster integrations, first add a Kubernetes cluster to a GitLab
-[project](../project/clusters/index.md) or
-[group](../group/clusters/index.md) or
-[instance](../instance/clusters/index.md).
-
-You can install your applications manually as shown in the following sections, or use the
-[Cluster management project template](management_project_template.md) that automates the
-installation.
-
-Although, the [Cluster management project template](management_project_template.md) still
-requires that you manually do the last steps of this section,
-[Enable Prometheus integration for your cluster](#enable-prometheus-integration-for-your-cluster). [An issue exists](https://gitlab.com/gitlab-org/gitlab/-/issues/326565)
-to automate this step.
-
-Prometheus cluster integrations can only be enabled for clusters [connected through cluster certificates](../project/clusters/add_existing_cluster.md).
-
-To enable Prometheus for your cluster connected through the [GitLab agent](agent/index.md), you can [integrate it manually](../project/integrations/prometheus.md#manual-configuration-of-prometheus).
-
-There is no option to enable Elastic Stack for your cluster if it is connected with the GitLab agent.
-Follow this [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/300230) for updates.
-
-## Prometheus cluster integration
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55244) in GitLab 13.11.
-
-WARNING:
-This feature was [deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5. However, you can **still use** Prometheus
-for Kubernetes clusters connected to GitLab through the
-[agent](agent/index.md) by [enabling Prometheus manually](../project/integrations/prometheus.md#manual-configuration-of-prometheus).
-
-You can integrate your Kubernetes cluster with
-[Prometheus](https://prometheus.io/) for monitoring key metrics of your
-apps directly from the GitLab UI.
-
-Once enabled, you can see metrics from services available in the
-[metrics library](../project/integrations/prometheus_library/index.md).
-
-### Prometheus Prerequisites
-
-To use this integration:
-
-1. Prometheus must be installed in your cluster in the `gitlab-managed-apps` namespace.
-1. The `Service` resource for Prometheus must be named `prometheus-prometheus-server`.
-
-You can manage your Prometheus however you like, but as an example, you can set
-it up using [Helm](https://helm.sh/) as follows:
-
-```shell
-# Create the required Kubernetes namespace
-kubectl create ns gitlab-managed-apps
-
-# Download Helm chart values that is compatible with the requirements above.
-# These are included in the Cluster Management project template.
-wget https://gitlab.com/gitlab-org/project-templates/cluster-management/-/raw/master/applications/prometheus/values.yaml
-
-# Add the Prometheus community Helm chart repository
-helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
-
-# Install Prometheus
-helm install prometheus prometheus-community/prometheus -n gitlab-managed-apps --values values.yaml
-```
-
-Alternatively, you can use your preferred installation method to install
-Prometheus as long as you meet the requirements above.
-
-### Enable Prometheus integration for your cluster
-
-To enable the Prometheus integration for your cluster:
-
-1. Go to the cluster's page:
- - For a [project-level cluster](../project/clusters/index.md), go to your project's
- **Infrastructure > Kubernetes clusters**.
- - For a [group-level cluster](../group/clusters/index.md), go to your group's
- **Kubernetes** page.
- - For an [instance-level cluster](../instance/clusters/index.md), go to your instance's
- **Kubernetes** page.
-1. Select the **Integrations** tab.
-1. Check the **Enable Prometheus integration** checkbox.
-1. Select **Save changes**.
-1. Go to the **Health** tab to see your cluster's metrics.
+This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7
+and [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/399231) in 16.0.
diff --git a/doc/user/img/explain_this_vulnerability.png b/doc/user/img/explain_this_vulnerability.png
new file mode 100644
index 00000000000..0880ad5f875
--- /dev/null
+++ b/doc/user/img/explain_this_vulnerability.png
Binary files differ
diff --git a/doc/user/infrastructure/clusters/manage/clusters_health.md b/doc/user/infrastructure/clusters/manage/clusters_health.md
index 620430a449a..d9b849ffccc 100644
--- a/doc/user/infrastructure/clusters/manage/clusters_health.md
+++ b/doc/user/infrastructure/clusters/manage/clusters_health.md
@@ -2,18 +2,11 @@
stage: Deploy
group: Environments
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
+remove_date: '2023-08-22'
+redirect_to: '../index.md'
---
-# Clusters health (deprecated) **(FREE)**
+# Clusters health (removed) **(FREE)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/4701) in GitLab 10.6.
-> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/208224) from GitLab Ultimate to GitLab Free in 13.2.
-> - [Deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5.
-
-WARNING:
-This feature was [deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5. However, you can **still use** Prometheus
-for Kubernetes clusters connected to GitLab by [enabling Prometheus manually](../../../project/integrations/prometheus.md#manual-configuration-of-prometheus).
-
-When [the Prometheus cluster integration is enabled](../../../clusters/integrations.md#prometheus-cluster-integration), GitLab monitors the cluster's health. At the top of the cluster settings page, CPU and Memory utilization is displayed, along with the total amount available. Keeping an eye on cluster resources can be important, if the cluster runs out of memory pods may be shutdown or fail to start.
-
-![Cluster Monitoring](img/k8s_cluster_monitoring.png)
+This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7
+and [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/399231) in 16.0.
diff --git a/doc/user/infrastructure/clusters/manage/img/k8s_cluster_monitoring.png b/doc/user/infrastructure/clusters/manage/img/k8s_cluster_monitoring.png
deleted file mode 100644
index 0a8c5043c65..00000000000
--- a/doc/user/infrastructure/clusters/manage/img/k8s_cluster_monitoring.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/integrations/prometheus.md b/doc/user/project/integrations/prometheus.md
index 744d8c7c352..d17e8e6bfca 100644
--- a/doc/user/project/integrations/prometheus.md
+++ b/doc/user/project/integrations/prometheus.md
@@ -2,129 +2,11 @@
stage: Monitor
group: Respond
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
+remove_date: '2023-08-22'
+redirect_to: 'index.md'
---
-# Prometheus **(FREE)**
+# Prometheus (removed) **(FREE)**
-GitLab offers powerful integration with [Prometheus](https://prometheus.io) for
-monitoring key metrics of your apps, directly in GitLab.
-Metrics for each environment are retrieved from Prometheus, and then displayed
-in the GitLab interface.
-
-![Environment Dashboard](img/prometheus_dashboard.png)
-
-There are two ways to set up Prometheus integration, depending on where your apps are running:
-
-- For deployments on Kubernetes, GitLab can be [integrated with an in-cluster Prometheus](#prometheus-cluster-integration)
-- For other deployment targets, [specify the Prometheus server](#manual-configuration-of-prometheus).
-
-Once enabled, GitLab detects metrics from known services in the
-[metric library](prometheus_library/index.md). You can also
-[add your own metrics](../../../operations/metrics/index.md#adding-custom-metrics) and create
-[custom dashboards](../../../operations/metrics/dashboards/index.md).
-
-## Enabling the Prometheus integration
-
-### Prometheus cluster integration
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55244) in GitLab 13.11.
-> - [Replaced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62725) the Prometheus cluster applications in GitLab 14.0.
-
-GitLab can query an in-cluster Prometheus for your metrics.
-See [Prometheus cluster integration](../../clusters/integrations.md#prometheus-cluster-integration) for details.
-
-### Manual configuration of Prometheus
-
-#### Prerequisites
-
-Integration with Prometheus requires the following:
-
-- Prometheus must be configured to collect one of the [supported metrics](prometheus_library/index.md)
-- Each metric must have a label to indicate the environment
-- GitLab must have network connectivity to the Prometheus server
-
-#### Getting started
-
-Installing and configuring Prometheus to monitor applications is fairly straightforward.
-
-1. [Install Prometheus](https://prometheus.io/docs/prometheus/latest/installation/)
-1. Set up one of the [supported monitoring targets](prometheus_library/index.md)
-1. Configure the Prometheus server to
- [collect their metrics](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config)
-
-#### Configuration in GitLab
-
-The actual configuration of Prometheus integration in GitLab
-requires the domain name or IP address of the Prometheus server you'd like
-to integrate with. If the Prometheus resource is secured with Google's Identity-Aware Proxy (IAP),
-you can pass information like Client ID and Service Account credentials.
-GitLab can use these to access the resource. More information about authentication from a
-service account can be found at Google's documentation for
-[Authenticating from a service account](https://cloud.google.com/iap/docs/authentication-howto#authenticating_from_a_service_account).
-
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **Settings > Integrations**.
-1. Select **Prometheus**.
-1. For **API URL**, provide the domain name or IP address of your server, such as
- `http://prometheus.example.com/` or `http://192.0.2.1/`.
-1. (Optional) In **Google IAP Audience Client ID**, provide the Client ID of the
- Prometheus OAuth Client secured with Google IAP.
-1. (Optional) In **Google IAP Service Account JSON**, provide the contents of the
- Service Account credentials file that is authorized to access the Prometheus resource.
- The JSON key `token_credential_uri` is discarded to prevent
- [Server-side Request Forgery (SSRF)](https://www.hackerone.com/application-security/how-server-side-request-forgery-ssrf).
-1. Select **Save changes**.
-
-![Configure Prometheus Service](img/prometheus_manual_configuration_v13_2.png)
-
-#### Thanos configuration in GitLab
-
-You can configure [Thanos](https://thanos.io/) as a drop-in replacement for Prometheus
-with GitLab. Use the domain name or IP address of the Thanos server you'd like
-to integrate with.
-
-1. On the top bar, select **Main menu > Projects** and find your project.
-1. On the left sidebar, select **Settings > Integrations**.
-1. Select **Prometheus**.
-1. Provide the domain name or IP address of your server, for example
- `http://thanos.example.com/` or `http://192.0.2.1/`.
-1. Select **Save changes**.
-
-### Precedence with multiple Prometheus configurations
-
-Although you can enable both a [manual configuration](#manual-configuration-of-prometheus)
-and [cluster integration](#prometheus-cluster-integration) of Prometheus, you
-can use only one:
-
-- If you have enabled a
- [Prometheus manual configuration](#manual-configuration-of-prometheus)
- and a [Prometheus cluster integration](#prometheus-cluster-integration),
- the manual configuration takes precedence and is used to run queries from
- [custom dashboards](../../../operations/metrics/dashboards/index.md) and
- [custom metrics](../../../operations/metrics/index.md#adding-custom-metrics).
-- If you have managed Prometheus applications installed on Kubernetes clusters
- at **different** levels (project, group, instance), the order of precedence is described in
- [Cluster precedence](../../instance/clusters/index.md#cluster-precedence).
-- If you have managed Prometheus applications installed on multiple Kubernetes
- clusters at the **same** level, the Prometheus application of a cluster with a
- matching [environment scope](../../../ci/environments/index.md#limit-the-environment-scope-of-a-cicd-variable) is used.
-
-## Determining the performance impact of a merge
-
-Developers can view the performance impact of their changes in the merge
-request workflow. This feature requires [Kubernetes](prometheus_library/kubernetes.md) metrics.
-
-When a source branch has been deployed to an environment, a sparkline and
-numeric comparison of the average memory consumption displays. On the
-sparkline, a dot indicates when the current changes were deployed, with up to 30 minutes of
-performance data displayed before and after. The comparison shows the difference
-between the 30 minute average before and after the deployment. This information
-is updated after each commit has been deployed.
-
-Once merged and the target branch has been redeployed, the metrics switches
-to show the new environments this revision has been deployed to.
-
-Performance data is available for the duration it is persisted on the
-Prometheus server.
-
-![Merge Request with Performance Impact](img/merge_request_performance.png)
+This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7
+and [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/399231) in 16.0.
diff --git a/doc/user/project/integrations/prometheus_library/cloudwatch.md b/doc/user/project/integrations/prometheus_library/cloudwatch.md
index 544f3c96644..848ccbb85f6 100644
--- a/doc/user/project/integrations/prometheus_library/cloudwatch.md
+++ b/doc/user/project/integrations/prometheus_library/cloudwatch.md
@@ -2,48 +2,11 @@
stage: Monitor
group: Respond
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
+remove_date: '2023-08-22'
+redirect_to: '../../../../operations/index.md'
---
-# Monitoring AWS resources (deprecated) **(FREE)**
+# Monitoring AWS resources (removed) **(FREE)**
-> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7.
-
-WARNING:
-This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541)
-in GitLab 14.7, and is planned for removal in GitLab 16.0.
-
-GitLab supports automatically detecting and monitoring AWS resources, starting
-with the [Elastic Load Balancer](https://aws.amazon.com/elasticloadbalancing/) (ELB).
-This is provided by leveraging the official [Cloudwatch exporter](https://github.com/prometheus/cloudwatch_exporter), which translates [Cloudwatch metrics](https://aws.amazon.com/cloudwatch/) into
-a Prometheus readable form.
-
-## Prerequisite
-
-You must enable the [Prometheus service](../prometheus.md).
-
-## Supported metrics
-
-| Name | Query |
-|----------------------|-------|
-| Throughput (req/sec) | `sum(aws_elb_request_count_sum{%{environment_filter}}) / 60` |
-| Latency (ms) | `avg(aws_elb_latency_average{%{environment_filter}}) * 1000` |
-| HTTP Error Rate (%) | `sum(aws_elb_httpcode_backend_5_xx_sum{%{environment_filter}}) / sum(aws_elb_request_count_sum{%{environment_filter}})` |
-
-## Configuring Prometheus to monitor for Cloudwatch metrics
-
-To get started with Cloudwatch monitoring, install and configure the
-[Cloudwatch exporter](https://github.com/prometheus/cloudwatch_exporter). The
-Cloudwatch exporter retrieves and parses the specified Cloudwatch metrics, and
-translates them into a Prometheus monitoring endpoint.
-
-The only supported AWS resource is the Elastic Load Balancer, whose Cloudwatch
-metrics are listed in [this AWS documentation](https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-cloudwatch-metrics.html).
-
-You can [download a sample Cloudwatch Exporter configuration file](../samples/cloudwatch.yml)
-that's configured for basic AWS ELB monitoring.
-
-## Specifying the Environment label
-
-To isolate and display only the relevant metrics for a given environment,
-GitLab needs a method to detect which labels are associated. To do this, GitLab
-[looks for an `environment` label](index.md#identifying-environments).
+This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7
+and [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/399231) in 16.0.
diff --git a/doc/user/project/integrations/prometheus_library/haproxy.md b/doc/user/project/integrations/prometheus_library/haproxy.md
index c4e45af3d2b..ca015d7dc8a 100644
--- a/doc/user/project/integrations/prometheus_library/haproxy.md
+++ b/doc/user/project/integrations/prometheus_library/haproxy.md
@@ -2,34 +2,11 @@
stage: Monitor
group: Respond
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
+remove_date: '2023-08-22'
+redirect_to: '../../../../operations/index.md'
---
-# Monitoring HAProxy (deprecated) **(FREE)**
+# Monitoring HAProxy (removed) **(FREE)**
-> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7.
-
-WARNING:
-This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541)
-in GitLab 14.7, and is planned for removal in GitLab 16.0.
-
-GitLab has support for automatically detecting and monitoring HAProxy. This is provided by leveraging the [HAProxy Exporter](https://github.com/prometheus/haproxy_exporter), which translates HAProxy statistics into a Prometheus readable form.
-
-## Prerequisite
-
-The [Prometheus service](../prometheus.md) must be enabled.
-
-## Metrics supported
-
-| Name | Query |
-| ---- | ----- |
-| Throughput (req/sec) | `sum(rate(haproxy_frontend_http_requests_total{%{environment_filter}}[2m])) by (code)` |
-| HTTP Error Rate (%) | `sum(rate(haproxy_frontend_http_requests_total{code="5xx",%{environment_filter}}[2m])) / sum(rate(haproxy_frontend_http_requests_total{%{environment_filter}}[2m]))` |
-
-## Configuring Prometheus to monitor for HAProxy metrics
-
-To get started with NGINX monitoring, you should install and configure the [HAProxy exporter](https://github.com/prometheus/haproxy_exporter) which parses these statistics and translates them into a Prometheus monitoring endpoint.
-
-## Specifying the Environment label
-
-In order to isolate and only display relevant metrics for a given environment
-however, GitLab needs a method to detect which labels are associated. To do this, GitLab [looks for an `environment` label](index.md#identifying-environments).
+This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7
+and [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/399231) in 16.0.
diff --git a/doc/user/project/integrations/prometheus_library/index.md b/doc/user/project/integrations/prometheus_library/index.md
index fe9ce323b23..ee0b0d1fccb 100644
--- a/doc/user/project/integrations/prometheus_library/index.md
+++ b/doc/user/project/integrations/prometheus_library/index.md
@@ -2,43 +2,11 @@
stage: Monitor
group: Respond
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
+remove_date: '2023-08-22'
+redirect_to: '../../../../operations/index.md'
---
-# Prometheus Metrics library (deprecated) **(FREE)**
+# Prometheus Metrics library (removed) **(FREE)**
-> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7.
-
-WARNING:
-This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541)
-in GitLab 14.7, and is planned for removal in GitLab 16.0.
-
-GitLab offers automatic detection of select [Prometheus exporters](https://prometheus.io/docs/instrumenting/exporters/).
-
-## Exporters
-
-Currently supported exporters are:
-
-- [Kubernetes](kubernetes.md)
-- [NGINX](nginx.md)
-- [NGINX Ingress Controller 0.9.0-0.15.x](nginx_ingress_vts.md)
-- [NGINX Ingress Controller 0.16.0+](nginx_ingress.md)
-- [HAProxy](haproxy.md)
-- [Amazon Cloud Watch](cloudwatch.md)
-
-We have tried to surface the most important metrics for each exporter, and
-continue to add support for additional exporters in future releases. If you
-would like to add support for other official exporters, contributions are welcome.
-
-## Identifying Environments
-
-GitLab retrieves performance data from the configured Prometheus server, and
-attempts to identifying the presence of known metrics. Once identified, GitLab
-then needs to be able to map the data to a particular environment.
-
-To isolate and only display relevant metrics for a given environment,
-GitLab needs a method to detect which labels are associated. To do that,
-GitLab uses the defined queries and fills in the environment specific variables.
-Typically this involves looking for the
-[`$CI_ENVIRONMENT_SLUG`](../../../../ci/variables/index.md#predefined-cicd-variables),
-but may also include other information such as the project's Kubernetes namespace.
-Each search query is defined in the [exporter specific documentation](#exporters).
+This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7
+and [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/399231) in 16.0.
diff --git a/doc/user/project/integrations/prometheus_library/kubernetes.md b/doc/user/project/integrations/prometheus_library/kubernetes.md
index e3d7114b24d..4b8b9b4bc21 100644
--- a/doc/user/project/integrations/prometheus_library/kubernetes.md
+++ b/doc/user/project/integrations/prometheus_library/kubernetes.md
@@ -2,66 +2,11 @@
stage: Monitor
group: Respond
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
+remove_date: '2023-08-22'
+redirect_to: '../../../../operations/index.md'
---
-# Monitoring Kubernetes (deprecated) **(FREE)**
+# Monitoring Kubernetes (removed) **(FREE)**
-> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7.
-
-WARNING:
-This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541)
-in GitLab 14.7, and is planned for removal in GitLab 16.0.
-
-GitLab has support for automatically detecting and monitoring Kubernetes metrics.
-
-## Prerequisite
-
-The [Prometheus](../prometheus.md) and [Kubernetes](../../../infrastructure/clusters/index.md)
-integration services must be enabled.
-
-## Metrics supported
-
-- Average Memory Usage (MB):
-
- ```prometheus
- avg(sum(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-([^c].*|c([^a]|a([^n]|n([^a]|a([^r]|r[^y])))).*|)-(.*)",namespace="%{kube_namespace}"}) by (job)) without (job) / count(avg(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-([^c].*|c([^a]|a([^n]|n([^a]|a([^r]|r[^y])))).*|)-(.*)",namespace="%{kube_namespace}"}) without (job)) /1024/1024
- ```
-
-- Average CPU Utilization (%):
-
- ```prometheus
- avg(sum(rate(container_cpu_usage_seconds_total{container_name!="POD",pod_name=~"^%{ci_environment_slug}-([^c].*|c([^a]|a([^n]|n([^a]|a([^r]|r[^y])))).*|)-(.*)",namespace="%{kube_namespace}"}[15m])) by (job)) without (job) / count(sum(rate(container_cpu_usage_seconds_total{container_name!="POD",pod_name=~"^%{ci_environment_slug}-([^c].*|c([^a]|a([^n]|n([^a]|a([^r]|r[^y])))).*|)-(.*)",namespace="%{kube_namespace}"}[15m])) by (pod_name))
- ```
-
-## Configuring Prometheus to monitor for Kubernetes metrics
-
-Prometheus needs to be deployed into the cluster and configured properly to gather Kubernetes metrics. GitLab supports two methods for doing so:
-
-- GitLab [integrates with Kubernetes](../../clusters/index.md), and can [query a Prometheus in a connected cluster](../../../clusters/integrations.md#prometheus-cluster-integration). The in-cluster Prometheus can be configured to automatically collect application metrics from your cluster.
-- To configure your own Prometheus server, you can follow the [Prometheus documentation](https://prometheus.io/docs/introduction/overview/).
-
-## Specifying the Environment
-
-To isolate and only display relevant CPU and Memory metrics for a given environment, GitLab needs a method to detect which containers it is running. Because these metrics are tracked at the container level, traditional Kubernetes labels are not available.
-
-Instead, the [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) or [DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) name should begin with [CI_ENVIRONMENT_SLUG](../../../../ci/variables/index.md#predefined-cicd-variables). It can be followed by a `-` and additional content if desired. For example, a deployment name of `review-homepage-5620p5` would match the `review/homepage` environment.
-
-## Displaying Canary metrics **(PREMIUM)**
-
-GitLab also gathers Kubernetes metrics for [canary deployments](../../canary_deployments.md), allowing easy comparison between the current deployed version and the canary.
-
-These metrics expect the [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) or [DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) name to begin with `$CI_ENVIRONMENT_SLUG-canary`, to isolate the canary metrics.
-
-### Canary metrics supported
-
-- Average Memory Usage (MB)
-
- ```prometheus
- avg(sum(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-canary-(.*)",namespace="%{kube_namespace}"}) by (job)) without (job) / count(avg(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-canary-(.*)",namespace="%{kube_namespace}"}) without (job)) /1024/1024
- ```
-
-- Average CPU Utilization (%)
-
- ```prometheus
- avg(sum(rate(container_cpu_usage_seconds_total{container_name!="POD",pod_name=~"^%{ci_environment_slug}-canary-(.*)",namespace="%{kube_namespace}"}[15m])) by (job)) without (job) / count(sum(rate(container_cpu_usage_seconds_total{container_name!="POD",pod_name=~"^%{ci_environment_slug}-canary-(.*)",namespace="%{kube_namespace}"}[15m])) by (pod_name))
- ```
+This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7
+and [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/399231) in 16.0.
diff --git a/doc/user/project/integrations/prometheus_library/nginx.md b/doc/user/project/integrations/prometheus_library/nginx.md
index 87eed81523b..995de6a28f3 100644
--- a/doc/user/project/integrations/prometheus_library/nginx.md
+++ b/doc/user/project/integrations/prometheus_library/nginx.md
@@ -2,42 +2,11 @@
stage: Monitor
group: Respond
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
+remove_date: '2023-08-22'
+redirect_to: '../../../../operations/index.md'
---
-# Monitoring NGINX (deprecated) **(FREE)**
+# Monitoring NGINX (removed) **(FREE)**
-> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7.
-
-WARNING:
-This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541)
-in GitLab 14.7, and is planned for removal in GitLab 16.0.
-
-GitLab has support for automatically detecting and monitoring NGINX. This is provided by leveraging the [NGINX VTS exporter](https://github.com/hnlq715/nginx-vts-exporter), which translates [VTS statistics](https://github.com/vozlt/nginx-module-vts) into a Prometheus readable form.
-
-## Prerequisite
-
-The [Prometheus service](../prometheus.md) must be enabled.
-
-## Metrics supported
-
-NGINX server metrics are detected, which tracks the pages and content directly served by NGINX.
-
-[`environment_filter`](../../../../operations/metrics/dashboards/variables.md#environment_filter) is one of the predefined variables that metrics dashboards support.
-
-| Name | Query |
-| ---- | ----- |
-| Throughput (req/sec) | `sum(rate(nginx_server_requests{server_zone!="*", server_zone!="_", %{environment_filter}}[2m])) by (code)` |
-| Latency (ms) | `avg(nginx_server_requestMsec{%{environment_filter}})` |
-| HTTP Error Rate (HTTP Errors / sec) | `sum(rate(nginx_server_requests{code="5xx", %{environment_filter}}[2m]))` |
-| HTTP Error (%)| `sum(rate(nginx_server_requests{code=~"5.*", host="*", %{environment_filter}}[2m])) / sum(rate(nginx_server_requests{code="total", host="*", %{environment_filter}}[2m])) * 100` |
-
-## Configuring Prometheus to monitor for NGINX metrics
-
-To get started with NGINX monitoring, you should first enable the [VTS statistics](https://github.com/vozlt/nginx-module-vts) module for your NGINX server. This captures and displays statistics in an HTML readable form. Next, you should install and configure the [NGINX VTS exporter](https://github.com/hnlq715/nginx-vts-exporter) which parses these statistics and translates them into a Prometheus monitoring endpoint.
-
-If you are using NGINX as your Kubernetes Ingress, GitLab [automatically detects](nginx_ingress.md) the metrics once enabled in 0.9.0 and later releases.
-
-## Specifying the Environment label
-
-In order to isolate and only display relevant metrics for a given environment
-however, GitLab needs a method to detect which labels are associated. To do this, GitLab [looks for an `environment` label](index.md#identifying-environments).
+This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7
+and [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/399231) in 16.0.
diff --git a/doc/user/project/integrations/prometheus_library/nginx_ingress.md b/doc/user/project/integrations/prometheus_library/nginx_ingress.md
index cc2634406dd..03f88e6f7c5 100644
--- a/doc/user/project/integrations/prometheus_library/nginx_ingress.md
+++ b/doc/user/project/integrations/prometheus_library/nginx_ingress.md
@@ -2,48 +2,11 @@
stage: Monitor
group: Respond
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
+remove_date: '2023-08-22'
+redirect_to: '../../../../operations/index.md'
---
-# Monitoring NGINX Ingress Controller (deprecated) **(FREE)**
+# Monitoring NGINX Ingress Controller (removed) **(FREE)**
-> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7.
-
-WARNING:
-This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541)
-in GitLab 14.7, and is planned for removal in GitLab 16.0.
-
-GitLab has support for automatically detecting and monitoring the Kubernetes NGINX Ingress controller. This is provided by leveraging the built-in Prometheus metrics included with Kubernetes NGINX Ingress controller [version 0.16.0](https://github.com/kubernetes/ingress-nginx/blob/master/Changelog.md#0160) onward.
-
-NOTE:
-NGINX Ingress versions prior to 0.16.0 offer an included [VTS Prometheus metrics exporter](nginx_ingress_vts.md), which exports metrics different than the built-in metrics.
-
-## Prerequisite
-
-[Prometheus integration](../prometheus.md) must be active.
-
-## Metrics supported
-
-| Name | Query |
-| ---- | ----- |
-| Throughput (req/sec) | `sum(label_replace(rate(nginx_ingress_controller_requests{namespace="%{kube_namespace}",ingress=~".*%{ci_environment_slug}.*"}[2m]), "status_code", "${1}xx", "status", "(.)..")) by (status_code)` |
-| Latency (ms) | `sum(rate(nginx_ingress_controller_ingress_upstream_latency_seconds_sum{namespace="%{kube_namespace}",ingress=~".*%{ci_environment_slug}.*"}[2m])) / sum(rate(nginx_ingress_controller_ingress_upstream_latency_seconds_count{namespace="%{kube_namespace}",ingress=~".*%{ci_environment_slug}.*"}[2m])) * 1000` |
-| HTTP Error Rate (%) | `sum(rate(nginx_ingress_controller_requests{status=~"5.*",namespace="%{kube_namespace}",ingress=~".*%{ci_environment_slug}.*"}[2m])) / sum(rate(nginx_ingress_controller_requests{namespace="%{kube_namespace}",ingress=~".*%{ci_environment_slug}.*"}[2m])) * 100` |
-
-## Configuring NGINX Ingress monitoring
-
-Version 0.9.0 and above of [NGINX Ingress](https://github.com/kubernetes/ingress-nginx) have built-in support for exporting Prometheus metrics. To enable, a ConfigMap setting must be passed: `enable-vts-status: "true"`. Once enabled, a Prometheus metrics endpoint starts running on port 10254.
-
-Next, the Ingress needs to be annotated for Prometheus monitoring. Two new annotations need to be added:
-
-- `prometheus.io/scrape: "true"`
-- `prometheus.io/port: "10254"`
-
-Managing these settings depends on how NGINX Ingress has been deployed. If you have deployed via the [official Helm chart](https://github.com/kubernetes/ingress-nginx/tree/master/charts/ingress-nginx), metrics can be enabled with `controller.stats.enabled` along with the required annotations. Alternatively it is possible to edit the NGINX Ingress YAML directly in the [Kubernetes dashboard](https://github.com/kubernetes/dashboard).
-
-## Specifying the Environment label
-
-To isolate and display only relevant metrics for a given environment, GitLab needs a method to
-detect which labels are associated. To do this, GitLab searches for metrics with appropriate labels.
-In this case, the `ingress` label must include the value `<CI_ENVIRONMENT_SLUG>`.
-
-If you have used [Auto Deploy](../../../../topics/autodevops/stages.md#auto-deploy) to deploy your app, this format is used automatically and metrics are detected with no action on your part.
+This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7
+and [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/399231) in 16.0.
diff --git a/doc/user/project/integrations/prometheus_library/nginx_ingress_vts.md b/doc/user/project/integrations/prometheus_library/nginx_ingress_vts.md
index 5dd47989f59..837be9d1e0a 100644
--- a/doc/user/project/integrations/prometheus_library/nginx_ingress_vts.md
+++ b/doc/user/project/integrations/prometheus_library/nginx_ingress_vts.md
@@ -2,46 +2,11 @@
stage: Monitor
group: Respond
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
+remove_date: '2023-08-22'
+redirect_to: '../../../../operations/index.md'
---
-# Monitoring NGINX Ingress Controller with VTS metrics (deprecated) **(FREE)**
+# Monitoring NGINX Ingress Controller with VTS metrics (removed) **(FREE)**
-> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7.
-
-WARNING:
-This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541)
-in GitLab 14.7, and is planned for removal in GitLab 16.0.
-
-NOTE:
-[NGINX Ingress version 0.16](nginx_ingress.md) and above have built-in Prometheus metrics, which are different than the VTS based metrics.
-
-GitLab has support for automatically detecting and monitoring the Kubernetes NGINX Ingress controller. This is provided by leveraging the included VTS Prometheus metrics exporter in [version 0.9.0](https://github.com/kubernetes/ingress-nginx/blob/master/Changelog.md#09-beta1) through [0.15.x](https://github.com/kubernetes/ingress-nginx/blob/master/Changelog.md#0150).
-
-## Prerequisite
-
-[Prometheus integration](../prometheus.md) must be active.
-
-## Metrics supported
-
-| Name | Query |
-| ---- | ----- |
-| Throughput (req/sec) | `sum(rate(nginx_upstream_responses_total{upstream=~"%{kube_namespace}-%{ci_environment_slug}-.*"}[2m])) by (status_code)` |
-| Latency (ms) | `avg(nginx_upstream_response_msecs_avg{upstream=~"%{kube_namespace}-%{ci_environment_slug}-.*"})` |
-| HTTP Error Rate (%) | `sum(rate(nginx_upstream_responses_total{status_code="5xx", upstream=~"%{kube_namespace}-%{ci_environment_slug}-.*"}[2m])) / sum(rate(nginx_upstream_responses_total{upstream=~"%{kube_namespace}-%{ci_environment_slug}-.*"}[2m])) * 100` |
-
-## Configuring NGINX Ingress monitoring
-
-Version 0.9.0 and above of [NGINX Ingress](https://github.com/kubernetes/ingress-nginx) has built-in support for exporting Prometheus metrics. To enable, a ConfigMap setting must be passed: `enable-vts-status: "true"`. Once enabled, a Prometheus metrics endpoint begins running on port 10254.
-
-Next, the Ingress needs to be annotated for Prometheus monitoring. Two new annotations need to be added:
-
-- `prometheus.io/scrape: "true"`
-- `prometheus.io/port: "10254"`
-
-Managing these settings depends on how NGINX Ingress has been deployed. If you have deployed via the [official Helm chart](https://github.com/kubernetes/ingress-nginx/tree/master/charts/ingress-nginx), metrics can be enabled with `controller.stats.enabled` along with the required annotations. Alternatively it is possible edit the NGINX Ingress YAML directly in the [Kubernetes dashboard](https://github.com/kubernetes/dashboard).
-
-## Specifying the Environment label
-
-To isolate and only display relevant metrics for a given environment, GitLab needs a method to detect which labels are associated. To do this, GitLab searches for metrics with appropriate labels. In this case, the `upstream` label must be of the form `<KUBE_NAMESPACE>-<CI_ENVIRONMENT_SLUG>-*`.
-
-If you have used [Auto Deploy](../../../../topics/autodevops/stages.md#auto-deploy) to deploy your app, this format is used automatically and metrics are detected with no action on your part.
+This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/346541) in GitLab 14.7
+and [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/399231) in 16.0.
diff --git a/doc/user/project/integrations/webhook_events.md b/doc/user/project/integrations/webhook_events.md
index 81b99438446..5585b0bf3e1 100644
--- a/doc/user/project/integrations/webhook_events.md
+++ b/doc/user/project/integrations/webhook_events.md
@@ -1507,6 +1507,7 @@ Payload example:
"deployable_id": 796,
"deployable_url": "http://10.126.0.2:3000/root/test-deployment-webhooks/-/jobs/796",
"environment": "staging",
+ "environment_tier": "staging",
"environment_slug": "staging",
"environment_external_url": "https://staging.example.com",
"project": {
diff --git a/doc/user/project/settings/index.md b/doc/user/project/settings/index.md
index 18030ab0a81..f89c2a1eaaa 100644
--- a/doc/user/project/settings/index.md
+++ b/doc/user/project/settings/index.md
@@ -358,7 +358,7 @@ Configure [alert integrations](../../../operations/incident_management/integrati
#### Alert integration
-Automatically [create](../../../operations/metrics/alerts.md#trigger-actions-from-alerts), [notify on](../../../operations/incident_management/paging.md#email-notifications-for-alerts), and [resolve](../../../operations/incident_management/manage_incidents.md#automatically-close-incidents-via-recovery-alerts) incidents based on GitLab alerts.
+Automatically [create](../../../operations/incident_management/alerts.md#trigger-actions-from-alerts), [notify on](../../../operations/incident_management/paging.md#email-notifications-for-alerts), and [resolve](../../../operations/incident_management/manage_incidents.md#automatically-close-incidents-via-recovery-alerts) incidents based on GitLab alerts.
#### PagerDuty integration
diff --git a/doc/user/shortcuts.md b/doc/user/shortcuts.md
index c0d2b74fd84..89de52c33ea 100644
--- a/doc/user/shortcuts.md
+++ b/doc/user/shortcuts.md
@@ -81,7 +81,6 @@ relatively quickly to work, and they take you to another page in the project.
| <kbd>g</kbd> + <kbd>b</kbd> | Go to the project issue boards list (**Issues > Boards**). |
| <kbd>g</kbd> + <kbd>m</kbd> | Go to the project [merge requests](project/merge_requests/index.md) list (**Merge Requests**). |
| <kbd>g</kbd> + <kbd>j</kbd> | Go to the CI/CD jobs list (**CI/CD > Jobs**). |
-| <kbd>g</kbd> + <kbd>l</kbd> | Go to the project metrics (**Monitor > Metrics**). |
| <kbd>g</kbd> + <kbd>e</kbd> | Go to the project environments (**Deployments > Environments**). |
| <kbd>g</kbd> + <kbd>k</kbd> | Go to the project Kubernetes cluster integration page (**Infrastructure > Kubernetes clusters**). You must have at least [`maintainer` permissions](permissions.md) to access this page. |
| <kbd>g</kbd> + <kbd>s</kbd> | Go to the project snippets list (**Snippets**). |
diff --git a/lib/api/entities/package.rb b/lib/api/entities/package.rb
index 1c22a1a36fa..ab6cc0fcb0a 100644
--- a/lib/api/entities/package.rb
+++ b/lib/api/entities/package.rb
@@ -7,8 +7,6 @@ module API
include ::Routing::PackagesHelper
extend ::API::Entities::EntityHelpers
- EMPTY_PIPELINES = [].freeze
-
expose :id, documentation: { type: 'integer', example: 1 }
expose :name, documentation: { type: 'string', example: '@foo/bar' } do |package|
@@ -46,9 +44,7 @@ module API
expose :tags
expose :pipeline, if: ->(package) { package.original_build_info }, using: Package::Pipeline
- expose :pipelines, if: ->(package) { package.pipelines.present? }, using: Package::Pipeline do |_|
- EMPTY_PIPELINES
- end
+ expose :pipelines, if: ->(package) { package.pipelines.present? }, using: Package::Pipeline
expose :versions, using: ::API::Entities::PackageVersion, unless: ->(_, opts) { opts[:collection] }
diff --git a/lib/api/metrics/dashboard/annotations.rb b/lib/api/metrics/dashboard/annotations.rb
index db667b0291b..6edf4783159 100644
--- a/lib/api/metrics/dashboard/annotations.rb
+++ b/lib/api/metrics/dashboard/annotations.rb
@@ -40,6 +40,8 @@ module API
end
post ':id/metrics_dashboard/annotations' do
+ not_found! if Feature.enabled?(:remove_monitor_metrics)
+
annotations_source_object = annotations_source[:class].find(params[:id])
forbidden! unless can?(current_user, :admin_metrics_dashboard_annotation, annotations_source_object)
diff --git a/lib/api/project_templates.rb b/lib/api/project_templates.rb
index 8ec67988e39..2360a7e6b2a 100644
--- a/lib/api/project_templates.rb
+++ b/lib/api/project_templates.rb
@@ -32,6 +32,8 @@ module API
use :pagination
end
get ':id/templates/:type' do
+ bad_request! if params[:type] == 'metrics_dashboard_ymls' && Feature.enabled?(:remove_monitor_metrics)
+
templates = TemplateFinder.all_template_names(user_project, params[:type]).values.flatten
present paginate(::Kaminari.paginate_array(templates)), with: Entities::TemplatesList
@@ -60,6 +62,8 @@ module API
end
get ':id/templates/:type/:name', requirements: TEMPLATE_NAMES_ENDPOINT_REQUIREMENTS do
+ bad_request! if params[:type] == 'metrics_dashboard_ymls' && Feature.enabled?(:remove_monitor_metrics)
+
begin
template = TemplateFinder.build(
params[:type],
diff --git a/lib/container_registry/gitlab_api_client.rb b/lib/container_registry/gitlab_api_client.rb
index d3c0ec03983..00877bb5a48 100644
--- a/lib/container_registry/gitlab_api_client.rb
+++ b/lib/container_registry/gitlab_api_client.rb
@@ -54,6 +54,33 @@ module ContainerRegistry
end
end
+ def self.each_sub_repositories_with_tag_page(path:, page_size: 100, &block)
+ raise ArgumentError, 'block not given' unless block
+
+ # dummy uri to initialize the loop
+ next_page_uri = URI('')
+ page_count = 0
+
+ with_dummy_client(token_config: { type: :nested_repositories_token, path: path&.downcase }) do |client|
+ while next_page_uri
+ last = Rack::Utils.parse_nested_query(next_page_uri.query)['last']
+ current_page = client.sub_repositories_with_tag(path&.downcase, page_size: page_size, last: last)
+
+ if current_page&.key?(:response_body)
+ yield (current_page[:response_body] || [])
+ next_page_uri = current_page.dig(:pagination, :next, :uri)
+ else
+ # no current page. Break the loop
+ next_page_uri = nil
+ end
+
+ page_count += 1
+
+ raise 'too many pages requested' if page_count >= MAX_REPOSITORIES_PAGE_SIZE
+ end
+ end
+ end
+
# https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs-gitlab/api.md#compliance-check
def supports_gitlab_api?
strong_memoize(:supports_gitlab_api) do
diff --git a/lib/gitlab/data_builder/deployment.rb b/lib/gitlab/data_builder/deployment.rb
index 7055f64937d..b26f9a61ee1 100644
--- a/lib/gitlab/data_builder/deployment.rb
+++ b/lib/gitlab/data_builder/deployment.rb
@@ -35,6 +35,7 @@ module Gitlab
deployable_id: deployment.deployable_id,
deployable_url: deployable_url,
environment: deployment.environment.name,
+ environment_tier: deployment.environment.tier,
environment_slug: deployment.environment.slug,
environment_external_url: deployment.environment.external_url,
project: deployment.project.hook_attrs,
diff --git a/lib/gitlab/database/migrations/instrumentation.rb b/lib/gitlab/database/migrations/instrumentation.rb
index 8c479d7eda2..5f87bc6bbe2 100644
--- a/lib/gitlab/database/migrations/instrumentation.rb
+++ b/lib/gitlab/database/migrations/instrumentation.rb
@@ -29,6 +29,8 @@ module Gitlab
observation.success = true
observation
+ rescue StandardError => error
+ observation.error_message = error.message
ensure
observation.walltime = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start
diff --git a/lib/gitlab/database/migrations/observation.rb b/lib/gitlab/database/migrations/observation.rb
index cd048beac96..1be62496806 100644
--- a/lib/gitlab/database/migrations/observation.rb
+++ b/lib/gitlab/database/migrations/observation.rb
@@ -4,7 +4,7 @@
module Gitlab
module Database
module Migrations
- Observation = Struct.new(:version, :name, :walltime, :success, :total_database_size_change,
+ Observation = Struct.new(:version, :name, :walltime, :success, :total_database_size_change, :error_message,
:meta, :query_statistics, keyword_init: true) do
def to_json(...)
as_json.except('meta').to_json(...)
diff --git a/lib/gitlab/database/schema_validation/inconsistency.rb b/lib/gitlab/database/schema_validation/inconsistency.rb
index c834a6bd693..766f48ef339 100644
--- a/lib/gitlab/database/schema_validation/inconsistency.rb
+++ b/lib/gitlab/database/schema_validation/inconsistency.rb
@@ -18,6 +18,10 @@ module Gitlab
validator_class.name.demodulize.underscore
end
+ def object_type
+ structure_sql_object&.class&.name&.demodulize || database_object&.class&.name&.demodulize
+ end
+
def table_name
structure_sql_object&.table_name || database_object&.table_name
end
@@ -40,10 +44,6 @@ module Gitlab
MSG
end
- private
-
- attr_reader :validator_class, :structure_sql_object, :database_object
-
def structure_sql_statement
return unless structure_sql_object
@@ -55,6 +55,10 @@ module Gitlab
"#{database_object.statement}\n"
end
+
+ private
+
+ attr_reader :validator_class, :structure_sql_object, :database_object
end
end
end
diff --git a/lib/gitlab/database/schema_validation/track_inconsistency.rb b/lib/gitlab/database/schema_validation/track_inconsistency.rb
index c7e946be647..47c3492971c 100644
--- a/lib/gitlab/database/schema_validation/track_inconsistency.rb
+++ b/lib/gitlab/database/schema_validation/track_inconsistency.rb
@@ -37,7 +37,6 @@ module Gitlab
{
title: issue_title,
description: issue_description,
- confidential: true,
issue_type: 'issue',
labels: %w[database database-inconsistency-report]
}
@@ -51,10 +50,32 @@ module Gitlab
<<~MSG
We have detected a new schema inconsistency.
- Table_name: #{inconsistency.table_name}
- Object_name: #{inconsistency.object_name}
- Validator_name: #{inconsistency.type}
- Error_message: #{inconsistency.error_message}
+ **Table name:** #{inconsistency.table_name}\
+ **Object name:** #{inconsistency.object_name}\
+ **Validator name:** #{inconsistency.type}\
+ **Object type:** #{inconsistency.object_type}\
+ **Error message:** #{inconsistency.error_message}
+
+
+ **Structure.sql statement:**
+
+ ```sql
+ #{inconsistency.structure_sql_statement}
+ ```
+
+ **Database statement:**
+
+ ```sql
+ #{inconsistency.database_statement}
+ ```
+
+ **Diff:**
+
+ ```diff
+ #{inconsistency.diff}
+
+ ```
+
For more information, please contact the database team.
MSG
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 9df05bf3889..84729dba6ef 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -11293,9 +11293,15 @@ msgstr ""
msgid "ComplianceFrameworks|Required format: %{codeStart}path/file.y[a]ml@group-name/project-name%{codeEnd}. %{linkStart}See some examples%{linkEnd}."
msgstr ""
+msgid "ComplianceFrameworks|Requires Ultimate subscription"
+msgstr ""
+
msgid "ComplianceFrameworks|Saved changes to compliance framework"
msgstr ""
+msgid "ComplianceFrameworks|Set compliance pipeline configuration for projects that use this framework. %{linkStart}How do I create the configuration?%{linkEnd}"
+msgstr ""
+
msgid "ComplianceFrameworks|Set default"
msgstr ""
@@ -25481,9 +25487,6 @@ msgstr ""
msgid "JobAssistant|Error - Valid value is between 1 second and 1 week"
msgstr ""
-msgid "JobAssistant|Example: %{entrypointPlaceholderExample}, Input format: %{entrypointPlaceholderInput}"
-msgstr ""
-
msgid "JobAssistant|Image"
msgstr ""
@@ -25505,16 +25508,16 @@ msgstr ""
msgid "JobAssistant|Job name"
msgstr ""
-msgid "JobAssistant|Please use \",\" to separate array type fields."
+msgid "JobAssistant|Please enter the parameters."
msgstr ""
-msgid "JobAssistant|Rules"
+msgid "JobAssistant|Please separate array type fields with new lines"
msgstr ""
-msgid "JobAssistant|Script"
+msgid "JobAssistant|Rules"
msgstr ""
-msgid "JobAssistant|Service"
+msgid "JobAssistant|Script"
msgstr ""
msgid "JobAssistant|Service entrypoint (optional)"
@@ -25523,6 +25526,9 @@ msgstr ""
msgid "JobAssistant|Service name (optional)"
msgstr ""
+msgid "JobAssistant|Services"
+msgstr ""
+
msgid "JobAssistant|Stage (optional)"
msgstr ""
@@ -27266,6 +27272,9 @@ msgstr ""
msgid "MattermostService|Fill in the word that works best for your team."
msgstr ""
+msgid "MattermostService|Install"
+msgstr ""
+
msgid "MattermostService|Request URL"
msgstr ""
@@ -36133,6 +36142,9 @@ msgstr ""
msgid "Promotions|Epics let you manage your portfolio of projects more efficiently and with less effort by tracking groups of issues that share a theme, across projects and milestones."
msgstr ""
+msgid "Promotions|Get started with GitLab Mobile DevOps"
+msgstr ""
+
msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition."
msgstr ""
@@ -36178,6 +36190,9 @@ msgstr ""
msgid "Promotions|Set the number of necessary approvals and define a list of approvers needed for every merge request in a project."
msgstr ""
+msgid "Promotions|Ship faster with GitLab Mobile DevOps."
+msgstr ""
+
msgid "Promotions|Start GitLab Ultimate trial"
msgstr ""
@@ -36211,6 +36226,9 @@ msgstr ""
msgid "Promotions|Upgrade your plan to improve repositories."
msgstr ""
+msgid "Promotions|Use GitLab Mobile DevOps to quickly build, sign, and release native and cross-platform mobile apps for Android and iOS using GitLab CI/CD."
+msgstr ""
+
msgid "Promotions|Webhooks allow you to trigger a URL if, for example, new code is pushed or a new issue is created. You can configure webhooks to listen for specific events like pushes, issues or merge requests. Group webhooks will apply to all projects in a group, allowing you to standardize webhook functionality across your entire group."
msgstr ""
@@ -42432,6 +42450,12 @@ msgstr ""
msgid "Someone edited this %{issueType} at the same time you did. The description has been updated and you will need to make your changes again."
msgstr ""
+msgid "Someone edited this %{model_name} at the same time you did. Please check out the %{link_to_model} and make sure your changes will not unintentionally remove theirs."
+msgstr ""
+
+msgid "Someone edited this %{model_name} at the same time you did. Please refresh your browser and make sure your changes will not unintentionally remove theirs."
+msgstr ""
+
msgid "Someone edited this merge request at the same time you did. Please refresh the page to see changes."
msgstr ""
diff --git a/qa/Gemfile b/qa/Gemfile
index a7e42e32be5..e8d3a435766 100644
--- a/qa/Gemfile
+++ b/qa/Gemfile
@@ -6,7 +6,7 @@ gem 'gitlab-qa', '~> 10', '>= 10.3.0', require: 'gitlab/qa'
gem 'gitlab_quality-test_tooling', '~> 0.4.0', require: false
gem 'activesupport', '~> 6.1.7.2' # This should stay in sync with the root's Gemfile
gem 'allure-rspec', '~> 2.20.0'
-gem 'capybara', '~> 3.39.0'
+gem 'capybara', '~> 3.39.1'
gem 'capybara-screenshot', '~> 1.0.26'
gem 'rake', '~> 13', '>= 13.0.6'
gem 'rspec', '~> 3.12'
@@ -18,7 +18,7 @@ gem 'rspec-retry', '~> 0.6.2', require: 'rspec/retry'
gem 'rspec_junit_formatter', '~> 0.6.0'
gem 'faker', '~> 3.2'
gem 'knapsack', '~> 4.0'
-gem 'parallel_tests', '~> 4.2'
+gem 'parallel_tests', '~> 4.2', '>= 4.2.1'
gem 'rotp', '~> 6.2.2'
gem 'parallel', '~> 1.23'
gem 'rainbow', '~> 3.1.1'
@@ -40,7 +40,7 @@ gem 'chemlab', '~> 0.10'
gem 'chemlab-library-www-gitlab-com', '~> 0.1', '>= 0.1.1'
# dependencies for jenkins client
-gem 'nokogiri', '~> 1.14', '>= 1.14.3'
+gem 'nokogiri', '~> 1.14', '>= 1.14.4'
gem 'deprecation_toolkit', '~> 2.0.3', require: false
diff --git a/qa/Gemfile.lock b/qa/Gemfile.lock
index a6d82f117e9..9b2b8acfb87 100644
--- a/qa/Gemfile.lock
+++ b/qa/Gemfile.lock
@@ -29,7 +29,7 @@ GEM
debug_inspector (>= 0.0.1)
builder (3.2.4)
byebug (11.1.3)
- capybara (3.39.0)
+ capybara (3.39.1)
addressable
matrix
mini_mime (>= 0.1.3)
@@ -190,7 +190,7 @@ GEM
multi_json (1.15.0)
multi_xml (0.6.0)
netrc (0.11.0)
- nokogiri (1.14.3)
+ nokogiri (1.14.4)
mini_portile2 (~> 2.8.0)
racc (~> 1.4)
octokit (6.1.1)
@@ -199,7 +199,7 @@ GEM
oj (3.13.23)
os (1.1.4)
parallel (1.23.0)
- parallel_tests (4.2.0)
+ parallel_tests (4.2.1)
parallel
parser (3.1.3.0)
ast (~> 2.4.1)
@@ -317,7 +317,7 @@ DEPENDENCIES
activesupport (~> 6.1.7.2)
airborne (~> 0.3.7)
allure-rspec (~> 2.20.0)
- capybara (~> 3.39.0)
+ capybara (~> 3.39.1)
capybara-screenshot (~> 1.0.26)
chemlab (~> 0.10)
chemlab-library-www-gitlab-com (~> 0.1, >= 0.1.1)
@@ -331,10 +331,10 @@ DEPENDENCIES
gitlab_quality-test_tooling (~> 0.4.0)
influxdb-client (~> 2.9)
knapsack (~> 4.0)
- nokogiri (~> 1.14, >= 1.14.3)
+ nokogiri (~> 1.14, >= 1.14.4)
octokit (~> 6.1.1)
parallel (~> 1.23)
- parallel_tests (~> 4.2)
+ parallel_tests (~> 4.2, >= 4.2.1)
pry-byebug (~> 3.10.1)
rainbow (~> 3.1.1)
rake (~> 13, >= 13.0.6)
@@ -353,4 +353,4 @@ DEPENDENCIES
zeitwerk (~> 2.6, >= 2.6.7)
BUNDLED WITH
- 2.4.12
+ 2.4.13
diff --git a/spec/controllers/groups/milestones_controller_spec.rb b/spec/controllers/groups/milestones_controller_spec.rb
index f4046cb97a0..87030448b30 100644
--- a/spec/controllers/groups/milestones_controller_spec.rb
+++ b/spec/controllers/groups/milestones_controller_spec.rb
@@ -260,6 +260,21 @@ RSpec.describe Groups::MilestonesController do
expect(response).to redirect_to(group_milestone_path(group, milestone.iid))
expect(milestone.title).to eq("title changed")
end
+
+ it "handles ActiveRecord::StaleObjectError" do
+ milestone_params[:title] = "title changed"
+ # Purposely reduce the lock_version to trigger an ActiveRecord::StaleObjectError
+ milestone_params[:lock_version] = milestone.lock_version - 1
+
+ put :update, params: {
+ id: milestone.iid,
+ group_id: group.to_param,
+ milestone: milestone_params
+ }
+
+ expect(response).not_to redirect_to(group_milestone_path(group, milestone.iid))
+ expect(response).to render_template(:edit)
+ end
end
describe "#destroy" do
diff --git a/spec/controllers/projects/milestones_controller_spec.rb b/spec/controllers/projects/milestones_controller_spec.rb
index 28da7eff8fc..e2b73e55145 100644
--- a/spec/controllers/projects/milestones_controller_spec.rb
+++ b/spec/controllers/projects/milestones_controller_spec.rb
@@ -156,6 +156,27 @@ RSpec.describe Projects::MilestonesController do
end
end
+ describe "#update" do
+ let(:milestone_params) do
+ { title: "title changed" }
+ end
+
+ it "handles ActiveRecord::StaleObjectError" do
+ # Purposely reduce the lock_version to trigger an ActiveRecord::StaleObjectError
+ milestone_params[:lock_version] = milestone.lock_version - 1
+
+ put :update, params: {
+ id: milestone.iid,
+ milestone: milestone_params,
+ namespace_id: project.namespace.id,
+ project_id: project.id
+ }
+
+ expect(response).not_to redirect_to(project_milestone_path(project, milestone.iid))
+ expect(response).to render_template(:edit)
+ end
+ end
+
describe "#destroy" do
it "removes milestone" do
expect(issue.milestone_id).to eq(milestone.id)
diff --git a/spec/factories/container_registry/data_repair_detail.rb b/spec/factories/container_registry/data_repair_detail.rb
new file mode 100644
index 00000000000..79467c464db
--- /dev/null
+++ b/spec/factories/container_registry/data_repair_detail.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :container_registry_data_repair_detail, class: 'ContainerRegistry::DataRepairDetail' do
+ project
+ updated_at { 1.hour.ago }
+
+ trait :ongoing do
+ status { :ongoing }
+ end
+
+ trait :completed do
+ status { :completed }
+ end
+
+ trait :failed do
+ status { :failed }
+ end
+ end
+end
diff --git a/spec/features/groups/milestones/milestone_editing_spec.rb b/spec/features/groups/milestones/milestone_editing_spec.rb
new file mode 100644
index 00000000000..b3c7cfe88af
--- /dev/null
+++ b/spec/features/groups/milestones/milestone_editing_spec.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe "Milestone editing", feature_category: :team_planning do
+ let_it_be(:group) { create(:group, owner: user) }
+ let_it_be(:user) { create(:group_member, :maintainer, user: create(:user), group: group).user }
+
+ let(:milestone) { create(:milestone, group: group, title: "12345676543") }
+
+ before do
+ sign_in(user)
+
+ visit(edit_group_milestone_path(group, milestone))
+ end
+
+ it_behaves_like 'milestone handling version conflicts'
+end
diff --git a/spec/features/issues/user_edits_issue_spec.rb b/spec/features/issues/user_edits_issue_spec.rb
index c1cf8fada26..bc20660d2a0 100644
--- a/spec/features/issues/user_edits_issue_spec.rb
+++ b/spec/features/issues/user_edits_issue_spec.rb
@@ -54,7 +54,7 @@ RSpec.describe "Issues > User edits issue", :js, feature_category: :team_plannin
first('.js-user-search').click
click_link 'Unassigned'
- click_button 'Save changes'
+ click_button _('Save changes')
page.within('.assignee') do
expect(page).to have_content 'None - assign yourself'
@@ -79,7 +79,7 @@ RSpec.describe "Issues > User edits issue", :js, feature_category: :team_plannin
expect(find('#issuable-due-date').value).to eq date.to_s
- click_button 'Save changes'
+ click_button _('Save changes')
page.within '.issuable-sidebar' do
expect(page).to have_content date.to_s(:medium)
@@ -92,9 +92,15 @@ RSpec.describe "Issues > User edits issue", :js, feature_category: :team_plannin
fill_in 'issue_title', with: 'bug 345'
fill_in 'issue_description', with: 'bug description'
- click_button 'Save changes'
+ click_button _('Save changes')
- expect(page).to have_content 'Someone edited the issue the same time you did'
+ expect(page).to have_content(
+ format(
+ _("Someone edited this %{model_name} at the same time you did. Please check out the %{link_to_model} and make sure your changes will not unintentionally remove theirs."), # rubocop:disable Layout/LineLength
+ model_name: _('issue'),
+ link_to_model: _('issue')
+ )
+ )
end
end
end
diff --git a/spec/features/merge_request/user_edits_mr_spec.rb b/spec/features/merge_request/user_edits_mr_spec.rb
index 114fa5b6ecb..76588832ee1 100644
--- a/spec/features/merge_request/user_edits_mr_spec.rb
+++ b/spec/features/merge_request/user_edits_mr_spec.rb
@@ -90,9 +90,15 @@ RSpec.describe 'Merge request > User edits MR', feature_category: :code_review_w
fill_in 'merge_request_title', with: 'bug 345'
fill_in 'merge_request_description', with: 'bug description'
- click_button 'Save changes'
-
- expect(page).to have_content 'Someone edited the merge request the same time you did'
+ click_button _('Save changes')
+
+ expect(page).to have_content(
+ format(
+ _("Someone edited this %{model_name} at the same time you did. Please check out the %{link_to_model} and make sure your changes will not unintentionally remove theirs."), # rubocop:disable Layout/LineLength
+ model_name: _('merge request'),
+ link_to_model: _('merge request')
+ )
+ )
end
it 'preserves description textarea height', :js do
diff --git a/spec/features/projects/blobs/blob_show_spec.rb b/spec/features/projects/blobs/blob_show_spec.rb
index 74e5dc9f8c3..cd1dde55e30 100644
--- a/spec/features/projects/blobs/blob_show_spec.rb
+++ b/spec/features/projects/blobs/blob_show_spec.rb
@@ -580,7 +580,11 @@ RSpec.describe 'File blob', :js, feature_category: :projects do
end
describe '.gitlab/dashboards/custom-dashboard.yml' do
+ let(:remove_monitor_metrics) { false }
+
before do
+ stub_feature_flags(remove_monitor_metrics: remove_monitor_metrics)
+
project.add_maintainer(project.creator)
Files::CreateService.new(
@@ -608,6 +612,15 @@ RSpec.describe 'File blob', :js, feature_category: :projects do
expect(page).to have_link('Learn more')
end
end
+
+ context 'when metrics dashboard feature is unavailable' do
+ let(:remove_monitor_metrics) { true }
+
+ it 'displays the blob without an auxiliary viewer' do
+ expect(page).to have_content('Environment metrics')
+ expect(page).not_to have_content('Metrics Dashboard YAML definition', wait: 0)
+ end
+ end
end
context 'invalid dashboard file' do
diff --git a/spec/features/projects/integrations/user_activates_mattermost_slash_command_spec.rb b/spec/features/projects/integrations/user_activates_mattermost_slash_command_spec.rb
index c2370f38faa..aea76944c7f 100644
--- a/spec/features/projects/integrations/user_activates_mattermost_slash_command_spec.rb
+++ b/spec/features/projects/integrations/user_activates_mattermost_slash_command_spec.rb
@@ -99,7 +99,7 @@ RSpec.describe 'Set up Mattermost slash commands', :js, feature_category: :integ
click_link 'Add to Mattermost'
- expect(find('input[type="submit"]')['disabled']).not_to eq("true")
+ expect(find('button[type="submit"]')['disabled']).not_to eq("true")
end
it 'disables the submit button if the required fields are not provided', :js do
@@ -109,7 +109,7 @@ RSpec.describe 'Set up Mattermost slash commands', :js, feature_category: :integ
fill_in('mattermost_trigger', with: '')
- expect(find('input[type="submit"]')['disabled']).to eq("true")
+ expect(find('button[type="submit"]')['disabled']).to eq("true")
end
def stub_teams(count: 0)
diff --git a/spec/features/projects/milestones/milestone_editing_spec.rb b/spec/features/projects/milestones/milestone_editing_spec.rb
new file mode 100644
index 00000000000..8a03683eb35
--- /dev/null
+++ b/spec/features/projects/milestones/milestone_editing_spec.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe "Milestone editing", :js, feature_category: :team_planning do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project, name: 'test', namespace: user.namespace) }
+
+ let(:milestone) { create(:milestone, project: project, start_date: Date.today, due_date: 5.days.from_now) }
+
+ before do
+ sign_in(user)
+
+ visit(edit_project_milestone_path(project, milestone))
+ end
+
+ it_behaves_like 'milestone handling version conflicts'
+end
diff --git a/spec/finders/template_finder_spec.rb b/spec/finders/template_finder_spec.rb
index 21fea7863ff..c466f533a61 100644
--- a/spec/finders/template_finder_spec.rb
+++ b/spec/finders/template_finder_spec.rb
@@ -103,6 +103,10 @@ RSpec.describe TemplateFinder do
describe '#build' do
let(:project) { build_stubbed(:project) }
+ before do
+ stub_feature_flags(remove_monitor_metrics: false)
+ end
+
where(:type, :expected_class) do
:dockerfiles | described_class
:gitignores | described_class
@@ -119,6 +123,16 @@ RSpec.describe TemplateFinder do
it { is_expected.to be_a(expected_class) }
it { expect(finder.project).to eq(project) }
end
+
+ context 'when metrics dashboard is unavailable' do
+ before do
+ stub_feature_flags(remove_monitor_metrics: true)
+ end
+
+ subject(:finder) { described_class.build(:metrics_dashboard_ymls, project) }
+
+ it { is_expected.to be_nil }
+ end
end
describe '#execute' do
diff --git a/spec/frontend/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/image_item_spec.js b/spec/frontend/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/image_item_spec.js
index c7c40c3a4b9..f99d7277612 100644
--- a/spec/frontend/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/image_item_spec.js
+++ b/spec/frontend/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/image_item_spec.js
@@ -8,8 +8,8 @@ describe('Image item', () => {
const findImageNameInput = () => wrapper.findByTestId('image-name-input');
const findImageEntrypointInput = () => wrapper.findByTestId('image-entrypoint-input');
- const dummyImageName = 'dummyImageName';
- const dummyImageEntrypoint = 'dummyImageEntrypoint';
+ const dummyImageName = 'a';
+ const dummyImageEntrypoint = ['b', 'c'];
const createComponent = ({ job = JSON.parse(JSON.stringify(JOB_TEMPLATE)) } = {}) => {
wrapper = shallowMountExtended(ImageItem, {
@@ -31,9 +31,9 @@ describe('Image item', () => {
expect(wrapper.emitted('update-job')).toHaveLength(1);
expect(wrapper.emitted('update-job')[0]).toEqual(['image.name', dummyImageName]);
- findImageEntrypointInput().vm.$emit('input', dummyImageEntrypoint);
+ findImageEntrypointInput().vm.$emit('input', dummyImageEntrypoint.join('\n'));
expect(wrapper.emitted('update-job')).toHaveLength(2);
- expect(wrapper.emitted('update-job')[1]).toEqual(['image.entrypoint', [dummyImageEntrypoint]]);
+ expect(wrapper.emitted('update-job')[1]).toEqual(['image.entrypoint', dummyImageEntrypoint]);
});
});
diff --git a/spec/frontend/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/services_item_spec.js b/spec/frontend/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/services_item_spec.js
index 07b3526f5fa..284d639c77f 100644
--- a/spec/frontend/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/services_item_spec.js
+++ b/spec/frontend/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/services_item_spec.js
@@ -34,7 +34,7 @@ describe('Services item', () => {
expect(wrapper.emitted('update-job')).toHaveLength(1);
expect(wrapper.emitted('update-job')[0]).toEqual(['services[0].name', dummyServiceName]);
- findServiceEntrypointInputByIndex(0).vm.$emit('input', dummyServiceEntrypoint.join(','));
+ findServiceEntrypointInputByIndex(0).vm.$emit('input', dummyServiceEntrypoint.join('\n'));
expect(wrapper.emitted('update-job')).toHaveLength(2);
expect(wrapper.emitted('update-job')[1]).toEqual([
diff --git a/spec/graphql/resolvers/metrics/dashboards/annotation_resolver_spec.rb b/spec/graphql/resolvers/metrics/dashboards/annotation_resolver_spec.rb
index a83cef40bdf..2ca194d519c 100644
--- a/spec/graphql/resolvers/metrics/dashboards/annotation_resolver_spec.rb
+++ b/spec/graphql/resolvers/metrics/dashboards/annotation_resolver_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Resolvers::Metrics::Dashboards::AnnotationResolver do
+RSpec.describe Resolvers::Metrics::Dashboards::AnnotationResolver, feature_category: :metrics do
include GraphqlHelpers
describe '#resolve' do
@@ -25,6 +25,10 @@ RSpec.describe Resolvers::Metrics::Dashboards::AnnotationResolver do
environment.project.add_developer(current_user)
end
+ before do
+ stub_feature_flags(remove_monitor_metrics: false)
+ end
+
context 'with annotation records' do
let_it_be(:annotation_1) { create(:metrics_dashboard_annotation, environment: environment, starting_at: 9.minutes.ago, dashboard_path: path) }
@@ -55,6 +59,16 @@ RSpec.describe Resolvers::Metrics::Dashboards::AnnotationResolver do
expect(resolve_annotations).to be_empty
end
end
+
+ context 'when metrics dashboard feature is unavailable' do
+ before do
+ stub_feature_flags(remove_monitor_metrics: true)
+ end
+
+ it 'returns nothing' do
+ expect(resolve_annotations).to be_nil
+ end
+ end
end
end
end
diff --git a/spec/graphql/types/permission_types/issue_spec.rb b/spec/graphql/types/permission_types/issue_spec.rb
index 58c5808cbcc..8f43a4a44a0 100644
--- a/spec/graphql/types/permission_types/issue_spec.rb
+++ b/spec/graphql/types/permission_types/issue_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe Types::PermissionTypes::Issue do
expected_permissions = [
:read_issue, :admin_issue, :update_issue, :reopen_issue,
:read_design, :create_design, :destroy_design,
- :create_note
+ :create_note, :update_design
]
expected_permissions.each do |permission|
diff --git a/spec/graphql/types/project_statistics_redirect_type_spec.rb b/spec/graphql/types/project_statistics_redirect_type_spec.rb
new file mode 100644
index 00000000000..3600a5b932f
--- /dev/null
+++ b/spec/graphql/types/project_statistics_redirect_type_spec.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['ProjectStatisticsRedirect'], feature_category: :consumables_cost_management do
+ it 'has all the required fields' do
+ expect(described_class).to have_graphql_fields(:repository, :build_artifacts, :packages,
+ :wiki, :snippets, :container_registry)
+ end
+end
diff --git a/spec/graphql/types/project_type_spec.rb b/spec/graphql/types/project_type_spec.rb
index 0f980241db3..bcfdb05ca90 100644
--- a/spec/graphql/types/project_type_spec.rb
+++ b/spec/graphql/types/project_type_spec.rb
@@ -24,7 +24,7 @@ RSpec.describe GitlabSchema.types['Project'] do
snippets_enabled jobs_enabled public_jobs open_issues_count import_status
only_allow_merge_if_pipeline_succeeds request_access_enabled
only_allow_merge_if_all_discussions_are_resolved printing_merge_request_link_enabled
- namespace group statistics repository merge_requests merge_request issues
+ namespace group statistics statistics_details_paths repository merge_requests merge_request issues
issue milestones pipelines removeSourceBranchAfterMerge pipeline_counts sentryDetailedError snippets
grafanaIntegration autocloseReferencedIssues suggestion_commit_message environments
environment boards jira_import_status jira_imports services releases release
diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb
index f7cbe8c816b..3eb1090c9dc 100644
--- a/spec/helpers/projects_helper_spec.rb
+++ b/spec/helpers/projects_helper_spec.rb
@@ -777,6 +777,34 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do
end
end
+ describe '#show_mobile_devops_project_promo?' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:hide_cookie, :feature_flag_enabled, :mobile_target_platform, :result) do
+ false | true | true | true
+ false | false | true | false
+ false | false | false | false
+ false | true | false | false
+ true | false | false | false
+ true | true | false | false
+ true | true | true | false
+ true | false | true | false
+ end
+
+ with_them do
+ before do
+ allow(Gitlab).to receive(:com?) { gitlab_com }
+ Feature.enable(:mobile_devops_projects_promo, feature_flag_enabled)
+ project.project_setting.target_platforms << 'ios' if mobile_target_platform
+ helper.request.cookies["hide_mobile_devops_promo_#{project.id}"] = true if hide_cookie
+ end
+
+ it 'resolves if the user can import members' do
+ expect(helper.show_mobile_devops_project_promo?(project)).to eq result
+ end
+ end
+ end
+
describe '#can_admin_project_member?' do
context 'when user is project owner' do
before do
diff --git a/spec/lib/api/entities/package_spec.rb b/spec/lib/api/entities/package_spec.rb
index 53d9a0b4557..9288f6fe8eb 100644
--- a/spec/lib/api/entities/package_spec.rb
+++ b/spec/lib/api/entities/package_spec.rb
@@ -40,13 +40,4 @@ RSpec.describe API::Entities::Package do
expect(subject[:_links]).not_to have_key(:web_path)
end
end
-
- context 'with build info' do
- let_it_be(:project) { create(:project) }
- let_it_be(:package) { create(:npm_package, :with_build, project: project) }
-
- it 'returns an empty array for pipelines' do
- expect(subject[:pipelines]).to eq([])
- end
- end
end
diff --git a/spec/lib/container_registry/gitlab_api_client_spec.rb b/spec/lib/container_registry/gitlab_api_client_spec.rb
index ac15048e4b5..c70dd265073 100644
--- a/spec/lib/container_registry/gitlab_api_client_spec.rb
+++ b/spec/lib/container_registry/gitlab_api_client_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe ContainerRegistry::GitlabApiClient do
+RSpec.describe ContainerRegistry::GitlabApiClient, feature_category: :container_registry do
using RSpec::Parameterized::TableSyntax
include_context 'container registry client'
@@ -615,6 +615,159 @@ RSpec.describe ContainerRegistry::GitlabApiClient do
end
end
+ describe '#each_sub_repositories_with_tag_page' do
+ let(:page_size) { 100 }
+ let(:project_path) { 'repo/project' }
+
+ shared_examples 'iterating through a page' do |expected_tags: true|
+ it 'iterates through one page' do
+ expect_next_instance_of(described_class) do |client|
+ expect(client).to receive(:sub_repositories_with_tag).with(project_path, page_size: page_size, last: nil).and_return(client_response)
+ end
+
+ expect { |b| described_class.each_sub_repositories_with_tag_page(path: project_path, page_size: page_size, &b) }
+ .to yield_with_args(expected_tags ? client_response_repositories : [])
+ end
+ end
+
+ context 'when no block is given' do
+ it 'raises an Argument error' do
+ expect do
+ described_class.each_sub_repositories_with_tag_page(path: project_path, page_size: page_size)
+ end.to raise_error(ArgumentError, 'block not given')
+ end
+ end
+
+ context 'when a block is given' do
+ before do
+ expect(Auth::ContainerRegistryAuthenticationService).to receive(:pull_nested_repositories_access_token).with(project_path).and_return(token)
+ stub_container_registry_config(enabled: true, api_url: registry_api_url, key: 'spec/fixtures/x509_certificate_pk.key')
+ end
+
+ context 'with an empty page' do
+ let(:client_response) { { pagination: {}, response_body: [] } }
+
+ it_behaves_like 'iterating through a page', expected_tags: false
+ end
+
+ context 'with one page' do
+ let(:client_response) { { pagination: {}, response_body: client_response_repositories } }
+ let(:client_response_repositories) do
+ [
+ {
+ "name": "docker-alpine",
+ "path": "gitlab-org/build/cng/docker-alpine",
+ "created_at": "2022-06-07T12:11:13.633+00:00",
+ "updated_at": "2022-06-07T14:37:49.251+00:00"
+ },
+ {
+ "name": "git-base",
+ "path": "gitlab-org/build/cng/git-base",
+ "created_at": "2022-06-07T12:11:13.633+00:00",
+ "updated_at": "2022-06-07T14:37:49.251+00:00"
+ }
+ ]
+ end
+
+ it_behaves_like 'iterating through a page'
+ end
+
+ context 'with two pages' do
+ let(:client_response1) { { pagination: { next: { uri: URI('http://localhost/next?last=latest') } }, response_body: client_response_repositories1 } }
+ let(:client_response_repositories1) do
+ [
+ {
+ "name": "docker-alpine",
+ "path": "gitlab-org/build/cng/docker-alpine",
+ "created_at": "2022-06-07T12:11:13.633+00:00",
+ "updated_at": "2022-06-07T14:37:49.251+00:00"
+ },
+ {
+ "name": "git-base",
+ "path": "gitlab-org/build/cng/git-base",
+ "created_at": "2022-06-07T12:11:13.633+00:00",
+ "updated_at": "2022-06-07T14:37:49.251+00:00"
+ }
+ ]
+ end
+
+ let(:client_response2) { { pagination: {}, response_body: client_response_repositories2 } }
+ let(:client_response_repositories2) do
+ [
+ {
+ "name": "docker-alpine1",
+ "path": "gitlab-org/build/cng/docker-alpine",
+ "created_at": "2022-06-07T12:11:13.633+00:00",
+ "updated_at": "2022-06-07T14:37:49.251+00:00"
+ },
+ {
+ "name": "git-base1",
+ "path": "gitlab-org/build/cng/git-base",
+ "created_at": "2022-06-07T12:11:13.633+00:00",
+ "updated_at": "2022-06-07T14:37:49.251+00:00"
+ }
+ ]
+ end
+
+ it 'iterates through two pages' do
+ expect_next_instance_of(described_class) do |client|
+ expect(client).to receive(:sub_repositories_with_tag).with(project_path, page_size: page_size, last: nil).and_return(client_response1)
+ expect(client).to receive(:sub_repositories_with_tag).with(project_path, page_size: page_size, last: 'latest').and_return(client_response2)
+ end
+
+ expect { |b| described_class.each_sub_repositories_with_tag_page(path: project_path, page_size: page_size, &b) }
+ .to yield_successive_args(client_response_repositories1, client_response_repositories2)
+ end
+ end
+
+ context 'when max pages is reached' do
+ let(:client_response) { { pagination: {}, response_body: [] } }
+
+ before do
+ stub_const('ContainerRegistry::GitlabApiClient::MAX_REPOSITORIES_PAGE_SIZE', 0)
+ expect_next_instance_of(described_class) do |client|
+ expect(client).to receive(:sub_repositories_with_tag).with(project_path, page_size: page_size, last: nil).and_return(client_response)
+ end
+ end
+
+ it 'raises an error' do
+ expect { described_class.each_sub_repositories_with_tag_page(path: project_path, page_size: page_size) {} } # rubocop:disable Lint/EmptyBlock
+ .to raise_error(StandardError, 'too many pages requested')
+ end
+ end
+
+ context 'without a page size set' do
+ let(:client_response) { { pagination: {}, response_body: [] } }
+
+ it 'uses a default size' do
+ expect_next_instance_of(described_class) do |client|
+ expect(client).to receive(:sub_repositories_with_tag).with(project_path, page_size: page_size, last: nil).and_return(client_response)
+ end
+
+ expect { |b| described_class.each_sub_repositories_with_tag_page(path: project_path, &b) }.to yield_with_args([])
+ end
+ end
+
+ context 'with an empty client response' do
+ let(:client_response) { {} }
+
+ it 'breaks the loop' do
+ expect_next_instance_of(described_class) do |client|
+ expect(client).to receive(:sub_repositories_with_tag).with(project_path, page_size: page_size, last: nil).and_return(client_response)
+ end
+
+ expect { |b| described_class.each_sub_repositories_with_tag_page(path: project_path, page_size: page_size, &b) }.not_to yield_control
+ end
+ end
+
+ context 'with a nil page' do
+ let(:client_response) { { pagination: {}, response_body: nil } }
+
+ it_behaves_like 'iterating through a page', expected_tags: false
+ end
+ end
+ end
+
def stub_pre_import(path, status_code, pre:)
import_type = pre ? 'pre' : 'final'
stub_request(:put, "#{registry_api_url}/gitlab/v1/import/#{path}/?import_type=#{import_type}")
diff --git a/spec/lib/gitlab/background_migration/backfill_cluster_agents_has_vulnerabilities_spec.rb b/spec/lib/gitlab/background_migration/backfill_cluster_agents_has_vulnerabilities_spec.rb
index 3aab0cdf54b..edb6ff59340 100644
--- a/spec/lib/gitlab/background_migration/backfill_cluster_agents_has_vulnerabilities_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_cluster_agents_has_vulnerabilities_spec.rb
@@ -4,10 +4,12 @@ require 'spec_helper'
RSpec.describe Gitlab::BackgroundMigration::BackfillClusterAgentsHasVulnerabilities, :migration do # rubocop:disable Layout/LineLength
let(:migration) do
- described_class.new(start_id: 1, end_id: 10,
- batch_table: table_name, batch_column: batch_column,
- sub_batch_size: sub_batch_size, pause_ms: pause_ms,
- connection: ApplicationRecord.connection)
+ described_class.new(
+ start_id: 1, end_id: 10,
+ batch_table: table_name, batch_column: batch_column,
+ sub_batch_size: sub_batch_size, pause_ms: pause_ms,
+ connection: ApplicationRecord.connection
+ )
end
let(:users_table) { table(:users) }
diff --git a/spec/lib/gitlab/background_migration/backfill_environment_tiers_spec.rb b/spec/lib/gitlab/background_migration/backfill_environment_tiers_spec.rb
index 788ed40b61e..9026c327e3c 100644
--- a/spec/lib/gitlab/background_migration/backfill_environment_tiers_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_environment_tiers_spec.rb
@@ -8,10 +8,12 @@ RSpec.describe Gitlab::BackgroundMigration::BackfillEnvironmentTiers,
let!(:project) { table(:projects).create!(namespace_id: namespace.id, project_namespace_id: namespace.id) }
let(:migration) do
- described_class.new(start_id: 1, end_id: 1000,
- batch_table: :environments, batch_column: :id,
- sub_batch_size: 10, pause_ms: 0,
- connection: ApplicationRecord.connection)
+ described_class.new(
+ start_id: 1, end_id: 1000,
+ batch_table: :environments, batch_column: :id,
+ sub_batch_size: 10, pause_ms: 0,
+ connection: ApplicationRecord.connection
+ )
end
describe '#perform' do
diff --git a/spec/lib/gitlab/background_migration/backfill_group_features_spec.rb b/spec/lib/gitlab/background_migration/backfill_group_features_spec.rb
index e0be5a785b8..023d4b04e63 100644
--- a/spec/lib/gitlab/background_migration/backfill_group_features_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_group_features_spec.rb
@@ -7,14 +7,16 @@ RSpec.describe Gitlab::BackgroundMigration::BackfillGroupFeatures, :migration, s
let(:namespaces) { table(:namespaces) }
subject do
- described_class.new(start_id: 1,
- end_id: 4,
- batch_table: :namespaces,
- batch_column: :id,
- sub_batch_size: 10,
- pause_ms: 0,
- job_arguments: [4],
- connection: ActiveRecord::Base.connection)
+ described_class.new(
+ start_id: 1,
+ end_id: 4,
+ batch_table: :namespaces,
+ batch_column: :id,
+ sub_batch_size: 10,
+ pause_ms: 0,
+ job_arguments: [4],
+ connection: ActiveRecord::Base.connection
+ )
end
describe '#perform' do
diff --git a/spec/lib/gitlab/background_migration/backfill_imported_issue_search_data_spec.rb b/spec/lib/gitlab/background_migration/backfill_imported_issue_search_data_spec.rb
index 479afb56210..b3f04055e0a 100644
--- a/spec/lib/gitlab/background_migration/backfill_imported_issue_search_data_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_imported_issue_search_data_spec.rb
@@ -30,13 +30,15 @@ RSpec.describe Gitlab::BackgroundMigration::BackfillImportedIssueSearchData,
end
let(:migration) do
- described_class.new(start_id: issue.id,
- end_id: issue.id + 30,
- batch_table: :issues,
- batch_column: :id,
- sub_batch_size: 2,
- pause_ms: 0,
- connection: ApplicationRecord.connection)
+ described_class.new(
+ start_id: issue.id,
+ end_id: issue.id + 30,
+ batch_table: :issues,
+ batch_column: :id,
+ sub_batch_size: 2,
+ pause_ms: 0,
+ connection: ApplicationRecord.connection
+ )
end
let(:perform_migration) { migration.perform }
diff --git a/spec/lib/gitlab/background_migration/backfill_namespace_details_spec.rb b/spec/lib/gitlab/background_migration/backfill_namespace_details_spec.rb
index b6282de0da6..39ad60fb13b 100644
--- a/spec/lib/gitlab/background_migration/backfill_namespace_details_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_namespace_details_spec.rb
@@ -7,27 +7,36 @@ RSpec.describe Gitlab::BackgroundMigration::BackfillNamespaceDetails, :migration
let(:namespace_details) { table(:namespace_details) }
subject(:perform_migration) do
- described_class.new(start_id: namespaces.minimum(:id),
- end_id: namespaces.maximum(:id),
- batch_table: :namespaces,
- batch_column: :id,
- sub_batch_size: 2,
- pause_ms: 0,
- connection: ActiveRecord::Base.connection)
- .perform
+ described_class.new(
+ start_id: namespaces.minimum(:id),
+ end_id: namespaces.maximum(:id),
+ batch_table: :namespaces,
+ batch_column: :id,
+ sub_batch_size: 2,
+ pause_ms: 0,
+ connection: ActiveRecord::Base.connection
+ ).perform
end
describe '#perform' do
it 'creates details for all namespaces in range' do
- namespace1 = namespaces.create!(id: 5, name: 'test1', path: 'test1', description: "Some description1",
- description_html: "Some description html1", cached_markdown_version: 4)
- namespaces.create!(id: 6, name: 'test2', path: 'test2', type: 'Project',
- description: "Some description2", description_html: "Some description html2",
- cached_markdown_version: 4)
- namespace3 = namespaces.create!(id: 7, name: 'test3', path: 'test3', description: "Some description3",
- description_html: "Some description html3", cached_markdown_version: 4)
- namespace4 = namespaces.create!(id: 8, name: 'test4', path: 'test4', description: "Some description3",
- description_html: "Some description html4", cached_markdown_version: 4)
+ namespace1 = namespaces.create!(
+ id: 5, name: 'test1', path: 'test1', description: "Some description1",
+ description_html: "Some description html1", cached_markdown_version: 4
+ )
+ namespaces.create!(
+ id: 6, name: 'test2', path: 'test2', type: 'Project',
+ description: "Some description2", description_html: "Some description html2",
+ cached_markdown_version: 4
+ )
+ namespace3 = namespaces.create!(
+ id: 7, name: 'test3', path: 'test3', description: "Some description3",
+ description_html: "Some description html3", cached_markdown_version: 4
+ )
+ namespace4 = namespaces.create!(
+ id: 8, name: 'test4', path: 'test4', description: "Some description3",
+ description_html: "Some description html4", cached_markdown_version: 4
+ )
namespace_details.delete_all
expect(namespace_details.pluck(:namespace_id)).to eql []
diff --git a/spec/lib/gitlab/background_migration/backfill_namespace_id_for_namespace_route_spec.rb b/spec/lib/gitlab/background_migration/backfill_namespace_id_for_namespace_route_spec.rb
index b821efcadb0..3a8a327550b 100644
--- a/spec/lib/gitlab/background_migration/backfill_namespace_id_for_namespace_route_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_namespace_id_for_namespace_route_spec.rb
@@ -22,18 +22,29 @@ RSpec.describe Gitlab::BackgroundMigration::BackfillNamespaceIdForNamespaceRoute
subject(:perform_migration) { migration.perform(1, 10, table_name, batch_column, sub_batch_size, pause_ms) }
before do
- routes_table.create!(id: 1, name: 'test1', path: 'test1', source_id: namespace1.id,
- source_type: namespace1.class.sti_name)
- routes_table.create!(id: 2, name: 'test2', path: 'test2', source_id: namespace2.id,
- source_type: namespace2.class.sti_name)
- routes_table.create!(id: 5, name: 'test3', path: 'test3', source_id: project1.id,
- source_type: project1.class.sti_name) # should be ignored - project route
- routes_table.create!(id: 6, name: 'test4', path: 'test4', source_id: non_existing_record_id,
- source_type: namespace3.class.sti_name) # should be ignored - invalid source_id
- routes_table.create!(id: 10, name: 'test5', path: 'test5', source_id: namespace3.id,
- source_type: namespace3.class.sti_name)
- routes_table.create!(id: 11, name: 'test6', path: 'test6', source_id: namespace4.id,
- source_type: namespace4.class.sti_name) # should be ignored - outside the scope
+ routes_table.create!(
+ id: 1, name: 'test1', path: 'test1', source_id: namespace1.id, source_type: namespace1.class.sti_name
+ )
+
+ routes_table.create!(
+ id: 2, name: 'test2', path: 'test2', source_id: namespace2.id, source_type: namespace2.class.sti_name
+ )
+
+ routes_table.create!(
+ id: 5, name: 'test3', path: 'test3', source_id: project1.id, source_type: project1.class.sti_name
+ ) # should be ignored - project route
+
+ routes_table.create!(
+ id: 6, name: 'test4', path: 'test4', source_id: non_existing_record_id, source_type: namespace3.class.sti_name
+ ) # should be ignored - invalid source_id
+
+ routes_table.create!(
+ id: 10, name: 'test5', path: 'test5', source_id: namespace3.id, source_type: namespace3.class.sti_name
+ )
+
+ routes_table.create!(
+ id: 11, name: 'test6', path: 'test6', source_id: namespace4.id, source_type: namespace4.class.sti_name
+ ) # should be ignored - outside the scope
end
it 'backfills `type` for the selected records', :aggregate_failures do
diff --git a/spec/lib/gitlab/background_migration/backfill_namespace_id_of_vulnerability_reads_spec.rb b/spec/lib/gitlab/background_migration/backfill_namespace_id_of_vulnerability_reads_spec.rb
index 564aa3b8c01..6a55c6951d5 100644
--- a/spec/lib/gitlab/background_migration/backfill_namespace_id_of_vulnerability_reads_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_namespace_id_of_vulnerability_reads_spec.rb
@@ -38,14 +38,15 @@ RSpec.describe Gitlab::BackgroundMigration::BackfillNamespaceIdOfVulnerabilityRe
end
subject(:perform_migration) do
- described_class.new(start_id: vulnerability_read.vulnerability_id,
- end_id: vulnerability_read.vulnerability_id,
- batch_table: :vulnerability_reads,
- batch_column: :vulnerability_id,
- sub_batch_size: 1,
- pause_ms: 0,
- connection: ActiveRecord::Base.connection)
- .perform
+ described_class.new(
+ start_id: vulnerability_read.vulnerability_id,
+ end_id: vulnerability_read.vulnerability_id,
+ batch_table: :vulnerability_reads,
+ batch_column: :vulnerability_id,
+ sub_batch_size: 1,
+ pause_ms: 0,
+ connection: ActiveRecord::Base.connection
+ ).perform
end
it 'sets the namespace_id of existing record' do
diff --git a/spec/lib/gitlab/background_migration/backfill_project_feature_package_registry_access_level_spec.rb b/spec/lib/gitlab/background_migration/backfill_project_feature_package_registry_access_level_spec.rb
index fd6c055b9f6..47ff2883fb2 100644
--- a/spec/lib/gitlab/background_migration/backfill_project_feature_package_registry_access_level_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_project_feature_package_registry_access_level_spec.rb
@@ -101,14 +101,15 @@ RSpec.describe Gitlab::BackgroundMigration::BackfillProjectFeaturePackageRegistr
end
subject(:perform_migration) do
- described_class.new(start_id: project1.id,
- end_id: project5.id,
- batch_table: :projects,
- batch_column: :id,
- sub_batch_size: 2,
- pause_ms: 0,
- connection: ActiveRecord::Base.connection)
- .perform
+ described_class.new(
+ start_id: project1.id,
+ end_id: project5.id,
+ batch_table: :projects,
+ batch_column: :id,
+ sub_batch_size: 2,
+ pause_ms: 0,
+ connection: ActiveRecord::Base.connection
+ ).perform
end
it 'backfills project_features.package_registry_access_level', :aggregate_failures do
diff --git a/spec/lib/gitlab/background_migration/backfill_project_member_namespace_id_spec.rb b/spec/lib/gitlab/background_migration/backfill_project_member_namespace_id_spec.rb
index ca7ca41a33e..96f49624d22 100644
--- a/spec/lib/gitlab/background_migration/backfill_project_member_namespace_id_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_project_member_namespace_id_spec.rb
@@ -4,10 +4,12 @@ require 'spec_helper'
RSpec.describe Gitlab::BackgroundMigration::BackfillProjectMemberNamespaceId, :migration, schema: 20220516054011 do
let(:migration) do
- described_class.new(start_id: 1, end_id: 10,
- batch_table: table_name, batch_column: batch_column,
- sub_batch_size: sub_batch_size, pause_ms: pause_ms,
- connection: ApplicationRecord.connection)
+ described_class.new(
+ start_id: 1, end_id: 10,
+ batch_table: table_name, batch_column: batch_column,
+ sub_batch_size: sub_batch_size, pause_ms: pause_ms,
+ connection: ApplicationRecord.connection
+ )
end
let(:members_table) { table(:members) }
@@ -35,37 +37,55 @@ RSpec.describe Gitlab::BackgroundMigration::BackfillProjectMemberNamespaceId, :m
projects_table.create!(id: 102, name: 'project3', path: 'project3', namespace_id: 202, project_namespace_id: 302)
# project1, no member namespace (fill in)
- members_table.create!(id: 1, source_id: 100,
- source_type: 'Project', type: 'ProjectMember',
- member_namespace_id: nil, access_level: 10, notification_level: 3)
+ members_table.create!(
+ id: 1, source_id: 100,
+ source_type: 'Project', type: 'ProjectMember',
+ member_namespace_id: nil, access_level: 10, notification_level: 3
+ )
+
# bogus source id, no member namespace id (do nothing)
- members_table.create!(id: 2, source_id: non_existing_record_id,
- source_type: 'Project', type: 'ProjectMember',
- member_namespace_id: nil, access_level: 10, notification_level: 3)
+ members_table.create!(
+ id: 2, source_id: non_existing_record_id,
+ source_type: 'Project', type: 'ProjectMember',
+ member_namespace_id: nil, access_level: 10, notification_level: 3
+ )
+
# project3, existing member namespace id (do nothing)
- members_table.create!(id: 3, source_id: 102,
- source_type: 'Project', type: 'ProjectMember',
- member_namespace_id: 300, access_level: 10, notification_level: 3)
+ members_table.create!(
+ id: 3, source_id: 102,
+ source_type: 'Project', type: 'ProjectMember',
+ member_namespace_id: 300, access_level: 10, notification_level: 3
+ )
# Group memberships (do not change)
# group1, no member namespace (do nothing)
- members_table.create!(id: 4, source_id: 201,
- source_type: 'Namespace', type: 'GroupMember',
- member_namespace_id: nil, access_level: 10, notification_level: 3)
+ members_table.create!(
+ id: 4, source_id: 201,
+ source_type: 'Namespace', type: 'GroupMember',
+ member_namespace_id: nil, access_level: 10, notification_level: 3
+ )
+
# group2, existing member namespace (do nothing)
- members_table.create!(id: 5, source_id: 202,
- source_type: 'Namespace', type: 'GroupMember',
- member_namespace_id: 201, access_level: 10, notification_level: 3)
+ members_table.create!(
+ id: 5, source_id: 202,
+ source_type: 'Namespace', type: 'GroupMember',
+ member_namespace_id: 201, access_level: 10, notification_level: 3
+ )
# Project Namespace memberships (do not change)
# project namespace, existing member namespace (do nothing)
- members_table.create!(id: 6, source_id: 300,
- source_type: 'Namespace', type: 'ProjectNamespaceMember',
- member_namespace_id: 201, access_level: 10, notification_level: 3)
+ members_table.create!(
+ id: 6, source_id: 300,
+ source_type: 'Namespace', type: 'ProjectNamespaceMember',
+ member_namespace_id: 201, access_level: 10, notification_level: 3
+ )
+
# project namespace, not member namespace (do nothing)
- members_table.create!(id: 7, source_id: 301,
- source_type: 'Namespace', type: 'ProjectNamespaceMember',
- member_namespace_id: 201, access_level: 10, notification_level: 3)
+ members_table.create!(
+ id: 7, source_id: 301,
+ source_type: 'Namespace', type: 'ProjectNamespaceMember',
+ member_namespace_id: 201, access_level: 10, notification_level: 3
+ )
end
it 'backfills `member_namespace_id` for the selected records', :aggregate_failures do
diff --git a/spec/lib/gitlab/background_migration/backfill_project_namespace_details_spec.rb b/spec/lib/gitlab/background_migration/backfill_project_namespace_details_spec.rb
index 01daf16d10c..aac17a426b5 100644
--- a/spec/lib/gitlab/background_migration/backfill_project_namespace_details_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_project_namespace_details_spec.rb
@@ -8,32 +8,41 @@ RSpec.describe Gitlab::BackgroundMigration::BackfillProjectNamespaceDetails, :mi
let!(:projects) { table(:projects) }
subject(:perform_migration) do
- described_class.new(start_id: projects.minimum(:id),
- end_id: projects.maximum(:id),
- batch_table: :projects,
- batch_column: :id,
- sub_batch_size: 2,
- pause_ms: 0,
- connection: ActiveRecord::Base.connection)
- .perform
+ described_class.new(
+ start_id: projects.minimum(:id),
+ end_id: projects.maximum(:id),
+ batch_table: :projects,
+ batch_column: :id,
+ sub_batch_size: 2,
+ pause_ms: 0,
+ connection: ActiveRecord::Base.connection
+ ).perform
end
describe '#perform' do
it 'creates details for all project namespaces in range' do
- namespaces.create!(id: 5, name: 'test1', path: 'test1', description: "Some description1",
- description_html: "Some description html1", cached_markdown_version: 4)
+ namespaces.create!(
+ id: 5, name: 'test1', path: 'test1', description: "Some description1",
+ description_html: "Some description html1", cached_markdown_version: 4
+ )
project_namespace1 = namespaces.create!(id: 6, name: 'test2', path: 'test2', type: 'Project')
- namespaces.create!(id: 7, name: 'test3', path: 'test3', description: "Some description3",
- description_html: "Some description html3", cached_markdown_version: 4)
+ namespaces.create!(
+ id: 7, name: 'test3', path: 'test3', description: "Some description3",
+ description_html: "Some description html3", cached_markdown_version: 4
+ )
project_namespace2 = namespaces.create!(id: 8, name: 'test4', path: 'test4', type: 'Project')
- project1 = projects.create!(namespace_id: project_namespace1.id, name: 'gitlab1', path: 'gitlab1',
- project_namespace_id: project_namespace1.id, description: "Some description2",
- description_html: "Some description html2", cached_markdown_version: 4)
- project2 = projects.create!(namespace_id: project_namespace2.id, name: 'gitlab2', path: 'gitlab2',
- project_namespace_id: project_namespace2.id,
- description: "Some description3",
- description_html: "Some description html4", cached_markdown_version: 4)
+ project1 = projects.create!(
+ namespace_id: project_namespace1.id, name: 'gitlab1', path: 'gitlab1',
+ project_namespace_id: project_namespace1.id, description: "Some description2",
+ description_html: "Some description html2", cached_markdown_version: 4
+ )
+ project2 = projects.create!(
+ namespace_id: project_namespace2.id, name: 'gitlab2', path: 'gitlab2',
+ project_namespace_id: project_namespace2.id,
+ description: "Some description3",
+ description_html: "Some description html4", cached_markdown_version: 4
+ )
namespace_details.delete_all
diff --git a/spec/lib/gitlab/background_migration/backfill_releases_author_id_spec.rb b/spec/lib/gitlab/background_migration/backfill_releases_author_id_spec.rb
index d8ad10849f2..898f241a930 100644
--- a/spec/lib/gitlab/background_migration/backfill_releases_author_id_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_releases_author_id_spec.rb
@@ -10,35 +10,52 @@ RSpec.describe Gitlab::BackgroundMigration::BackfillReleasesAuthorId,
let!(:test_user) { user_table.create!(name: 'test', email: 'test@example.com', username: 'test', projects_limit: 10) }
let!(:ghost_user) do
- user_table.create!(name: 'ghost', email: 'ghost@example.com',
- username: 'ghost', user_type: User::USER_TYPES['ghost'], projects_limit: 100000)
+ user_table.create!(
+ name: 'ghost', email: 'ghost@example.com',
+ username: 'ghost', user_type: User::USER_TYPES['ghost'], projects_limit: 100000
+ )
end
let(:migration) do
- described_class.new(start_id: 1, end_id: 100,
- batch_table: :releases, batch_column: :id,
- sub_batch_size: 10, pause_ms: 0,
- job_arguments: [ghost_user.id],
- connection: ApplicationRecord.connection)
+ described_class.new(
+ start_id: 1, end_id: 100,
+ batch_table: :releases, batch_column: :id,
+ sub_batch_size: 10, pause_ms: 0,
+ job_arguments: [ghost_user.id],
+ connection: ApplicationRecord.connection
+ )
end
subject(:perform_migration) { migration.perform }
before do
- releases_table.create!(tag: 'tag1', name: 'tag1',
- released_at: (date_time - 1.minute), author_id: test_user.id)
- releases_table.create!(tag: 'tag2', name: 'tag2',
- released_at: (date_time - 2.minutes), author_id: test_user.id)
- releases_table.new(tag: 'tag3', name: 'tag3',
- released_at: (date_time - 3.minutes), author_id: nil).save!(validate: false)
- releases_table.new(tag: 'tag4', name: 'tag4',
- released_at: (date_time - 4.minutes), author_id: nil).save!(validate: false)
- releases_table.new(tag: 'tag5', name: 'tag5',
- released_at: (date_time - 5.minutes), author_id: nil).save!(validate: false)
- releases_table.create!(tag: 'tag6', name: 'tag6',
- released_at: (date_time - 6.minutes), author_id: test_user.id)
- releases_table.new(tag: 'tag7', name: 'tag7',
- released_at: (date_time - 7.minutes), author_id: nil).save!(validate: false)
+ releases_table.create!(
+ tag: 'tag1', name: 'tag1', released_at: (date_time - 1.minute), author_id: test_user.id
+ )
+
+ releases_table.create!(
+ tag: 'tag2', name: 'tag2', released_at: (date_time - 2.minutes), author_id: test_user.id
+ )
+
+ releases_table.new(
+ tag: 'tag3', name: 'tag3', released_at: (date_time - 3.minutes), author_id: nil
+ ).save!(validate: false)
+
+ releases_table.new(
+ tag: 'tag4', name: 'tag4', released_at: (date_time - 4.minutes), author_id: nil
+ ).save!(validate: false)
+
+ releases_table.new(
+ tag: 'tag5', name: 'tag5', released_at: (date_time - 5.minutes), author_id: nil
+ ).save!(validate: false)
+
+ releases_table.create!(
+ tag: 'tag6', name: 'tag6', released_at: (date_time - 6.minutes), author_id: test_user.id
+ )
+
+ releases_table.new(
+ tag: 'tag7', name: 'tag7', released_at: (date_time - 7.minutes), author_id: nil
+ ).save!(validate: false)
end
it 'backfills `author_id` for the selected records', :aggregate_failures do
diff --git a/spec/lib/gitlab/background_migration/backfill_snippet_repositories_spec.rb b/spec/lib/gitlab/background_migration/backfill_snippet_repositories_spec.rb
index 4a50d08b2aa..d8874cb811b 100644
--- a/spec/lib/gitlab/background_migration/backfill_snippet_repositories_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_snippet_repositories_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Gitlab::BackgroundMigration::BackfillSnippetRepositories, :migration, schema: 20211202041233,
-feature_category: :source_code_management do
+ feature_category: :source_code_management do
let(:gitlab_shell) { Gitlab::Shell.new }
let(:users) { table(:users) }
let(:snippets) { table(:snippets) }
@@ -14,24 +14,28 @@ feature_category: :source_code_management do
let(:user_name) { 'Test' }
let!(:user) do
- users.create!(id: 1,
- email: 'user@example.com',
- projects_limit: 10,
- username: 'test',
- name: user_name,
- state: user_state,
- last_activity_on: 1.minute.ago,
- user_type: user_type,
- confirmed_at: 1.day.ago)
+ users.create!(
+ id: 1,
+ email: 'user@example.com',
+ projects_limit: 10,
+ username: 'test',
+ name: user_name,
+ state: user_state,
+ last_activity_on: 1.minute.ago,
+ user_type: user_type,
+ confirmed_at: 1.day.ago
+ )
end
let!(:migration_bot) do
- users.create!(id: 100,
- email: "noreply+gitlab-migration-bot%s@#{Settings.gitlab.host}",
- user_type: HasUserType::USER_TYPES[:migration_bot],
- name: 'GitLab Migration Bot',
- projects_limit: 10,
- username: 'bot')
+ users.create!(
+ id: 100,
+ email: "noreply+gitlab-migration-bot%s@#{Settings.gitlab.host}",
+ user_type: HasUserType::USER_TYPES[:migration_bot],
+ name: 'GitLab Migration Bot',
+ projects_limit: 10,
+ username: 'bot'
+ )
end
let!(:snippet_with_repo) { snippets.create!(id: 1, type: 'PersonalSnippet', author_id: user.id, file_name: file_name, content: content) }
@@ -260,15 +264,17 @@ feature_category: :source_code_management do
context 'when both user name and snippet file_name are invalid' do
let(:user_name) { '.' }
let!(:other_user) do
- users.create!(id: 2,
- email: 'user2@example.com',
- projects_limit: 10,
- username: 'test2',
- name: 'Test2',
- state: user_state,
- last_activity_on: 1.minute.ago,
- user_type: user_type,
- confirmed_at: 1.day.ago)
+ users.create!(
+ id: 2,
+ email: 'user2@example.com',
+ projects_limit: 10,
+ username: 'test2',
+ name: 'Test2',
+ state: user_state,
+ last_activity_on: 1.minute.ago,
+ user_type: user_type,
+ confirmed_at: 1.day.ago
+ )
end
let!(:invalid_snippet) { snippets.create!(id: 4, type: 'PersonalSnippet', author_id: user.id, file_name: '.', content: content) }
@@ -322,10 +328,12 @@ feature_category: :source_code_management do
end
def raw_repository(snippet)
- Gitlab::Git::Repository.new('default',
- "#{disk_path(snippet)}.git",
- Gitlab::GlRepository::SNIPPET.identifier_for_container(snippet),
- "@snippets/#{snippet.id}")
+ Gitlab::Git::Repository.new(
+ 'default',
+ "#{disk_path(snippet)}.git",
+ Gitlab::GlRepository::SNIPPET.identifier_for_container(snippet),
+ "@snippets/#{snippet.id}"
+ )
end
def hashed_repository(snippet)
diff --git a/spec/lib/gitlab/background_migration/backfill_vulnerability_reads_cluster_agent_spec.rb b/spec/lib/gitlab/background_migration/backfill_vulnerability_reads_cluster_agent_spec.rb
index f642ec8c20d..3f1a57434a7 100644
--- a/spec/lib/gitlab/background_migration/backfill_vulnerability_reads_cluster_agent_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_vulnerability_reads_cluster_agent_spec.rb
@@ -4,10 +4,12 @@ require 'spec_helper'
RSpec.describe Gitlab::BackgroundMigration::BackfillVulnerabilityReadsClusterAgent, :migration, schema: 20220525221133 do # rubocop:disable Layout/LineLength
let(:migration) do
- described_class.new(start_id: 1, end_id: 10,
- batch_table: table_name, batch_column: batch_column,
- sub_batch_size: sub_batch_size, pause_ms: pause_ms,
- connection: ApplicationRecord.connection)
+ described_class.new(
+ start_id: 1, end_id: 10,
+ batch_table: table_name, batch_column: batch_column,
+ sub_batch_size: sub_batch_size, pause_ms: pause_ms,
+ connection: ApplicationRecord.connection
+ )
end
let(:users_table) { table(:users) }
diff --git a/spec/lib/gitlab/background_migration/nullify_orphan_runner_id_on_ci_builds_spec.rb b/spec/lib/gitlab/background_migration/nullify_orphan_runner_id_on_ci_builds_spec.rb
index 2f0eef3c399..5b234679e22 100644
--- a/spec/lib/gitlab/background_migration/nullify_orphan_runner_id_on_ci_builds_spec.rb
+++ b/spec/lib/gitlab/background_migration/nullify_orphan_runner_id_on_ci_builds_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Gitlab::BackgroundMigration::NullifyOrphanRunnerIdOnCiBuilds,
- :suppress_gitlab_schemas_validate_connection, migration: :gitlab_ci, schema: 20220223112304 do
+ :suppress_gitlab_schemas_validate_connection, migration: :gitlab_ci, schema: 20220223112304 do
let(:namespaces) { table(:namespaces) }
let(:projects) { table(:projects) }
let(:ci_runners) { table(:ci_runners) }
diff --git a/spec/lib/gitlab/background_migration/prune_stale_project_export_jobs_spec.rb b/spec/lib/gitlab/background_migration/prune_stale_project_export_jobs_spec.rb
index 5150d0ea4b0..3446b9f0676 100644
--- a/spec/lib/gitlab/background_migration/prune_stale_project_export_jobs_spec.rb
+++ b/spec/lib/gitlab/background_migration/prune_stale_project_export_jobs_spec.rb
@@ -10,14 +10,15 @@ RSpec.describe Gitlab::BackgroundMigration::PruneStaleProjectExportJobs, feature
let(:uploads) { table(:project_relation_export_uploads) }
subject(:perform_migration) do
- described_class.new(start_id: 1,
- end_id: 300,
- batch_table: :project_export_jobs,
- batch_column: :id,
- sub_batch_size: 2,
- pause_ms: 0,
- connection: ActiveRecord::Base.connection)
- .perform
+ described_class.new(
+ start_id: 1,
+ end_id: 300,
+ batch_table: :project_export_jobs,
+ batch_column: :id,
+ sub_batch_size: 2,
+ pause_ms: 0,
+ connection: ActiveRecord::Base.connection
+ ).perform
end
it 'removes export jobs and associated relations older than 7 days' do
diff --git a/spec/lib/gitlab/background_migration/remove_backfilled_job_artifacts_expire_at_spec.rb b/spec/lib/gitlab/background_migration/remove_backfilled_job_artifacts_expire_at_spec.rb
index 5fede892463..582c0fe1b1b 100644
--- a/spec/lib/gitlab/background_migration/remove_backfilled_job_artifacts_expire_at_spec.rb
+++ b/spec/lib/gitlab/background_migration/remove_backfilled_job_artifacts_expire_at_spec.rb
@@ -86,8 +86,10 @@ RSpec.describe Gitlab::BackgroundMigration::RemoveBackfilledJobArtifactsExpireAt
def create_job_artifact(id:, file_type:, expire_at:)
job = table(:ci_builds, database: :ci).create!(id: id, partition_id: 100)
- job_artifact.create!(id: id, job_id: job.id, expire_at: expire_at, project_id: project.id,
- file_type: file_type, partition_id: 100)
+ job_artifact.create!(
+ id: id, job_id: job.id, expire_at: expire_at, project_id: project.id,
+ file_type: file_type, partition_id: 100
+ )
end
end
end
diff --git a/spec/lib/gitlab/background_migration/remove_occurrence_pipelines_and_duplicate_vulnerabilities_findings_spec.rb b/spec/lib/gitlab/background_migration/remove_occurrence_pipelines_and_duplicate_vulnerabilities_findings_spec.rb
index 1844347f4a9..60ee61cf50a 100644
--- a/spec/lib/gitlab/background_migration/remove_occurrence_pipelines_and_duplicate_vulnerabilities_findings_spec.rb
+++ b/spec/lib/gitlab/background_migration/remove_occurrence_pipelines_and_duplicate_vulnerabilities_findings_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe Gitlab::BackgroundMigration::RemoveOccurrencePipelinesAndDuplicateVulnerabilitiesFindings, :migration,
- :suppress_gitlab_schemas_validate_connection, schema: 20220326161803 do
+ :suppress_gitlab_schemas_validate_connection, schema: 20220326161803 do
let(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
let(:users) { table(:users) }
let(:user) { create_user! }
diff --git a/spec/lib/gitlab/background_migration/remove_self_managed_wiki_notes_spec.rb b/spec/lib/gitlab/background_migration/remove_self_managed_wiki_notes_spec.rb
index 81927100562..59d5d56ebe8 100644
--- a/spec/lib/gitlab/background_migration/remove_self_managed_wiki_notes_spec.rb
+++ b/spec/lib/gitlab/background_migration/remove_self_managed_wiki_notes_spec.rb
@@ -6,14 +6,15 @@ RSpec.describe Gitlab::BackgroundMigration::RemoveSelfManagedWikiNotes, :migrati
let(:notes) { table(:notes) }
subject(:perform_migration) do
- described_class.new(start_id: 1,
- end_id: 30,
- batch_table: :notes,
- batch_column: :id,
- sub_batch_size: 2,
- pause_ms: 0,
- connection: ActiveRecord::Base.connection)
- .perform
+ described_class.new(
+ start_id: 1,
+ end_id: 30,
+ batch_table: :notes,
+ batch_column: :id,
+ sub_batch_size: 2,
+ pause_ms: 0,
+ connection: ActiveRecord::Base.connection
+ ).perform
end
it 'removes all wiki notes' do
diff --git a/spec/lib/gitlab/background_migration/reset_too_many_tags_skipped_registry_imports_spec.rb b/spec/lib/gitlab/background_migration/reset_too_many_tags_skipped_registry_imports_spec.rb
index 3f59b0a24a3..afdd855c5a8 100644
--- a/spec/lib/gitlab/background_migration/reset_too_many_tags_skipped_registry_imports_spec.rb
+++ b/spec/lib/gitlab/background_migration/reset_too_many_tags_skipped_registry_imports_spec.rb
@@ -3,8 +3,8 @@
require 'spec_helper'
RSpec.describe Gitlab::BackgroundMigration::ResetTooManyTagsSkippedRegistryImports, :migration,
- :aggregate_failures,
- schema: 20220502173045 do
+ :aggregate_failures,
+ schema: 20220502173045 do
let(:namespaces) { table(:namespaces) }
let(:projects) { table(:projects) }
let(:container_repositories) { table(:container_repositories) }
@@ -15,46 +15,54 @@ RSpec.describe Gitlab::BackgroundMigration::ResetTooManyTagsSkippedRegistryImpor
let!(:project) { projects.create!(id: 1, project_namespace_id: 1, namespace_id: 1, path: 'bar', name: 'bar') }
let!(:container_repository1) do
- container_repositories.create!(id: 1,
- project_id: 1,
- name: 'a',
- migration_state: 'import_skipped',
- migration_skipped_at: Time.zone.now,
- migration_skipped_reason: 2,
- migration_pre_import_started_at: Time.zone.now,
- migration_pre_import_done_at: Time.zone.now,
- migration_import_started_at: Time.zone.now,
- migration_import_done_at: Time.zone.now,
- migration_aborted_at: Time.zone.now,
- migration_retries_count: 2,
- migration_aborted_in_state: 'importing')
+ container_repositories.create!(
+ id: 1,
+ project_id: 1,
+ name: 'a',
+ migration_state: 'import_skipped',
+ migration_skipped_at: Time.zone.now,
+ migration_skipped_reason: 2,
+ migration_pre_import_started_at: Time.zone.now,
+ migration_pre_import_done_at: Time.zone.now,
+ migration_import_started_at: Time.zone.now,
+ migration_import_done_at: Time.zone.now,
+ migration_aborted_at: Time.zone.now,
+ migration_retries_count: 2,
+ migration_aborted_in_state: 'importing'
+ )
end
let!(:container_repository2) do
- container_repositories.create!(id: 2,
- project_id: 1,
- name: 'b',
- migration_state: 'import_skipped',
- migration_skipped_at: Time.zone.now,
- migration_skipped_reason: 2)
+ container_repositories.create!(
+ id: 2,
+ project_id: 1,
+ name: 'b',
+ migration_state: 'import_skipped',
+ migration_skipped_at: Time.zone.now,
+ migration_skipped_reason: 2
+ )
end
let!(:container_repository3) do
- container_repositories.create!(id: 3,
- project_id: 1,
- name: 'c',
- migration_state: 'import_skipped',
- migration_skipped_at: Time.zone.now,
- migration_skipped_reason: 1)
+ container_repositories.create!(
+ id: 3,
+ project_id: 1,
+ name: 'c',
+ migration_state: 'import_skipped',
+ migration_skipped_at: Time.zone.now,
+ migration_skipped_reason: 1
+ )
end
# This is an unlikely state, but included here to test the edge case
let!(:container_repository4) do
- container_repositories.create!(id: 4,
- project_id: 1,
- name: 'd',
- migration_state: 'default',
- migration_skipped_reason: 2)
+ container_repositories.create!(
+ id: 4,
+ project_id: 1,
+ name: 'd',
+ migration_state: 'default',
+ migration_skipped_reason: 2
+ )
end
describe '#up' do
diff --git a/spec/lib/gitlab/background_migration/set_correct_vulnerability_state_spec.rb b/spec/lib/gitlab/background_migration/set_correct_vulnerability_state_spec.rb
index 2372ce21c4c..df1ee494987 100644
--- a/spec/lib/gitlab/background_migration/set_correct_vulnerability_state_spec.rb
+++ b/spec/lib/gitlab/background_migration/set_correct_vulnerability_state_spec.rb
@@ -35,13 +35,15 @@ RSpec.describe Gitlab::BackgroundMigration::SetCorrectVulnerabilityState do
let(:dismissed_state) { 2 }
let(:migration_job) do
- described_class.new(start_id: vulnerability_with_dismissed_at.id,
- end_id: vulnerability_without_dismissed_at.id,
- batch_table: :vulnerabilities,
- batch_column: :id,
- sub_batch_size: 1,
- pause_ms: 0,
- connection: ActiveRecord::Base.connection)
+ described_class.new(
+ start_id: vulnerability_with_dismissed_at.id,
+ end_id: vulnerability_without_dismissed_at.id,
+ batch_table: :vulnerabilities,
+ batch_column: :id,
+ sub_batch_size: 1,
+ pause_ms: 0,
+ connection: ActiveRecord::Base.connection
+ )
end
describe '#filter_batch' do
diff --git a/spec/lib/gitlab/background_migration/set_legacy_open_source_license_available_for_non_public_projects_spec.rb b/spec/lib/gitlab/background_migration/set_legacy_open_source_license_available_for_non_public_projects_spec.rb
index e9f73672144..5109c3ec0c2 100644
--- a/spec/lib/gitlab/background_migration/set_legacy_open_source_license_available_for_non_public_projects_spec.rb
+++ b/spec/lib/gitlab/background_migration/set_legacy_open_source_license_available_for_non_public_projects_spec.rb
@@ -3,21 +3,22 @@
require 'spec_helper'
RSpec.describe Gitlab::BackgroundMigration::SetLegacyOpenSourceLicenseAvailableForNonPublicProjects,
- :migration,
- schema: 20220722110026 do
+ :migration,
+ schema: 20220722110026 do
let(:namespaces_table) { table(:namespaces) }
let(:projects_table) { table(:projects) }
let(:project_settings_table) { table(:project_settings) }
subject(:perform_migration) do
- described_class.new(start_id: projects_table.minimum(:id),
- end_id: projects_table.maximum(:id),
- batch_table: :projects,
- batch_column: :id,
- sub_batch_size: 2,
- pause_ms: 0,
- connection: ActiveRecord::Base.connection)
- .perform
+ described_class.new(
+ start_id: projects_table.minimum(:id),
+ end_id: projects_table.maximum(:id),
+ batch_table: :projects,
+ batch_column: :id,
+ sub_batch_size: 2,
+ pause_ms: 0,
+ connection: ActiveRecord::Base.connection
+ ).perform
end
it 'sets `legacy_open_source_license_available` attribute to false for non-public projects', :aggregate_failures do
@@ -37,11 +38,13 @@ RSpec.describe Gitlab::BackgroundMigration::SetLegacyOpenSourceLicenseAvailableF
def create_legacy_license_project(path, visibility_level:)
namespace = namespaces_table.create!(name: "namespace-#{path}", path: "namespace-#{path}")
project_namespace = namespaces_table.create!(name: "project-namespace-#{path}", path: path, type: 'Project')
- project = projects_table.create!(name: path,
- path: path,
- namespace_id: namespace.id,
- project_namespace_id: project_namespace.id,
- visibility_level: visibility_level)
+ project = projects_table.create!(
+ name: path,
+ path: path,
+ namespace_id: namespace.id,
+ project_namespace_id: project_namespace.id,
+ visibility_level: visibility_level
+ )
project_settings_table.create!(project_id: project.id, legacy_open_source_license_available: true)
project
diff --git a/spec/lib/gitlab/background_migration/update_delayed_project_removal_to_null_for_user_namespaces_spec.rb b/spec/lib/gitlab/background_migration/update_delayed_project_removal_to_null_for_user_namespaces_spec.rb
index 980a7771f4c..0579a299c74 100644
--- a/spec/lib/gitlab/background_migration/update_delayed_project_removal_to_null_for_user_namespaces_spec.rb
+++ b/spec/lib/gitlab/background_migration/update_delayed_project_removal_to_null_for_user_namespaces_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Gitlab::BackgroundMigration::UpdateDelayedProjectRemovalToNullForUserNamespaces,
- :migration do
+ :migration do
let(:namespaces_table) { table(:namespaces) }
let(:namespace_settings_table) { table(:namespace_settings) }
diff --git a/spec/lib/gitlab/background_migration/update_jira_tracker_data_deployment_type_based_on_url_spec.rb b/spec/lib/gitlab/background_migration/update_jira_tracker_data_deployment_type_based_on_url_spec.rb
index c090c1df424..75fe5699986 100644
--- a/spec/lib/gitlab/background_migration/update_jira_tracker_data_deployment_type_based_on_url_spec.rb
+++ b/spec/lib/gitlab/background_migration/update_jira_tracker_data_deployment_type_based_on_url_spec.rb
@@ -13,10 +13,12 @@ RSpec.describe Gitlab::BackgroundMigration::UpdateJiraTrackerDataDeploymentTypeB
let(:sub_batch_size) { 1 }
let(:pause_ms) { 0 }
let(:migration) do
- described_class.new(start_id: 1, end_id: 10,
- batch_table: table_name, batch_column: batch_column,
- sub_batch_size: sub_batch_size, pause_ms: pause_ms,
- connection: ApplicationRecord.connection)
+ described_class.new(
+ start_id: 1, end_id: 10,
+ batch_table: table_name, batch_column: batch_column,
+ sub_batch_size: sub_batch_size, pause_ms: pause_ms,
+ connection: ApplicationRecord.connection
+ )
end
subject(:perform_migration) do
diff --git a/spec/lib/gitlab/data_builder/deployment_spec.rb b/spec/lib/gitlab/data_builder/deployment_spec.rb
index bf08e782035..82ec3e791a4 100644
--- a/spec/lib/gitlab/data_builder/deployment_spec.rb
+++ b/spec/lib/gitlab/data_builder/deployment_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::DataBuilder::Deployment do
+RSpec.describe Gitlab::DataBuilder::Deployment, feature_category: :continuous_delivery do
describe '.build' do
it 'returns the object kind for a deployment' do
deployment = build(:deployment, deployable: nil, environment: create(:environment))
@@ -40,6 +40,7 @@ RSpec.describe Gitlab::DataBuilder::Deployment do
expect(data[:commit_url]).to eq(expected_commit_url)
expect(data[:commit_title]).to eq(commit.title)
expect(data[:ref]).to eq(deployment.ref)
+ expect(data[:environment_tier]).to eq('other')
end
it 'does not include the deployable URL when there is no deployable' do
diff --git a/spec/lib/gitlab/database/migrations/instrumentation_spec.rb b/spec/lib/gitlab/database/migrations/instrumentation_spec.rb
index 4f347034c0b..0b25389c667 100644
--- a/spec/lib/gitlab/database/migrations/instrumentation_spec.rb
+++ b/spec/lib/gitlab/database/migrations/instrumentation_spec.rb
@@ -18,7 +18,9 @@ RSpec.describe Gitlab::Database::Migrations::Instrumentation do
let(:migration_name) { 'test' }
let(:migration_version) { '12345' }
let(:migration_meta) { { 'max_batch_size' => 1, 'total_tuple_count' => 10, 'interval' => 60 } }
- let(:expected_json_keys) { %w[version name walltime success total_database_size_change query_statistics] }
+ let(:expected_json_keys) do
+ %w[version name walltime success total_database_size_change query_statistics error_message]
+ end
it 'executes the given block' do
expect do |b|
@@ -90,16 +92,14 @@ RSpec.describe Gitlab::Database::Migrations::Instrumentation do
end
context 'upon failure' do
- where(exception: ['something went wrong', SystemStackError, Interrupt])
+ where(:exception, :error_message) do
+ [[StandardError, 'something went wrong'], [ActiveRecord::StatementTimeout, 'timeout']]
+ end
with_them do
subject(:observe) do
instrumentation.observe(version: migration_version, name: migration_name,
- connection: connection, meta: migration_meta) { raise exception }
- end
-
- it 'raises the exception' do
- expect { observe }.to raise_error(exception)
+ connection: connection, meta: migration_meta) { raise exception, error_message }
end
context 'retrieving observations' do
@@ -107,10 +107,6 @@ RSpec.describe Gitlab::Database::Migrations::Instrumentation do
before do
observe
- # rubocop:disable Lint/RescueException
- rescue Exception
- # rubocop:enable Lint/RescueException
- # ignore (we expect this exception)
end
it 'records a valid observation', :aggregate_failures do
@@ -118,6 +114,7 @@ RSpec.describe Gitlab::Database::Migrations::Instrumentation do
expect(subject['success']).to be_falsey
expect(subject['version']).to eq(migration_version)
expect(subject['name']).to eq(migration_name)
+ expect(subject['error_message']).to eq(error_message)
end
it 'transforms observation to expected json' do
diff --git a/spec/lib/gitlab/database/schema_validation/inconsistency_spec.rb b/spec/lib/gitlab/database/schema_validation/inconsistency_spec.rb
index cb3df75b3fb..a49ff8339a1 100644
--- a/spec/lib/gitlab/database/schema_validation/inconsistency_spec.rb
+++ b/spec/lib/gitlab/database/schema_validation/inconsistency_spec.rb
@@ -50,6 +50,32 @@ RSpec.describe Gitlab::Database::SchemaValidation::Inconsistency, feature_catego
end
end
+ describe '#object_type' do
+ it 'returns the structure sql object type' do
+ expect(inconsistency.object_type).to eq('Index')
+ end
+
+ context 'when the structure sql object is not available' do
+ subject(:inconsistency) { described_class.new(validator, nil, database_object) }
+
+ it 'returns the database object type' do
+ expect(inconsistency.object_type).to eq('Index')
+ end
+ end
+ end
+
+ describe '#structure_sql_statement' do
+ it 'returns structure sql statement' do
+ expect(inconsistency.structure_sql_statement).to eq("#{structure_sql_statement}\n")
+ end
+ end
+
+ describe '#database_statement' do
+ it 'returns database statement' do
+ expect(inconsistency.database_statement).to eq("#{database_statement}\n")
+ end
+ end
+
describe '#inspect' do
let(:expected_output) do
<<~MSG
diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml
index 8a2602ea9f6..34f9948b9dc 100644
--- a/spec/lib/gitlab/import_export/all_models.yml
+++ b/spec/lib/gitlab/import_export/all_models.yml
@@ -647,6 +647,7 @@ project:
- redirect_routes
- statistics
- container_repositories
+- container_registry_data_repair_detail
- uploads
- file_uploads
- import_state
diff --git a/spec/models/blob_viewer/metrics_dashboard_yml_spec.rb b/spec/models/blob_viewer/metrics_dashboard_yml_spec.rb
index d28fa0bbe97..c9ac13eefc0 100644
--- a/spec/models/blob_viewer/metrics_dashboard_yml_spec.rb
+++ b/spec/models/blob_viewer/metrics_dashboard_yml_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe BlobViewer::MetricsDashboardYml do
+RSpec.describe BlobViewer::MetricsDashboardYml, feature_category: :metrics do
include FakeBlobHelpers
include RepoHelpers
@@ -119,4 +119,18 @@ RSpec.describe BlobViewer::MetricsDashboardYml do
expect(viewer.errors).to eq ["YAML syntax: The parsed YAML is too big"]
end
end
+
+ describe '.can_render?' do
+ subject { described_class.can_render?(blob) }
+
+ it { is_expected.to be false }
+
+ context 'when metrics dashboard feature is available' do
+ before do
+ stub_feature_flags(remove_monitor_metrics: false)
+ end
+
+ it { is_expected.to be true }
+ end
+ end
end
diff --git a/spec/models/commit_spec.rb b/spec/models/commit_spec.rb
index df630d6336c..edb856d34df 100644
--- a/spec/models/commit_spec.rb
+++ b/spec/models/commit_spec.rb
@@ -885,4 +885,94 @@ eos
expect(commit.has_been_reverted?(user, issue.notes_with_associations)).to eq(false)
end
end
+
+ describe '#tipping_refs' do
+ let_it_be(:tag_name) { 'v1.1.0' }
+ let_it_be(:branch_names) { %w[master not-merged-branch v1.1.0] }
+
+ shared_examples 'tipping ref names' do
+ context 'when called without limits' do
+ it 'return tipping refs names' do
+ expect(called_method.call).to eq(expected)
+ end
+ end
+
+ context 'when called with limits' do
+ it 'return tipping refs names' do
+ limit = 1
+ expect(called_method.call(limit).size).to be <= limit
+ end
+ end
+
+ describe '#tipping_branches' do
+ let(:called_method) { ->(limit = 0) { commit.tipping_branches(limit: limit) } }
+ let(:expected) { branch_names }
+
+ it_behaves_like 'with tipping ref names'
+ end
+
+ describe '#tipping_tags' do
+ let(:called_method) { ->(limit = 0) { commit.tipping_tags(limit: limit) } }
+ let(:expected) { [tag_name] }
+
+ it_behaves_like 'with tipping ref names'
+ end
+ end
+ end
+
+ context 'containing refs' do
+ shared_examples 'containing ref names' do
+ context 'without arguments' do
+ it 'returns branch names containing the commit' do
+ expect(ref_containing.call).to eq(containing_refs)
+ end
+ end
+
+ context 'with limit argument' do
+ it 'returns the appropriate amount branch names' do
+ limit = 2
+ expect(ref_containing.call(limit: limit).size).to be <= limit
+ end
+ end
+
+ context 'with tipping refs excluded' do
+ let(:excluded_refs) do
+ project.repository.refs_by_oid(oid: commit_sha, ref_patterns: [ref_prefix]).map { |n| n.delete_prefix(ref_prefix) }
+ end
+
+ it 'returns branch names containing the commit without the one with the commit at tip' do
+ expect(ref_containing.call(excluded_tipped: true)).to eq(containing_refs - excluded_refs)
+ end
+
+ it 'returns the appropriate amount branch names with limit argument' do
+ limit = 2
+ expect(ref_containing.call(limit: limit, excluded_tipped: true).size).to be <= limit
+ end
+ end
+ end
+
+ describe '#branches_containing' do
+ let_it_be(:commit_sha) { project.commit.sha }
+ let_it_be(:containing_refs) { project.repository.branch_names_contains(commit_sha) }
+
+ let(:ref_prefix) { Gitlab::Git::BRANCH_REF_PREFIX }
+
+ let(:ref_containing) { ->(limit: 0, excluded_tipped: false) { commit.branches_containing(exclude_tipped: excluded_tipped, limit: limit) } }
+
+ it_behaves_like 'containing ref names'
+ end
+
+ describe '#tags_containing' do
+ let_it_be(:tag_name) { 'v1.1.0' }
+ let_it_be(:commit_sha) { project.repository.find_tag(tag_name).target_commit.sha }
+ let_it_be(:containing_refs) { %w[v1.1.0 v1.1.1] }
+
+ let(:ref_prefix) { Gitlab::Git::TAG_REF_PREFIX }
+
+ let(:commit) { project.repository.commit(commit_sha) }
+ let(:ref_containing) { ->(limit: 0, excluded_tipped: false) { commit.tags_containing(exclude_tipped: excluded_tipped, limit: limit) } }
+
+ it_behaves_like 'containing ref names'
+ end
+ end
end
diff --git a/spec/models/container_registry/data_repair_detail_spec.rb b/spec/models/container_registry/data_repair_detail_spec.rb
index 92833553a1e..4d2ac5fff42 100644
--- a/spec/models/container_registry/data_repair_detail_spec.rb
+++ b/spec/models/container_registry/data_repair_detail_spec.rb
@@ -8,4 +8,22 @@ RSpec.describe ContainerRegistry::DataRepairDetail, type: :model, feature_catego
subject { described_class.new(project: project) }
it { is_expected.to belong_to(:project).required }
+
+ it_behaves_like 'having unique enum values'
+
+ describe '.ongoing_since' do
+ let_it_be(:repair_detail1) { create(:container_registry_data_repair_detail, :ongoing, updated_at: 1.day.ago) }
+ let_it_be(:repair_detail2) { create(:container_registry_data_repair_detail, :ongoing, updated_at: 20.minutes.ago) }
+ let_it_be(:repair_detail3) do
+ create(:container_registry_data_repair_detail, :completed, updated_at: 20.minutes.ago)
+ end
+
+ let_it_be(:repair_detail4) do
+ create(:container_registry_data_repair_detail, :completed, updated_at: 31.minutes.ago)
+ end
+
+ subject { described_class.ongoing_since(30.minutes.ago) }
+
+ it { is_expected.to contain_exactly(repair_detail1) }
+ end
end
diff --git a/spec/models/milestone_spec.rb b/spec/models/milestone_spec.rb
index 8bd7c057a6e..1c43eafb576 100644
--- a/spec/models/milestone_spec.rb
+++ b/spec/models/milestone_spec.rb
@@ -724,4 +724,12 @@ RSpec.describe Milestone do
end
end
end
+
+ describe '#lock_version' do
+ let_it_be(:milestone) { create(:milestone, project: project) }
+
+ it 'ensures that lock_version and optimistic locking is enabled' do
+ expect(milestone.lock_version).to be_present
+ end
+ end
end
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 855c5f66554..e9bb01f4b23 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -95,6 +95,7 @@ RSpec.describe Project, factory_default: :keep, feature_category: :projects do
it { is_expected.to have_one(:mock_ci_integration) }
it { is_expected.to have_one(:mock_monitoring_integration) }
it { is_expected.to have_one(:service_desk_custom_email_verification).class_name('ServiceDesk::CustomEmailVerification') }
+ it { is_expected.to have_one(:container_registry_data_repair_detail).class_name('ContainerRegistry::DataRepairDetail') }
it { is_expected.to have_many(:commit_statuses) }
it { is_expected.to have_many(:ci_pipelines) }
it { is_expected.to have_many(:ci_refs) }
@@ -6800,6 +6801,19 @@ RSpec.describe Project, factory_default: :keep, feature_category: :projects do
end
end
+ describe '.pending_data_repair_analysis' do
+ it 'returns projects that are not in ContainerRegistry::DataRepairDetail' do
+ project_1 = create(:project)
+ project_2 = create(:project)
+
+ expect(described_class.pending_data_repair_analysis).to match_array([project_1, project_2])
+
+ create(:container_registry_data_repair_detail, project: project_1)
+
+ expect(described_class.pending_data_repair_analysis).to match_array([project_2])
+ end
+ end
+
describe '.deployments' do
subject { project.deployments }
diff --git a/spec/requests/api/graphql/metrics/dashboard/annotations_spec.rb b/spec/requests/api/graphql/metrics/dashboard/annotations_spec.rb
index a3103b1af57..143bc1672f8 100644
--- a/spec/requests/api/graphql/metrics/dashboard/annotations_spec.rb
+++ b/spec/requests/api/graphql/metrics/dashboard/annotations_spec.rb
@@ -22,6 +22,7 @@ RSpec.describe 'Getting Metrics Dashboard Annotations', feature_category: :metri
create(:metrics_dashboard_annotation, environment: environment, starting_at: to.advance(minutes: 5), dashboard_path: path)
end
+ let(:remove_monitor_metrics) { false }
let(:args) { "from: \"#{from}\", to: \"#{to}\"" }
let(:fields) do
<<~QUERY
@@ -50,7 +51,7 @@ RSpec.describe 'Getting Metrics Dashboard Annotations', feature_category: :metri
end
before do
- stub_feature_flags(remove_monitor_metrics: false)
+ stub_feature_flags(remove_monitor_metrics: remove_monitor_metrics)
project.add_developer(current_user)
post_graphql(query, current_user: current_user)
end
@@ -86,4 +87,18 @@ RSpec.describe 'Getting Metrics Dashboard Annotations', feature_category: :metri
it_behaves_like 'a working graphql query'
end
end
+
+ context 'when metrics dashboard feature is unavailable' do
+ let(:remove_monitor_metrics) { true }
+
+ it_behaves_like 'a working graphql query'
+
+ it 'returns nil' do
+ annotations = graphql_data.dig(
+ 'project', 'environments', 'nodes', 0, 'metricsDashboard', 'annotations'
+ )
+
+ expect(annotations).to be_nil
+ end
+ end
end
diff --git a/spec/requests/api/graphql/mutations/metrics/dashboard/annotations/create_spec.rb b/spec/requests/api/graphql/mutations/metrics/dashboard/annotations/create_spec.rb
index 3c7f4a030f9..d81744abe1b 100644
--- a/spec/requests/api/graphql/mutations/metrics/dashboard/annotations/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/metrics/dashboard/annotations/create_spec.rb
@@ -19,6 +19,10 @@ RSpec.describe Mutations::Metrics::Dashboard::Annotations::Create, feature_categ
graphql_mutation_response(:create_annotation)
end
+ before do
+ stub_feature_flags(remove_monitor_metrics: false)
+ end
+
specify { expect(described_class).to require_graphql_authorizations(:admin_metrics_dashboard_annotation) }
context 'when annotation source is environment' do
@@ -103,6 +107,15 @@ RSpec.describe Mutations::Metrics::Dashboard::Annotations::Create, feature_categ
it_behaves_like 'an invalid argument to the mutation', argument_name: :environment_id
end
+
+ context 'when metrics dashboard feature is unavailable' do
+ before do
+ stub_feature_flags(remove_monitor_metrics: true)
+ end
+
+ it_behaves_like 'a mutation that returns top-level errors',
+ errors: [Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR]
+ end
end
end
diff --git a/spec/requests/api/graphql/mutations/metrics/dashboard/annotations/delete_spec.rb b/spec/requests/api/graphql/mutations/metrics/dashboard/annotations/delete_spec.rb
index c104138b725..09977cd19d7 100644
--- a/spec/requests/api/graphql/mutations/metrics/dashboard/annotations/delete_spec.rb
+++ b/spec/requests/api/graphql/mutations/metrics/dashboard/annotations/delete_spec.rb
@@ -17,6 +17,10 @@ RSpec.describe Mutations::Metrics::Dashboard::Annotations::Delete, feature_categ
graphql_mutation_response(:delete_annotation)
end
+ before do
+ stub_feature_flags(remove_monitor_metrics: false)
+ end
+
specify { expect(described_class).to require_graphql_authorizations(:admin_metrics_dashboard_annotation) }
context 'when the user has permission to delete the annotation' do
@@ -54,6 +58,15 @@ RSpec.describe Mutations::Metrics::Dashboard::Annotations::Delete, feature_categ
expect(mutation_response['errors']).to eq([service_response[:message]])
end
end
+
+ context 'when metrics dashboard feature is unavailable' do
+ before do
+ stub_feature_flags(remove_monitor_metrics: true)
+ end
+
+ it_behaves_like 'a mutation that returns top-level errors',
+ errors: [Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR]
+ end
end
context 'when the user does not have permission to delete the annotation' do
diff --git a/spec/requests/api/graphql/project/branches_tipping_at_commit_spec.rb b/spec/requests/api/graphql/project/branches_tipping_at_commit_spec.rb
deleted file mode 100644
index bba8977078d..00000000000
--- a/spec/requests/api/graphql/project/branches_tipping_at_commit_spec.rb
+++ /dev/null
@@ -1,67 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe 'Query.project(fullPath).tagsTippingAtCommit(commitSha)', feature_category: :source_code_management do
- include GraphqlHelpers
- include Presentable
-
- let_it_be(:project) { create(:project, :repository) }
- let_it_be(:repository) { project.repository.raw }
- let_it_be(:current_user) { project.first_owner }
- let_it_be(:branches_names) { %w[master not-merged-branch v1.1.0] }
-
- let(:post_query) { post_graphql(query, current_user: current_user) }
- let(:path) { %w[project branchesTippingAtCommit names] }
- let(:data) { graphql_data.dig(*path) }
-
- let(:query) do
- graphql_query_for(
- :project,
- { fullPath: project.full_path },
- query_graphql_field(:branchesTippingAtCommit, { commitSha: commit_sha }, :names)
- )
- end
-
- context 'when commit exists and is tipping branches' do
- let_it_be(:commit_sha) { repository.commit.id }
-
- context 'with authorized user' do
- it 'returns branches names tipping the commit' do
- post_query
-
- expect(data).to eq(branches_names)
- end
- end
-
- context 'when user is not authorized' do
- let(:current_user) { create(:user) }
-
- it 'returns branches names tipping the commit' do
- post_query
-
- expect(data).to eq(nil)
- end
- end
- end
-
- context 'when commit does not exist' do
- let(:commit_sha) { '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff4' }
-
- it 'returns tags names tipping the commit' do
- post_query
-
- expect(data).to eq([])
- end
- end
-
- context 'when commit exists but does not tip any branches' do
- let(:commit_sha) { project.repository.commits(nil, { limit: 4 }).commits[2].id }
-
- it 'returns tags names tipping the commit' do
- post_query
-
- expect(data).to eq([])
- end
- end
-end
diff --git a/spec/requests/api/graphql/project/commit_references_spec.rb b/spec/requests/api/graphql/project/commit_references_spec.rb
new file mode 100644
index 00000000000..4b545adee12
--- /dev/null
+++ b/spec/requests/api/graphql/project/commit_references_spec.rb
@@ -0,0 +1,240 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Query.project(fullPath).commitReferences(commitSha)', feature_category: :source_code_management do
+ include GraphqlHelpers
+ include Presentable
+
+ let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:repository) { project.repository.raw }
+ let_it_be(:current_user) { project.first_owner }
+ let_it_be(:branches_names) { %w[master not-merged-branch v1.1.0] }
+ let_it_be(:tag_name) { 'v1.0.0' }
+ let_it_be(:commit_sha) { repository.commit.id }
+
+ let(:post_query) { post_graphql(query, current_user: current_user) }
+ let(:data) { graphql_data.dig(*path) }
+ let(:base_args) { {} }
+ let(:args) { base_args }
+
+ shared_context 'with the limit argument' do
+ context 'with limit of 2' do
+ let(:args) { { limit: 2 } }
+
+ it 'returns the right amount of refs' do
+ post_query
+ expect(data.count).to be <= 2
+ end
+ end
+
+ context 'with limit of -2' do
+ let(:args) { { limit: -2 } }
+
+ it 'casts an argument error "limit must be greater then 0"' do
+ post_query
+ expect(graphql_errors).to include(custom_graphql_error(path - ['names'],
+ 'limit must be within 1..1000'))
+ end
+ end
+
+ context 'with limit of 1001' do
+ let(:args) { { limit: 1001 } }
+
+ it 'casts an argument error "limit must be greater then 0"' do
+ post_query
+ expect(graphql_errors).to include(custom_graphql_error(path - ['names'],
+ 'limit must be within 1..1000'))
+ end
+ end
+ end
+
+ describe 'the path commitReferences should return nil' do
+ let(:path) { %w[project commitReferences] }
+
+ let(:query) do
+ graphql_query_for(:project, { fullPath: project.full_path },
+ query_graphql_field(
+ :commitReferences,
+ { commitSha: commit_sha },
+ query_graphql_field(:tippingTags, :names)
+ )
+ )
+ end
+
+ context 'when commit does not exist' do
+ let(:commit_sha) { '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff4' }
+
+ it 'commitReferences returns nil' do
+ post_query
+ expect(data).to eq(nil)
+ end
+ end
+
+ context 'when sha length is incorrect' do
+ let(:commit_sha) { 'foo' }
+
+ it 'commitReferences returns nil' do
+ post_query
+ expect(data).to eq(nil)
+ end
+ end
+
+ context 'when user is not authorized' do
+ let(:commit_sha) { repository.commit.id }
+ let(:current_user) { create(:user) }
+
+ it 'commitReferences returns nil' do
+ post_query
+ expect(data).to eq(nil)
+ end
+ end
+ end
+
+ context 'with containing refs' do
+ let(:base_args) { { excludeTipped: false } }
+ let(:excluded_tipped_args) do
+ hash = base_args.dup
+ hash[:excludeTipped] = true
+ hash
+ end
+
+ context 'with path Query.project(fullPath).commitReferences(commitSha).containingTags' do
+ let_it_be(:commit_sha) { repository.find_tag(tag_name).target_commit.sha }
+ let_it_be(:path) { %w[project commitReferences containingTags names] }
+ let(:query) do
+ graphql_query_for(
+ :project,
+ { fullPath: project.full_path },
+ query_graphql_field(
+ :commitReferences,
+ { commitSha: commit_sha },
+ query_graphql_field(:containingTags, args, :names)
+ )
+ )
+ end
+
+ context 'without excludeTipped argument' do
+ it 'returns tags names containing the commit' do
+ post_query
+ expect(data).to eq(%w[v1.0.0 v1.1.0 v1.1.1])
+ end
+ end
+
+ context 'with excludeTipped argument' do
+ let_it_be(:ref_prefix) { Gitlab::Git::TAG_REF_PREFIX }
+
+ let(:args) { excluded_tipped_args }
+
+ it 'returns tags names containing the commit without the tipped tags' do
+ excluded_refs = project.repository
+ .refs_by_oid(oid: commit_sha, ref_patterns: [ref_prefix])
+ .map { |n| n.delete_prefix(ref_prefix) }
+
+ post_query
+ expect(data).to eq(%w[v1.0.0 v1.1.0 v1.1.1] - excluded_refs)
+ end
+ end
+
+ include_context 'with the limit argument'
+ end
+
+ context 'with path Query.project(fullPath).commitReferences(commitSha).containingBranches' do
+ let_it_be(:ref_prefix) { Gitlab::Git::BRANCH_REF_PREFIX }
+ let_it_be(:path) { %w[project commitReferences containingBranches names] }
+
+ let(:query) do
+ graphql_query_for(
+ :project,
+ { fullPath: project.full_path },
+ query_graphql_field(
+ :commitReferences,
+ { commitSha: commit_sha },
+ query_graphql_field(:containingBranches, args, :names)
+ )
+ )
+ end
+
+ context 'without excludeTipped argument' do
+ it 'returns branch names containing the commit' do
+ refs = project.repository.branch_names_contains(commit_sha)
+
+ post_query
+
+ expect(data).to eq(refs)
+ end
+ end
+
+ context 'with excludeTipped argument' do
+ let(:args) { excluded_tipped_args }
+
+ it 'returns branch names containing the commit without the tipped branch' do
+ refs = project.repository.branch_names_contains(commit_sha)
+
+ excluded_refs = project.repository
+ .refs_by_oid(oid: commit_sha, ref_patterns: [ref_prefix])
+ .map { |n| n.delete_prefix(ref_prefix) }
+
+ post_query
+
+ expect(data).to eq(refs - excluded_refs)
+ end
+ end
+
+ include_context 'with the limit argument'
+ end
+ end
+
+ context 'with tipping refs' do
+ context 'with path Query.project(fullPath).commitReferences(commitSha).tippingTags' do
+ let(:commit_sha) { repository.find_tag(tag_name).dereferenced_target.sha }
+ let(:path) { %w[project commitReferences tippingTags names] }
+
+ let(:query) do
+ graphql_query_for(
+ :project,
+ { fullPath: project.full_path },
+ query_graphql_field(
+ :commitReferences,
+ { commitSha: commit_sha },
+ query_graphql_field(:tippingTags, args, :names)
+ )
+ )
+ end
+
+ context 'with authorized user' do
+ it 'returns tags names tipping the commit' do
+ post_query
+
+ expect(data).to eq([tag_name])
+ end
+ end
+
+ include_context 'with the limit argument'
+ end
+
+ context 'with path Query.project(fullPath).commitReferences(commitSha).tippingBranches' do
+ let(:path) { %w[project commitReferences tippingBranches names] }
+
+ let(:query) do
+ graphql_query_for(
+ :project,
+ { fullPath: project.full_path },
+ query_graphql_field(
+ :commitReferences,
+ { commitSha: commit_sha },
+ query_graphql_field(:tippingBranches, args, :names)
+ )
+ )
+ end
+
+ it 'returns branches names tipping the commit' do
+ post_query
+
+ expect(data).to eq(branches_names)
+ end
+
+ include_context 'with the limit argument'
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/project/project_statistics_redirect_spec.rb b/spec/requests/api/graphql/project/project_statistics_redirect_spec.rb
new file mode 100644
index 00000000000..8049a75ace3
--- /dev/null
+++ b/spec/requests/api/graphql/project/project_statistics_redirect_spec.rb
@@ -0,0 +1,78 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'rendering project storage type routes', feature_category: :shared do
+ include GraphqlHelpers
+
+ let_it_be(:project) { create(:project, :public) }
+ let_it_be(:user) { create(:user) }
+
+ let(:query) do
+ graphql_query_for('project',
+ { 'fullPath' => project.full_path },
+ "statisticsDetailsPaths { #{all_graphql_fields_for('ProjectStatisticsRedirect')} }")
+ end
+
+ it_behaves_like 'a working graphql query' do
+ before do
+ post_graphql(query, current_user: user)
+ end
+ end
+
+ shared_examples 'valid routes for storage type' do
+ it 'contains all keys' do
+ post_graphql(query, current_user: user)
+
+ expect(graphql_data['project']['statisticsDetailsPaths'].keys).to match_array(
+ %w[repository buildArtifacts wiki packages snippets containerRegistry]
+ )
+ end
+
+ it 'contains valid paths' do
+ repository_url = Gitlab::Routing.url_helpers.project_tree_url(project, "master")
+ wiki_url = Gitlab::Routing.url_helpers.project_wikis_pages_url(project)
+ build_artifacts_url = Gitlab::Routing.url_helpers.project_artifacts_url(project)
+ packages_url = Gitlab::Routing.url_helpers.project_packages_url(project)
+ snippets_url = Gitlab::Routing.url_helpers.project_snippets_url(project)
+ container_registry_url = Gitlab::Routing.url_helpers.project_container_registry_index_url(project)
+
+ post_graphql(query, current_user: user)
+
+ expect(graphql_data['project']['statisticsDetailsPaths'].values).to match_array [repository_url,
+ wiki_url,
+ build_artifacts_url,
+ packages_url,
+ snippets_url,
+ container_registry_url]
+ end
+ end
+
+ context 'when project is public' do
+ it_behaves_like 'valid routes for storage type'
+
+ context 'when user is nil' do
+ let_it_be(:user) { nil }
+
+ it_behaves_like 'valid routes for storage type'
+ end
+ end
+
+ context 'when project is private' do
+ let_it_be(:project) { create(:project, :private) }
+
+ before do
+ project.add_reporter(user)
+ end
+
+ it_behaves_like 'valid routes for storage type'
+
+ context 'when user is nil' do
+ it 'hides statisticsDetailsPaths for nil users' do
+ post_graphql(query, current_user: nil)
+
+ expect(graphql_data['project']).to be_blank
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/project/tags_tipping_at_commit_spec.rb b/spec/requests/api/graphql/project/tags_tipping_at_commit_spec.rb
deleted file mode 100644
index a5e26482a9e..00000000000
--- a/spec/requests/api/graphql/project/tags_tipping_at_commit_spec.rb
+++ /dev/null
@@ -1,67 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe 'Query.project(fullPath).tagsTippingAtCommit(commitSha)', feature_category: :source_code_management do
- include GraphqlHelpers
- include Presentable
-
- let_it_be(:project) { create(:project, :repository) }
- let_it_be(:repository) { project.repository.raw }
- let_it_be(:current_user) { project.first_owner }
- let_it_be(:tag_name) { 'v1.0.0' }
-
- let(:post_query) { post_graphql(query, current_user: current_user) }
- let(:path) { %w[project tagsTippingAtCommit names] }
- let(:data) { graphql_data.dig(*path) }
-
- let(:query) do
- graphql_query_for(
- :project,
- { fullPath: project.full_path },
- query_graphql_field(:tagsTippingAtCommit, { commitSha: commit_sha }, :names)
- )
- end
-
- context 'when commit exists and is tipping tags' do
- let(:commit_sha) { repository.find_tag(tag_name).dereferenced_target.sha }
-
- context 'with authorized user' do
- it 'returns tags names tipping the commit' do
- post_query
-
- expect(data).to eq([tag_name])
- end
- end
-
- context 'when user is not authorized' do
- let(:current_user) { create(:user) }
-
- it 'returns tags names tipping the commit' do
- post_query
-
- expect(data).to eq(nil)
- end
- end
- end
-
- context 'when commit does not exist' do
- let(:commit_sha) { '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff4' }
-
- it 'returns tags names tipping the commit' do
- post_query
-
- expect(data).to eq([])
- end
- end
-
- context 'when commit exists but does not tip any tags' do
- let(:commit_sha) { project.repository.commits(nil, { limit: 4 }).commits[2].id }
-
- it 'returns tags names tipping the commit' do
- post_query
-
- expect(data).to eq([])
- end
- end
-end
diff --git a/spec/requests/api/metrics/dashboard/annotations_spec.rb b/spec/requests/api/metrics/dashboard/annotations_spec.rb
index cefd5896158..250fe2a3ee3 100644
--- a/spec/requests/api/metrics/dashboard/annotations_spec.rb
+++ b/spec/requests/api/metrics/dashboard/annotations_spec.rb
@@ -16,6 +16,7 @@ RSpec.describe API::Metrics::Dashboard::Annotations, feature_category: :metrics
let(:url) { "/#{source_type.pluralize}/#{source.id}/metrics_dashboard/annotations" }
before do
+ stub_feature_flags(remove_monitor_metrics: false)
project.add_developer(user)
end
@@ -104,6 +105,18 @@ RSpec.describe API::Metrics::Dashboard::Annotations, feature_category: :metrics
expect(response).to have_gitlab_http_status(:forbidden)
end
end
+
+ context 'when metrics dashboard feature is unavailable' do
+ before do
+ stub_feature_flags(remove_monitor_metrics: true)
+ end
+
+ it 'returns 404 not found' do
+ post api(url, user), params: params
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
end
end
diff --git a/spec/requests/api/project_packages_spec.rb b/spec/requests/api/project_packages_spec.rb
index 69579323908..c003ae9cd48 100644
--- a/spec/requests/api/project_packages_spec.rb
+++ b/spec/requests/api/project_packages_spec.rb
@@ -224,19 +224,15 @@ RSpec.describe API::ProjectPackages, feature_category: :package_registry do
context 'without the need for a license' do
context 'with build info' do
- let_it_be(:package1) { create(:npm_package, :with_build, project: project) }
-
- it 'returns an empty array for the pipelines attribute' do
- subject
-
- expect(json_response['pipelines']).to be_empty
- end
-
it 'does not result in additional queries' do
control = ActiveRecord::QueryRecorder.new do
get api(package_url, user)
end
+ pipeline = create(:ci_pipeline, user: user, project: project)
+ create(:ci_build, user: user, pipeline: pipeline, project: project)
+ create(:package_build_info, package: package1, pipeline: pipeline)
+
expect do
get api(package_url, user)
end.not_to exceed_query_limit(control)
diff --git a/spec/requests/api/project_templates_spec.rb b/spec/requests/api/project_templates_spec.rb
index 38d6a05a104..91e5ed76c37 100644
--- a/spec/requests/api/project_templates_spec.rb
+++ b/spec/requests/api/project_templates_spec.rb
@@ -10,6 +10,7 @@ RSpec.describe API::ProjectTemplates, feature_category: :source_code_management
let(:url_encoded_path) { "#{public_project.namespace.path}%2F#{public_project.path}" }
before do
+ stub_feature_flags(remove_monitor_metrics: false)
private_project.add_developer(developer)
end
@@ -71,6 +72,18 @@ RSpec.describe API::ProjectTemplates, feature_category: :source_code_management
expect(json_response).to satisfy_one { |template| template['key'] == 'Default' }
end
+ context 'when metrics dashboard feature is unavailable' do
+ before do
+ stub_feature_flags(remove_monitor_metrics: true)
+ end
+
+ it 'returns 400 bad request like other unknown types' do
+ get api("/projects/#{public_project.id}/templates/metrics_dashboard_ymls")
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ end
+ end
+
it 'returns issue templates' do
get api("/projects/#{private_project.id}/templates/issues", developer)
@@ -171,6 +184,18 @@ RSpec.describe API::ProjectTemplates, feature_category: :source_code_management
expect(json_response['name']).to eq('Default')
end
+ context 'when metrics dashboard feature is unavailable' do
+ before do
+ stub_feature_flags(remove_monitor_metrics: true)
+ end
+
+ it 'returns 400 bad request like other unknown types' do
+ get api("/projects/#{public_project.id}/templates/metrics_dashboard_ymls/Default")
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ end
+ end
+
it 'returns a specific license' do
get api("/projects/#{public_project.id}/templates/licenses/mit")
diff --git a/spec/services/jira_connect/sync_service_spec.rb b/spec/services/jira_connect/sync_service_spec.rb
index fc1b4e997a5..7457cdca13c 100644
--- a/spec/services/jira_connect/sync_service_spec.rb
+++ b/spec/services/jira_connect/sync_service_spec.rb
@@ -44,16 +44,18 @@ RSpec.describe JiraConnect::SyncService, feature_category: :integrations do
subject
end
- context 'when a request returns an error' do
- it 'logs the response as an error' do
+ context 'when a request returns errors' do
+ it 'logs each response as an error' do
expect_next(client).to store_info(
[
{ 'errorMessages' => ['some error message'] },
- { 'errorMessages' => ['x'] }
+ { 'errorMessage' => 'a single error message' },
+ { 'errorMessages' => [] },
+ { 'errorMessage' => '' }
])
expect_log(:error, { 'errorMessages' => ['some error message'] })
- expect_log(:error, { 'errorMessages' => ['x'] })
+ expect_log(:error, { 'errorMessage' => 'a single error message' })
subject
end
diff --git a/spec/support/import_export/export_file_helper.rb b/spec/support/import_export/export_file_helper.rb
index 9a26f50903f..ee1b4a3c33a 100644
--- a/spec/support/import_export/export_file_helper.rb
+++ b/spec/support/import_export/export_file_helper.rb
@@ -21,21 +21,25 @@ module ExportFileHelper
create(:label_link, label: label, target: issue)
- ci_pipeline = create(:ci_pipeline,
- project: project,
- sha: merge_request.diff_head_sha,
- ref: merge_request.source_branch,
- statuses: [commit_status])
+ ci_pipeline = create(
+ :ci_pipeline,
+ project: project,
+ sha: merge_request.diff_head_sha,
+ ref: merge_request.source_branch,
+ statuses: [commit_status]
+ )
create(:ci_build, pipeline: ci_pipeline, project: project)
create(:milestone, project: project)
create(:note, noteable: issue, project: project)
create(:note, noteable: merge_request, project: project)
create(:note, noteable: snippet, project: project)
- create(:note_on_commit,
- author: user,
- project: project,
- commit_id: ci_pipeline.sha)
+ create(
+ :note_on_commit,
+ author: user,
+ project: project,
+ commit_id: ci_pipeline.sha
+ )
event = create(:event, :created, target: milestone, project: project, author: user, action: 5)
create(:push_event_payload, event: event)
diff --git a/spec/support/shared_examples/controllers/snippets_sort_order_shared_examples.rb b/spec/support/shared_examples/controllers/snippets_sort_order_shared_examples.rb
index 112b9cbb204..f658cfac0f5 100644
--- a/spec/support/shared_examples/controllers/snippets_sort_order_shared_examples.rb
+++ b/spec/support/shared_examples/controllers/snippets_sort_order_shared_examples.rb
@@ -15,8 +15,9 @@ RSpec.shared_examples 'snippets sort order' do
context 'when no sort param is provided' do
it 'calls SnippetsFinder with updated_at sort option' do
- expect(SnippetsFinder).to receive(:new).with(user,
- hash_including(sort: 'updated_desc')).and_call_original
+ expect(SnippetsFinder).to receive(:new)
+ .with(user, hash_including(sort: 'updated_desc'))
+ .and_call_original
subject
end
@@ -27,8 +28,9 @@ RSpec.shared_examples 'snippets sort order' do
let(:sort_argument) { { sort: order } }
it 'calls SnippetsFinder with the given sort param' do
- expect(SnippetsFinder).to receive(:new).with(user,
- hash_including(sort: order)).and_call_original
+ expect(SnippetsFinder).to receive(:new)
+ .with(user, hash_including(sort: order))
+ .and_call_original
subject
end
diff --git a/spec/support/shared_examples/controllers/wiki_actions_shared_examples.rb b/spec/support/shared_examples/controllers/wiki_actions_shared_examples.rb
index 768b54dc73e..32aa566c27e 100644
--- a/spec/support/shared_examples/controllers/wiki_actions_shared_examples.rb
+++ b/spec/support/shared_examples/controllers/wiki_actions_shared_examples.rb
@@ -399,11 +399,10 @@ RSpec.shared_examples 'wiki controller actions' do
let(:id_param) { wiki_title }
subject(:request) do
- patch(:update,
- params: routing_params.merge(
- id: id_param,
- wiki: { title: new_title, content: new_content }
- ))
+ patch(:update, params: routing_params.merge(
+ id: id_param,
+ wiki: { title: new_title, content: new_content }
+ ))
end
it_behaves_like 'edit action'
@@ -439,10 +438,9 @@ RSpec.shared_examples 'wiki controller actions' do
let(:new_content) { 'New content' }
subject(:request) do
- post(:create,
- params: routing_params.merge(
- wiki: { title: new_title, content: new_content }
- ))
+ post(:create, params: routing_params.merge(
+ wiki: { title: new_title, content: new_content }
+ ))
end
context 'when page is valid' do
@@ -476,10 +474,9 @@ RSpec.shared_examples 'wiki controller actions' do
let(:delete_user) { user }
subject(:request) do
- delete(:destroy,
- params: routing_params.merge(
- id: id_param
- ))
+ delete(:destroy, params: routing_params.merge(
+ id: id_param
+ ))
end
before do
diff --git a/spec/support/shared_examples/features/editable_merge_request_shared_examples.rb b/spec/support/shared_examples/features/editable_merge_request_shared_examples.rb
index 2bcbd5e5190..14e53dc8655 100644
--- a/spec/support/shared_examples/features/editable_merge_request_shared_examples.rb
+++ b/spec/support/shared_examples/features/editable_merge_request_shared_examples.rb
@@ -83,9 +83,15 @@ RSpec.shared_examples 'an editable merge request' do
fill_in 'merge_request_title', with: 'bug 345'
fill_in 'merge_request_description', with: 'bug description'
- click_button 'Save changes'
-
- expect(page).to have_content 'Someone edited the merge request the same time you did'
+ click_button _('Save changes')
+
+ expect(page).to have_content(
+ format(
+ _("Someone edited this %{model_name} at the same time you did. Please check out the %{link_to_model} and make sure your changes will not unintentionally remove theirs."), # rubocop:disable Layout/LineLength
+ model_name: _('merge request'),
+ link_to_model: _('merge request')
+ )
+ )
end
it 'preserves description textarea height', :js do
diff --git a/spec/support/shared_examples/features/milestone_editing_shared_examples.rb b/spec/support/shared_examples/features/milestone_editing_shared_examples.rb
new file mode 100644
index 00000000000..d21bf62ecfa
--- /dev/null
+++ b/spec/support/shared_examples/features/milestone_editing_shared_examples.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'milestone handling version conflicts' do
+ it 'warns about version conflict when milestone has been updated in the background' do
+ # Update the milestone in the background in order to trigger a version conflict
+ milestone.update!(title: "New title")
+
+ fill_in _('Title'), with: 'Title for version conflict'
+ fill_in _('Description'), with: 'Description for version conflict'
+
+ click_button _('Save changes')
+
+ expect(page).to have_content(
+ format(
+ _("Someone edited this %{model_name} at the same time you did. Please check out the %{link_to_model} and make sure your changes will not unintentionally remove theirs."), # rubocop:disable Layout/LineLength
+ model_name: _('milestone'),
+ link_to_model: _('milestone')
+ )
+ )
+ end
+end
diff --git a/spec/support/shared_examples/features/search/redacted_search_results_shared_examples.rb b/spec/support/shared_examples/features/search/redacted_search_results_shared_examples.rb
index 4d242d0e719..cbd0ffbab21 100644
--- a/spec/support/shared_examples/features/search/redacted_search_results_shared_examples.rb
+++ b/spec/support/shared_examples/features/search/redacted_search_results_shared_examples.rb
@@ -48,14 +48,18 @@ RSpec.shared_examples 'a redacted search results' do
it 'redacts the inaccessible issue' do
expect(search_service.send(:logger))
.to receive(:error)
- .with(hash_including(
- message: "redacted_search_results",
- current_user_id: user.id,
- query: search,
- filtered: array_including(
- [
- { class_name: 'Issue', id: unreadable.id, ability: :read_issue }
- ])))
+ .with(
+ hash_including(
+ message: "redacted_search_results",
+ current_user_id: user.id,
+ query: search,
+ filtered: array_including(
+ [
+ { class_name: 'Issue', id: unreadable.id, ability: :read_issue }
+ ]
+ )
+ )
+ )
expect(result).to contain_exactly(readable)
end
@@ -95,16 +99,18 @@ RSpec.shared_examples 'a redacted search results' do
end
let(:unredacted_results) do
- ar_relation(Note,
- readable_note_on_commit,
- readable_diff_note,
- readable_note_on_mr,
- readable_diff_note_on_mr,
- readable_note_on_project_snippet,
- unreadable_note_on_commit,
- unreadable_diff_note,
- unreadable_note_on_mr,
- unreadable_note_on_project_snippet)
+ ar_relation(
+ Note,
+ readable_note_on_commit,
+ readable_diff_note,
+ readable_note_on_mr,
+ readable_diff_note_on_mr,
+ readable_note_on_project_snippet,
+ unreadable_note_on_commit,
+ unreadable_diff_note,
+ unreadable_note_on_mr,
+ unreadable_note_on_project_snippet
+ )
end
let(:scope) { 'notes' }
@@ -112,23 +118,29 @@ RSpec.shared_examples 'a redacted search results' do
it 'redacts the inaccessible notes' do
expect(search_service.send(:logger))
.to receive(:error)
- .with(hash_including(
- message: "redacted_search_results",
- current_user_id: user.id,
- query: search,
- filtered: array_including(
- [
- { class_name: 'Note', id: unreadable_note_on_commit.id, ability: :read_note },
- { class_name: 'DiffNote', id: unreadable_diff_note.id, ability: :read_note },
- { class_name: 'DiscussionNote', id: unreadable_note_on_mr.id, ability: :read_note },
- { class_name: 'Note', id: unreadable_note_on_project_snippet.id, ability: :read_note }
- ])))
-
- expect(result).to contain_exactly(readable_note_on_commit,
- readable_diff_note,
- readable_note_on_mr,
- readable_diff_note_on_mr,
- readable_note_on_project_snippet)
+ .with(
+ hash_including(
+ message: "redacted_search_results",
+ current_user_id: user.id,
+ query: search,
+ filtered: array_including(
+ [
+ { class_name: 'Note', id: unreadable_note_on_commit.id, ability: :read_note },
+ { class_name: 'DiffNote', id: unreadable_diff_note.id, ability: :read_note },
+ { class_name: 'DiscussionNote', id: unreadable_note_on_mr.id, ability: :read_note },
+ { class_name: 'Note', id: unreadable_note_on_project_snippet.id, ability: :read_note }
+ ]
+ )
+ )
+ )
+
+ expect(result).to contain_exactly(
+ readable_note_on_commit,
+ readable_diff_note,
+ readable_note_on_mr,
+ readable_diff_note_on_mr,
+ readable_note_on_project_snippet
+ )
end
end
@@ -141,14 +153,18 @@ RSpec.shared_examples 'a redacted search results' do
it 'redacts the inaccessible merge request' do
expect(search_service.send(:logger))
.to receive(:error)
- .with(hash_including(
- message: "redacted_search_results",
- current_user_id: user.id,
- query: search,
- filtered: array_including(
- [
- { class_name: 'MergeRequest', id: unreadable.id, ability: :read_merge_request }
- ])))
+ .with(
+ hash_including(
+ message: "redacted_search_results",
+ current_user_id: user.id,
+ query: search,
+ filtered: array_including(
+ [
+ { class_name: 'MergeRequest', id: unreadable.id, ability: :read_merge_request }
+ ]
+ )
+ )
+ )
expect(result).to contain_exactly(readable)
end
@@ -169,14 +185,18 @@ RSpec.shared_examples 'a redacted search results' do
it 'redacts the inaccessible blob' do
expect(search_service.send(:logger))
.to receive(:error)
- .with(hash_including(
- message: "redacted_search_results",
- current_user_id: user.id,
- query: search,
- filtered: array_including(
- [
- { class_name: 'Gitlab::Search::FoundBlob', id: unreadable.id, ability: :read_blob }
- ])))
+ .with(
+ hash_including(
+ message: "redacted_search_results",
+ current_user_id: user.id,
+ query: search,
+ filtered: array_including(
+ [
+ { class_name: 'Gitlab::Search::FoundBlob', id: unreadable.id, ability: :read_blob }
+ ]
+ )
+ )
+ )
expect(result).to contain_exactly(readable)
end
@@ -191,14 +211,18 @@ RSpec.shared_examples 'a redacted search results' do
it 'redacts the inaccessible blob' do
expect(search_service.send(:logger))
.to receive(:error)
- .with(hash_including(
- message: "redacted_search_results",
- current_user_id: user.id,
- query: search,
- filtered: array_including(
- [
- { class_name: 'Gitlab::Search::FoundWikiPage', id: unreadable.id, ability: :read_wiki_page }
- ])))
+ .with(
+ hash_including(
+ message: "redacted_search_results",
+ current_user_id: user.id,
+ query: search,
+ filtered: array_including(
+ [
+ { class_name: 'Gitlab::Search::FoundWikiPage', id: unreadable.id, ability: :read_wiki_page }
+ ]
+ )
+ )
+ )
expect(result).to contain_exactly(readable)
end
@@ -213,14 +237,18 @@ RSpec.shared_examples 'a redacted search results' do
it 'redacts the inaccessible snippet' do
expect(search_service.send(:logger))
.to receive(:error)
- .with(hash_including(
- message: "redacted_search_results",
- current_user_id: user.id,
- query: search,
- filtered: array_including(
- [
- { class_name: 'ProjectSnippet', id: unreadable.id, ability: :read_snippet }
- ])))
+ .with(
+ hash_including(
+ message: "redacted_search_results",
+ current_user_id: user.id,
+ query: search,
+ filtered: array_including(
+ [
+ { class_name: 'ProjectSnippet', id: unreadable.id, ability: :read_snippet }
+ ]
+ )
+ )
+ )
expect(result).to contain_exactly(readable)
end
@@ -239,14 +267,18 @@ RSpec.shared_examples 'a redacted search results' do
it 'redacts the inaccessible snippet' do
expect(search_service.send(:logger))
.to receive(:error)
- .with(hash_including(
- message: "redacted_search_results",
- current_user_id: user.id,
- query: search,
- filtered: array_including(
- [
- { class_name: 'PersonalSnippet', id: unreadable.id, ability: :read_snippet }
- ])))
+ .with(
+ hash_including(
+ message: "redacted_search_results",
+ current_user_id: user.id,
+ query: search,
+ filtered: array_including(
+ [
+ { class_name: 'PersonalSnippet', id: unreadable.id, ability: :read_snippet }
+ ]
+ )
+ )
+ )
expect(result).to contain_exactly(readable)
end
@@ -265,14 +297,18 @@ RSpec.shared_examples 'a redacted search results' do
it 'redacts the inaccessible commit' do
expect(search_service.send(:logger))
.to receive(:error)
- .with(hash_including(
- message: "redacted_search_results",
- current_user_id: user.id,
- query: search,
- filtered: array_including(
- [
- { class_name: 'Commit', id: unreadable.id, ability: :read_commit }
- ])))
+ .with(
+ hash_including(
+ message: "redacted_search_results",
+ current_user_id: user.id,
+ query: search,
+ filtered: array_including(
+ [
+ { class_name: 'Commit', id: unreadable.id, ability: :read_commit }
+ ]
+ )
+ )
+ )
expect(result).to contain_exactly(readable)
end
diff --git a/spec/support/shared_examples/features/wiki/user_views_wiki_page_shared_examples.rb b/spec/support/shared_examples/features/wiki/user_views_wiki_page_shared_examples.rb
index a7c32932ba7..767caffd417 100644
--- a/spec/support/shared_examples/features/wiki/user_views_wiki_page_shared_examples.rb
+++ b/spec/support/shared_examples/features/wiki/user_views_wiki_page_shared_examples.rb
@@ -9,9 +9,11 @@ RSpec.shared_examples 'User views a wiki page' do
let(:path) { 'image.png' }
let(:wiki_page) do
- create(:wiki_page,
- wiki: wiki,
- title: 'home', content: "Look at this [image](#{path})\n\n ![alt text](#{path})")
+ create(
+ :wiki_page,
+ wiki: wiki,
+ title: 'home', content: "Look at this [image](#{path})\n\n ![alt text](#{path})"
+ )
end
before do
diff --git a/spec/support/shared_examples/graphql/members_shared_examples.rb b/spec/support/shared_examples/graphql/members_shared_examples.rb
index 5cba8baa829..5ab17f5a49d 100644
--- a/spec/support/shared_examples/graphql/members_shared_examples.rb
+++ b/spec/support/shared_examples/graphql/members_shared_examples.rb
@@ -39,8 +39,10 @@ RSpec.shared_examples 'querying members with a group' do
let(:base_args) { { relations: described_class.arguments['relations'].default_value } }
subject do
- resolve(described_class, obj: resource, args: base_args.merge(args),
- ctx: { current_user: user_4 }, arg_style: :internal)
+ resolve(
+ described_class, obj: resource, args: base_args.merge(args),
+ ctx: { current_user: user_4 }, arg_style: :internal
+ )
end
describe '#resolve' do
@@ -83,8 +85,10 @@ RSpec.shared_examples 'querying members with a group' do
let_it_be(:other_user) { create(:user) }
subject do
- resolve(described_class, obj: resource, args: base_args.merge(args),
- ctx: { current_user: other_user }, arg_style: :internal)
+ resolve(
+ described_class, obj: resource, args: base_args.merge(args),
+ ctx: { current_user: other_user }, arg_style: :internal
+ )
end
it 'generates an error' do
diff --git a/spec/support/shared_examples/graphql/mutation_shared_examples.rb b/spec/support/shared_examples/graphql/mutation_shared_examples.rb
index dc590e23ace..808fb097f29 100644
--- a/spec/support/shared_examples/graphql/mutation_shared_examples.rb
+++ b/spec/support/shared_examples/graphql/mutation_shared_examples.rb
@@ -15,7 +15,7 @@ RSpec.shared_examples 'a mutation that returns top-level errors' do |errors: []|
expect(graphql_errors).to be_present
- error_messages = graphql_errors.map { |e| e['message'] }
+ error_messages = graphql_errors.pluck('message')
expect(error_messages).to match_errors
end
@@ -25,7 +25,7 @@ end
# the mutation.
RSpec.shared_examples 'a mutation that returns a top-level access error' do
include_examples 'a mutation that returns top-level errors',
- errors: [Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR]
+ errors: [Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR]
end
RSpec.shared_examples 'an invalid argument to the mutation' do |argument_name:|
diff --git a/spec/support/shared_examples/graphql/mutations/set_assignees_shared_examples.rb b/spec/support/shared_examples/graphql/mutations/set_assignees_shared_examples.rb
index 022e2308517..3b9dadf2e80 100644
--- a/spec/support/shared_examples/graphql/mutations/set_assignees_shared_examples.rb
+++ b/spec/support/shared_examples/graphql/mutations/set_assignees_shared_examples.rb
@@ -16,10 +16,12 @@ RSpec.shared_examples 'an assignable resource' do
let(:mode) { described_class.arguments['operationMode'].default_value }
subject do
- mutation.resolve(project_path: resource.project.full_path,
- iid: resource.iid,
- operation_mode: mode,
- assignee_usernames: assignee_usernames)
+ mutation.resolve(
+ project_path: resource.project.full_path,
+ iid: resource.iid,
+ operation_mode: mode,
+ assignee_usernames: assignee_usernames
+ )
end
it 'raises an error if the resource is not accessible to the user' do
diff --git a/spec/support/shared_examples/graphql/notes_on_noteables_shared_examples.rb b/spec/support/shared_examples/graphql/notes_on_noteables_shared_examples.rb
index 09239ced73a..99d122e8254 100644
--- a/spec/support/shared_examples/graphql/notes_on_noteables_shared_examples.rb
+++ b/spec/support/shared_examples/graphql/notes_on_noteables_shared_examples.rb
@@ -4,9 +4,11 @@ RSpec.shared_context 'exposing regular notes on a noteable in GraphQL' do
include GraphqlHelpers
let(:note) do
- create(:note,
- noteable: noteable,
- project: (noteable.project if noteable.respond_to?(:project)))
+ create(
+ :note,
+ noteable: noteable,
+ project: (noteable.project if noteable.respond_to?(:project))
+ )
end
let(:user) { note.author }
diff --git a/spec/support/shared_examples/requests/api/container_repositories_shared_examples.rb b/spec/support/shared_examples/requests/api/container_repositories_shared_examples.rb
index f5c41416763..3ff52166990 100644
--- a/spec/support/shared_examples/requests/api/container_repositories_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/container_repositories_shared_examples.rb
@@ -18,7 +18,7 @@ RSpec.shared_examples 'returns repositories for allowed users' do |user_type, sc
subject
expect(json_response.length).to eq(2)
- expect(json_response.map { |repository| repository['id'] }).to contain_exactly(
+ expect(json_response.pluck('id')).to contain_exactly(
root_repository.id, test_repository.id)
expect(response.body).not_to include('tags')
expect(response.body).not_to include('tags_count')
@@ -47,7 +47,7 @@ RSpec.shared_examples 'returns tags for allowed users' do |user_type, scope|
subject
expect(json_response.length).to eq(2)
- expect(json_response.map { |repository| repository['id'] }).to contain_exactly(
+ expect(json_response.pluck('id')).to contain_exactly(
root_repository.id, test_repository.id)
expect(response.body).to include('tags')
end
diff --git a/spec/support/shared_examples/requests/api/custom_attributes_shared_examples.rb b/spec/support/shared_examples/requests/api/custom_attributes_shared_examples.rb
index e3ba51addaf..804221b7416 100644
--- a/spec/support/shared_examples/requests/api/custom_attributes_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/custom_attributes_shared_examples.rb
@@ -14,7 +14,7 @@ RSpec.shared_examples 'custom attributes endpoints' do |attributable_name|
get api("/#{attributable_name}", user), params: { custom_attributes: { foo: 'foo', bar: 'bar' } }
expect(response).to have_gitlab_http_status(:ok)
- expect(json_response.map { |r| r['id'] }).to include(attributable.id, other_attributable.id)
+ expect(json_response.pluck('id')).to include(attributable.id, other_attributable.id)
end
end
diff --git a/spec/support/shared_examples/requests/api/graphql/packages/group_and_project_packages_list_shared_examples.rb b/spec/support/shared_examples/requests/api/graphql/packages/group_and_project_packages_list_shared_examples.rb
index f5835460a77..5e9dfc826d4 100644
--- a/spec/support/shared_examples/requests/api/graphql/packages/group_and_project_packages_list_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/graphql/packages/group_and_project_packages_list_shared_examples.rb
@@ -279,11 +279,11 @@ RSpec.shared_examples 'group and project packages query' do
end
def npm_pipeline_ids
- graphql_data_npm_package.dig('pipelines', 'nodes').map { |pipeline| pipeline['id'] }
+ graphql_data_npm_package.dig('pipelines', 'nodes').pluck('id')
end
def composer_pipeline_ids
- graphql_data_composer_package.dig('pipelines', 'nodes').map { |pipeline| pipeline['id'] }
+ graphql_data_composer_package.dig('pipelines', 'nodes').pluck('id')
end
def graphql_data_npm_package
diff --git a/spec/support/shared_examples/requests/api/graphql/packages/package_details_shared_examples.rb b/spec/support/shared_examples/requests/api/graphql/packages/package_details_shared_examples.rb
index b4019d7c232..161f4a02b8c 100644
--- a/spec/support/shared_examples/requests/api/graphql/packages/package_details_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/graphql/packages/package_details_shared_examples.rb
@@ -38,7 +38,7 @@ RSpec.shared_examples 'a package with files' do
context 'with package files pending destruction' do
let_it_be(:package_file_pending_destruction) { create(:package_file, :pending_destruction, package: package) }
- let(:response_package_file_ids) { package_files_response.map { |pf| pf['id'] } }
+ let(:response_package_file_ids) { package_files_response.pluck('id') }
it 'does not return them' do
expect(package.reload.package_files).to include(package_file_pending_destruction)
diff --git a/spec/support/shared_examples/requests/api/labels_api_shared_examples.rb b/spec/support/shared_examples/requests/api/labels_api_shared_examples.rb
index 41d21490343..fba0533251a 100644
--- a/spec/support/shared_examples/requests/api/labels_api_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/labels_api_shared_examples.rb
@@ -9,6 +9,6 @@ RSpec.shared_examples 'fetches labels' do
expect(json_response).to be_an Array
expect(json_response).to all(match_schema('public_api/v4/labels/label'))
expect(json_response.size).to eq(expected_labels.size)
- expect(json_response.map { |r| r['name'] }).to match_array(expected_labels)
+ expect(json_response.pluck('name')).to match_array(expected_labels)
end
end
diff --git a/spec/support/shared_examples/requests/api/milestones_shared_examples.rb b/spec/support/shared_examples/requests/api/milestones_shared_examples.rb
index 1ea11ba3d7c..ee7d0e86771 100644
--- a/spec/support/shared_examples/requests/api/milestones_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/milestones_shared_examples.rb
@@ -52,7 +52,7 @@ RSpec.shared_examples 'group and project milestones' do |route_definition|
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
- expect(json_response.map { |m| m['id'] }).to match_array([closed_milestone.id, other_milestone.id])
+ expect(json_response.pluck('id')).to match_array([closed_milestone.id, other_milestone.id])
end
it 'does not return any milestone if none found' do
@@ -293,7 +293,7 @@ RSpec.shared_examples 'group and project milestones' do |route_definition|
expect(json_response).to be_an Array
# 2 for projects, 3 for group(which has another project with an issue)
expect(json_response.size).to be_between(2, 3)
- expect(json_response.map { |issue| issue['id'] }).to include(issue.id, confidential_issue.id)
+ expect(json_response.pluck('id')).to include(issue.id, confidential_issue.id)
end
it 'does not return confidential issues to team members with guest role' do
@@ -306,7 +306,7 @@ RSpec.shared_examples 'group and project milestones' do |route_definition|
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.size).to eq(1)
- expect(json_response.map { |issue| issue['id'] }).to include(issue.id)
+ expect(json_response.pluck('id')).to include(issue.id)
end
it 'does not return confidential issues to regular users' do
@@ -316,7 +316,7 @@ RSpec.shared_examples 'group and project milestones' do |route_definition|
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.size).to eq(1)
- expect(json_response.map { |issue| issue['id'] }).to include(issue.id)
+ expect(json_response.pluck('id')).to include(issue.id)
end
it 'returns issues ordered by label priority' do
diff --git a/spec/support/shared_examples/requests/api/notes_shared_examples.rb b/spec/support/shared_examples/requests/api/notes_shared_examples.rb
index 0518749452e..b44ff952cdf 100644
--- a/spec/support/shared_examples/requests/api/notes_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/notes_shared_examples.rb
@@ -14,7 +14,7 @@ RSpec.shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
it 'sorts by created_at in descending order by default' do
get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user, admin_mode: user.admin?)
- response_dates = json_response.map { |note| note['created_at'] }
+ response_dates = json_response.pluck('created_at')
expect(json_response.length).to eq(4)
expect(response_dates).to eq(response_dates.sort.reverse)
@@ -42,7 +42,7 @@ RSpec.shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
it 'page breaks first page correctly' do
get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes?per_page=4", user, admin_mode: user.admin?)
- response_ids = json_response.map { |note| note['id'] }
+ response_ids = json_response.pluck('id')
expect(response_ids).to include(@note2.id)
expect(response_ids).not_to include(@first_note.id)
@@ -51,7 +51,7 @@ RSpec.shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
it 'page breaks second page correctly' do
get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes?per_page=4&page=2", user, admin_mode: user.admin?)
- response_ids = json_response.map { |note| note['id'] }
+ response_ids = json_response.pluck('id')
expect(response_ids).not_to include(@note2.id)
expect(response_ids).to include(@first_note.id)
@@ -62,7 +62,7 @@ RSpec.shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
it 'sorts by ascending order when requested' do
get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes?sort=asc", user, admin_mode: user.admin?)
- response_dates = json_response.map { |note| note['created_at'] }
+ response_dates = json_response.pluck('created_at')
expect(json_response.length).to eq(4)
expect(response_dates).to eq(response_dates.sort)
@@ -71,7 +71,7 @@ RSpec.shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
it 'sorts by updated_at in descending order when requested' do
get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes?order_by=updated_at", user, admin_mode: user.admin?)
- response_dates = json_response.map { |note| note['updated_at'] }
+ response_dates = json_response.pluck('updated_at')
expect(json_response.length).to eq(4)
expect(response_dates).to eq(response_dates.sort.reverse)
@@ -80,7 +80,7 @@ RSpec.shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
it 'sorts by updated_at in ascending order when requested' do
get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes?order_by=updated_at&sort=asc", user, admin_mode: user.admin?)
- response_dates = json_response.map { |note| note['updated_at'] }
+ response_dates = json_response.pluck('updated_at')
expect(json_response.length).to eq(4)
expect(response_dates).to eq(response_dates.sort)
diff --git a/spec/support/shared_examples/requests/api/repository_storage_moves_shared_examples.rb b/spec/support/shared_examples/requests/api/repository_storage_moves_shared_examples.rb
index 7df8d6a513d..3913d29e086 100644
--- a/spec/support/shared_examples/requests/api/repository_storage_moves_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/repository_storage_moves_shared_examples.rb
@@ -70,7 +70,7 @@ RSpec.shared_examples 'repository_storage_moves API' do |container_type|
get_container_repository_storage_moves
- json_ids = json_response.map { |storage_move| storage_move['id'] }
+ json_ids = json_response.pluck('id')
expect(json_ids).to eq([storage_move.id, storage_move_middle.id, storage_move_oldest.id])
end
diff --git a/spec/support/shared_examples/services/packages_shared_examples.rb b/spec/support/shared_examples/services/packages_shared_examples.rb
index f63693dbf26..7a4d7f81e96 100644
--- a/spec/support/shared_examples/services/packages_shared_examples.rb
+++ b/spec/support/shared_examples/services/packages_shared_examples.rb
@@ -76,7 +76,7 @@ RSpec.shared_examples 'returns packages' do |container_type, user_type|
subject
expect(json_response.length).to eq(2)
- expect(json_response.map { |package| package['id'] }).to contain_exactly(package1.id, package2.id)
+ expect(json_response.pluck('id')).to contain_exactly(package1.id, package2.id)
end
end
end
@@ -123,7 +123,7 @@ RSpec.shared_examples 'returns packages with subgroups' do |container_type, user
subject
expect(json_response.length).to eq(3)
- expect(json_response.map { |package| package['id'] }).to contain_exactly(package1.id, package2.id, package3.id)
+ expect(json_response.pluck('id')).to contain_exactly(package1.id, package2.id, package3.id)
end
end
end
@@ -138,7 +138,7 @@ RSpec.shared_examples 'package sorting' do |order_by|
it 'returns the sorted packages' do
subject
- expect(json_response.map { |package| package['id'] }).to eq(packages.map(&:id))
+ expect(json_response.pluck('id')).to eq(packages.map(&:id))
end
end
@@ -148,7 +148,7 @@ RSpec.shared_examples 'package sorting' do |order_by|
it 'returns the sorted packages' do
subject
- expect(json_response.map { |package| package['id'] }).to eq(packages.reverse.map(&:id))
+ expect(json_response.pluck('id')).to eq(packages.reverse.map(&:id))
end
end
end
@@ -225,7 +225,7 @@ RSpec.shared_examples 'filters on each package_type' do |is_project: false|
subject
expect(json_response.length).to eq(1)
- expect(json_response.map { |package| package['package_type'] }).to contain_exactly(package_type)
+ expect(json_response.pluck('package_type')).to contain_exactly(package_type)
end
end
end
@@ -253,7 +253,7 @@ RSpec.shared_examples 'with versionless packages' do
it 'does not return the package' do
subject
- expect(json_response.map { |package| package['id'] }).not_to include(versionless_package.id)
+ expect(json_response.pluck('id')).not_to include(versionless_package.id)
end
end
@@ -268,7 +268,7 @@ RSpec.shared_examples 'with versionless packages' do
it 'returns the package' do
subject
- expect(json_response.map { |package| package['id'] }).to include(versionless_package.id)
+ expect(json_response.pluck('id')).to include(versionless_package.id)
end
end
end
@@ -295,7 +295,7 @@ RSpec.shared_examples 'with status param' do
it 'does not return the package' do
subject
- expect(json_response.map { |package| package['id'] }).not_to include(hidden_package.id)
+ expect(json_response.pluck('id')).not_to include(hidden_package.id)
end
end
@@ -309,7 +309,7 @@ RSpec.shared_examples 'with status param' do
it 'returns the package' do
subject
- expect(json_response.map { |package| package['id'] }).to include(hidden_package.id)
+ expect(json_response.pluck('id')).to include(hidden_package.id)
end
end
end
diff --git a/spec/workers/container_registry/cleanup_worker_spec.rb b/spec/workers/container_registry/cleanup_worker_spec.rb
index 72e1243ccb5..955d2175085 100644
--- a/spec/workers/container_registry/cleanup_worker_spec.rb
+++ b/spec/workers/container_registry/cleanup_worker_spec.rb
@@ -46,6 +46,77 @@ RSpec.describe ContainerRegistry::CleanupWorker, :aggregate_failures, feature_ca
end
end
+ context 'with stale ongoing repair details' do
+ let_it_be(:stale_updated_at) { (described_class::STALE_REPAIR_DETAIL_THRESHOLD + 5.minutes).ago }
+ let_it_be(:recent_updated_at) { (described_class::STALE_REPAIR_DETAIL_THRESHOLD - 5.minutes).ago }
+ let_it_be(:old_repair_detail) { create(:container_registry_data_repair_detail, updated_at: stale_updated_at) }
+ let_it_be(:new_repair_detail) { create(:container_registry_data_repair_detail, updated_at: recent_updated_at) }
+
+ it 'deletes them' do
+ expect { perform }.to change { ContainerRegistry::DataRepairDetail.count }.from(2).to(1)
+ expect(ContainerRegistry::DataRepairDetail.all).to contain_exactly(new_repair_detail)
+ end
+ end
+
+ shared_examples 'does not enqueue record repair detail jobs' do
+ it 'does not enqueue record repair detail jobs' do
+ expect(ContainerRegistry::RecordDataRepairDetailWorker).not_to receive(:perform_with_capacity)
+
+ perform
+ end
+ end
+
+ context 'when on gitlab.com', :saas do
+ context 'when the gitlab api is supported' do
+ let(:relation) { instance_double(ActiveRecord::Relation) }
+
+ before do
+ allow(ContainerRegistry::GitlabApiClient).to receive(:supports_gitlab_api?).and_return(true)
+ allow(Project).to receive(:pending_data_repair_analysis).and_return(relation)
+ end
+
+ context 'when there are pending projects to analyze' do
+ before do
+ allow(relation).to receive(:exists?).and_return(true)
+ end
+
+ it "enqueues record repair detail jobs" do
+ expect(ContainerRegistry::RecordDataRepairDetailWorker).to receive(:perform_with_capacity)
+
+ perform
+ end
+ end
+
+ context 'when there are no pending projects to analyze' do
+ before do
+ allow(relation).to receive(:exists?).and_return(false)
+ end
+
+ it_behaves_like 'does not enqueue record repair detail jobs'
+ end
+ end
+
+ context 'when the Gitlab API is not supported' do
+ before do
+ allow(ContainerRegistry::GitlabApiClient).to receive(:supports_gitlab_api?).and_return(false)
+ end
+
+ it_behaves_like 'does not enqueue record repair detail jobs'
+ end
+ end
+
+ context 'when not on Gitlab.com' do
+ it_behaves_like 'does not enqueue record repair detail jobs'
+ end
+
+ context 'when registry_data_repair_worker feature is disabled' do
+ before do
+ stub_feature_flags(registry_data_repair_worker: false)
+ end
+
+ it_behaves_like 'does not enqueue record repair detail jobs'
+ end
+
context 'for counts logging' do
let_it_be(:delete_started_at) { (described_class::STALE_DELETE_THRESHOLD + 5.minutes).ago }
let_it_be(:stale_delete_container_repository) do
diff --git a/spec/workers/container_registry/record_data_repair_detail_worker_spec.rb b/spec/workers/container_registry/record_data_repair_detail_worker_spec.rb
new file mode 100644
index 00000000000..f107144d397
--- /dev/null
+++ b/spec/workers/container_registry/record_data_repair_detail_worker_spec.rb
@@ -0,0 +1,191 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ContainerRegistry::RecordDataRepairDetailWorker, :aggregate_failures, :clean_gitlab_redis_shared_state,
+ feature_category: :container_registry do
+ include ExclusiveLeaseHelpers
+
+ let(:worker) { described_class.new }
+
+ describe '#perform_work' do
+ subject(:perform_work) { worker.perform_work }
+
+ context 'with no work to do - no projects pending analysis' do
+ it 'will not try to get an exclusive lease and connect to the endpoint' do
+ allow(Project).to receive(:pending_data_repair_analysis).and_return([])
+ expect(::Gitlab::ExclusiveLease).not_to receive(:new)
+
+ expect(::ContainerRegistry::GitlabApiClient).not_to receive(:each_sub_repositories_with_tag_page)
+
+ perform_work
+ end
+ end
+
+ context 'with work to do' do
+ let_it_be(:path) { 'build/cng/docker-alpine' }
+ let_it_be(:group) { create(:group, path: 'build') }
+ let_it_be(:project) { create(:project, name: 'cng', namespace: group) }
+
+ let_it_be(:container_repository) { create(:container_repository, project: project, name: "docker-alpine") }
+ let_it_be(:lease_key) { "container_registry_data_repair_detail_worker:#{project.id}" }
+
+ before do
+ allow(ContainerRegistry::GitlabApiClient).to receive(:each_sub_repositories_with_tag_page)
+ allow(ContainerRegistry::GitlabApiClient).to receive(:supports_gitlab_api?).and_return(true)
+ end
+
+ context 'when on Gitlab.com', :saas do
+ it 'obtains exclusive lease on the project' do
+ expect(Project).to receive(:pending_data_repair_analysis).and_call_original
+ expect_to_obtain_exclusive_lease("container_registry_data_repair_detail_worker:#{project.id}",
+ timeout: described_class::LEASE_TIMEOUT)
+ expect_to_cancel_exclusive_lease("container_registry_data_repair_detail_worker:#{project.id}", 'uuid')
+
+ perform_work
+ end
+
+ it 'queries how many are existing repositories and counts the missing ones' do
+ stub_exclusive_lease("container_registry_data_repair_detail_worker:#{project.id}",
+ timeout: described_class::LEASE_TIMEOUT)
+ allow(ContainerRegistry::GitlabApiClient).to receive(:each_sub_repositories_with_tag_page)
+ .with(path: project.full_path, page_size: 50).and_yield(
+ [
+ { "path" => container_repository.path },
+ { "path" => 'missing1/repository' },
+ { "path" => 'missing2/repository' }
+ ]
+ )
+
+ expect(worker).not_to receive(:log_extra_metadata_on_done)
+ expect { perform_work }.to change { ContainerRegistry::DataRepairDetail.count }.from(0).to(1)
+ expect(ContainerRegistry::DataRepairDetail.first).to have_attributes(project: project, missing_count: 2)
+ end
+
+ it 'logs invalid paths' do
+ stub_exclusive_lease("container_registry_data_repair_detail_worker:#{project.id}",
+ timeout: described_class::LEASE_TIMEOUT)
+ valid_path = ContainerRegistry::Path.new('valid/path')
+ invalid_path = ContainerRegistry::Path.new('invalid/path')
+ allow(valid_path).to receive(:valid?).and_return(true)
+ allow(invalid_path).to receive(:valid?).and_return(false)
+
+ allow(ContainerRegistry::GitlabApiClient).to receive(:each_sub_repositories_with_tag_page)
+ .with(path: project.full_path, page_size: 50).and_yield(
+ [
+ { "path" => valid_path.to_s },
+ { "path" => invalid_path.to_s }
+ ]
+ )
+
+ allow(ContainerRegistry::Path).to receive(:new).with(valid_path.to_s).and_return(valid_path)
+ allow(ContainerRegistry::Path).to receive(:new).with(invalid_path.to_s).and_return(invalid_path)
+
+ expect(worker).to receive(:log_extra_metadata_on_done).with(
+ :invalid_paths_parsed_in_container_repository_repair,
+ "invalid/path"
+ )
+ perform_work
+ end
+
+ it_behaves_like 'an idempotent worker' do
+ it 'creates a data repair detail' do
+ expect { perform_work }.to change { ContainerRegistry::DataRepairDetail.count }.from(0).to(1)
+ expect(project.container_registry_data_repair_detail).to be_present
+ end
+ end
+
+ context 'when the lease cannot be obtained' do
+ before do
+ stub_exclusive_lease_taken(lease_key, timeout: described_class::LEASE_TIMEOUT)
+ end
+
+ it 'logs an error and does not proceed' do
+ expect(worker).to receive(:log_lease_taken)
+ expect(ContainerRegistry::GitlabApiClient).not_to receive(:each_sub_repositories_with_tag_page)
+
+ perform_work
+ end
+
+ it 'does not create the data repair detail' do
+ perform_work
+
+ expect(project.reload.container_registry_data_repair_detail).to be_nil
+ end
+ end
+
+ context 'when an error occurs' do
+ before do
+ stub_exclusive_lease("container_registry_data_repair_detail_worker:#{project.id}",
+ timeout: described_class::LEASE_TIMEOUT)
+ allow(ContainerRegistry::GitlabApiClient).to receive(:each_sub_repositories_with_tag_page)
+ .with(path: project.full_path, page_size: 50).and_raise(RuntimeError)
+ end
+
+ it 'logs the error' do
+ expect(::Gitlab::ErrorTracking).to receive(:log_exception)
+ .with(instance_of(RuntimeError), class: described_class.name)
+
+ perform_work
+ end
+
+ it 'sets the status of the repair detail to failed' do
+ expect { perform_work }.to change { ContainerRegistry::DataRepairDetail.failed.count }.from(0).to(1)
+ expect(project.reload.container_registry_data_repair_detail.failed?).to eq(true)
+ end
+ end
+ end
+
+ context 'when not on Gitlab.com' do
+ it 'will not do anything' do
+ expect(::Gitlab::ExclusiveLease).not_to receive(:new)
+ expect(::ContainerRegistry::GitlabApiClient).not_to receive(:each_sub_repositories_with_tag_page)
+
+ perform_work
+ end
+ end
+ end
+ end
+
+ describe '#max_running_jobs' do
+ subject { worker.max_running_jobs }
+
+ it { is_expected.to eq(described_class::MAX_CAPACITY) }
+ end
+
+ describe '#remaining_work_count' do
+ let_it_be(:pending_projects) do
+ create_list(:project, described_class::MAX_CAPACITY + 2)
+ end
+
+ subject { worker.remaining_work_count }
+
+ context 'when on Gitlab.com', :saas do
+ before do
+ allow(ContainerRegistry::GitlabApiClient).to receive(:supports_gitlab_api?).and_return(true)
+ end
+
+ it { is_expected.to eq(described_class::MAX_CAPACITY + 1) }
+
+ context 'when the Gitlab API is not supported' do
+ before do
+ allow(ContainerRegistry::GitlabApiClient).to receive(:supports_gitlab_api?).and_return(false)
+ end
+
+ it { is_expected.to eq(0) }
+ end
+ end
+
+ context 'when not on Gitlab.com' do
+ it { is_expected.to eq(0) }
+ end
+
+ context 'when registry_data_repair_worker feature is disabled' do
+ before do
+ stub_feature_flags(registry_data_repair_worker: false)
+ end
+
+ it { is_expected.to eq(0) }
+ end
+ end
+end
diff --git a/spec/workers/every_sidekiq_worker_spec.rb b/spec/workers/every_sidekiq_worker_spec.rb
index 4309ec24a9e..2c2cd7e9960 100644
--- a/spec/workers/every_sidekiq_worker_spec.rb
+++ b/spec/workers/every_sidekiq_worker_spec.rb
@@ -191,6 +191,7 @@ RSpec.describe 'Every Sidekiq worker', feature_category: :shared do
'Clusters::Cleanup::ServiceAccountWorker' => 3,
'ContainerExpirationPolicies::CleanupContainerRepositoryWorker' => 0,
'ContainerRegistry::DeleteContainerRepositoryWorker' => 0,
+ 'ContainerRegistry::RecordDataRepairDetailWorker' => 0,
'CreateCommitSignatureWorker' => 3,
'CreateGithubWebhookWorker' => 3,
'CreateNoteDiffFileWorker' => 3,