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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-06-15 15:10:11 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-06-15 15:10:11 +0300
commit96acc69fae1ee7d559ba7eaa4e8304c8261525e3 (patch)
treeb1ed433da35a415cab8ed544d85ac4c939efab0e
parenta1498861799d1695682d72870580a6c3fb5ca3cf (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.gitlab/ci/global.gitlab-ci.yml20
-rw-r--r--.gitlab/ci/rails.gitlab-ci.yml99
-rw-r--r--GITALY_SERVER_VERSION2
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.lock4
-rw-r--r--app/assets/javascripts/ci_settings_pipeline_triggers/components/triggers_list.vue2
-rw-r--r--app/assets/javascripts/emoji/components/picker.vue2
-rw-r--r--app/assets/javascripts/environments/components/environment_actions.vue2
-rw-r--r--app/assets/javascripts/environments/components/environments_app.vue2
-rw-r--r--app/assets/javascripts/environments/components/stop_environment_modal.vue2
-rw-r--r--app/assets/javascripts/error_tracking/components/error_tracking_list.vue2
-rw-r--r--app/assets/javascripts/import_entities/import_groups/components/import_table_row.vue4
-rw-r--r--app/assets/javascripts/issuable_list/components/issuable_tabs.vue2
-rw-r--r--app/assets/javascripts/packages/details/components/package_files.vue2
-rw-r--r--app/assets/javascripts/pages/projects/shared/permissions/components/project_feature_setting.vue2
-rw-r--r--app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue2
-rw-r--r--app/assets/javascripts/reports/codequality_report/components/codequality_issue_body.vue2
-rw-r--r--app/assets/javascripts/runner/constants.js1
-rw-r--r--app/assets/javascripts/runner/graphql/get_runners.query.graphql2
-rw-r--r--app/assets/javascripts/runner/runner_list/runner_list_app.vue2
-rw-r--r--app/assets/javascripts/runner/runner_list/runner_search_utils.js (renamed from app/assets/javascripts/runner/runner_list/filtered_search_utils.js)89
-rw-r--r--app/assets/javascripts/search/topbar/components/app.vue2
-rw-r--r--app/assets/javascripts/sidebar/components/severity/sidebar_severity.vue4
-rw-r--r--app/assets/javascripts/user_lists/components/user_list_form.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_expandable_section.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue4
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/terraform/mr_widget_terraform_container.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/terraform/terraform_plan.vue4
-rw-r--r--app/assets/javascripts/vue_shared/components/filtered_search_bar/filtered_search_utils.js65
-rw-r--r--app/assets/javascripts/vue_shared/components/registry/list_item.vue6
-rw-r--r--app/assets/javascripts/vue_shared/components/registry/registry_search.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/runner_instructions/runner_instructions_modal.vue4
-rw-r--r--app/assets/stylesheets/framework.scss1
-rw-r--r--app/assets/stylesheets/framework/blank.scss118
-rw-r--r--app/controllers/clusters/applications_controller.rb2
-rw-r--r--app/controllers/concerns/membership_actions.rb30
-rw-r--r--app/controllers/groups/group_members_controller.rb12
-rw-r--r--app/controllers/projects/feature_flags_controller.rb16
-rw-r--r--app/controllers/projects/project_members_controller.rb12
-rw-r--r--app/finders/feature_flags_finder.rb11
-rw-r--r--app/helpers/search_helper.rb3
-rw-r--r--app/models/ci/job_artifact.rb2
-rw-r--r--app/models/clusters/applications/fluentd.rb121
-rw-r--r--app/models/clusters/cluster.rb2
-rw-r--r--app/serializers/cluster_application_entity.rb1
-rw-r--r--app/services/ci/job_artifacts/create_service.rb5
-rw-r--r--app/services/clusters/applications/base_service.rb10
-rw-r--r--app/services/clusters/parse_cluster_applications_artifact_service.rb94
-rw-r--r--app/services/feature_flags/disable_service.rb46
-rw-r--r--app/services/feature_flags/enable_service.rb93
-rw-r--r--app/services/search/project_service.rb4
-rw-r--r--app/services/search_service.rb4
-rw-r--r--app/views/dashboard/todos/index.html.haml2
-rw-r--r--app/views/layouts/fullscreen.html.haml2
-rw-r--r--app/views/projects/empty.html.haml3
-rw-r--r--app/views/search/_results.html.haml4
-rw-r--r--app/views/shared/wikis/diff.html.haml2
-rw-r--r--app/views/shared/wikis/edit.html.haml2
-rw-r--r--app/views/shared/wikis/pages.html.haml2
-rw-r--r--config/feature_flags/development/advanced_search_multi_project_select.yml (renamed from config/feature_flags/development/remove_legacy_flags.yml)8
-rw-r--r--config/feature_flags/development/feature_flag_api.yml8
-rw-r--r--config/feature_flags/development/remove_legacy_flags_override.yml8
-rw-r--r--config/metrics/counts_28d/20210421144352_i_code_review_click_single_file_mode_setting_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210421145818_i_code_review_click_file_browser_setting_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210421145945_i_code_review_click_whitespace_setting_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210422101516_i_code_review_diff_view_inline_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210422101613_i_code_review_diff_view_parallel_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210422101753_i_code_review_file_browser_tree_view_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210422101852_i_code_review_file_browser_list_view_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210422101928_i_code_review_diff_show_whitespace_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210422102010_i_code_review_diff_hide_whitespace_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210422102121_i_code_review_diff_single_file_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210422102202_i_code_review_diff_multiple_files_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210427102618_code_review_category_monthly_active_users.yml2
-rw-r--r--config/metrics/counts_28d/20210427103010_code_review_extension_category_monthly_active_users.yml2
-rw-r--r--config/metrics/counts_28d/20210427103119_code_review_group_monthly_active_users.yml2
-rw-r--r--config/metrics/counts_28d/20210427105033_pipeline_authoring_total_unique_counts_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210427213346_geo_secondary_web_oauth_users.yml2
-rw-r--r--config/metrics/counts_28d/20210514013545_i_code_review_user_resolve_conflict_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210514013549_i_code_review_user_load_conflict_ui_monthly.yml2
-rw-r--r--config/metrics/counts_28d/20210607113556_i_code_review_click_diff_view_setting_monthly.yml2
-rw-r--r--config/metrics/counts_7d/20210421144349_i_code_review_click_single_file_mode_setting_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210421145814_i_code_review_click_file_browser_setting_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210421145942_i_code_review_click_whitespace_setting_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210422101512_i_code_review_diff_view_inline_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210422101609_i_code_review_diff_view_parallel_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210422101750_i_code_review_file_browser_tree_view_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210422101849_i_code_review_file_browser_list_view_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210422101925_i_code_review_diff_show_whitespace_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210422102007_i_code_review_diff_hide_whitespace_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210422102118_i_code_review_diff_single_file_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210422102159_i_code_review_diff_multiple_files_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210427103328_code_review_group_monthly_active_users.yml2
-rw-r--r--config/metrics/counts_7d/20210427103407_code_review_category_monthly_active_users.yml2
-rw-r--r--config/metrics/counts_7d/20210427103452_code_review_extension_category_monthly_active_users.yml2
-rw-r--r--config/metrics/counts_7d/20210427105030_pipeline_authoring_total_unique_counts_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210514013544_i_code_review_user_load_conflict_ui_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210514013545_i_code_review_user_resolve_conflict_weekly.yml2
-rw-r--r--config/metrics/counts_7d/20210607113552_i_code_review_click_diff_view_setting_weekly.yml2
-rw-r--r--config/metrics/counts_all/20210423005644_i_analytics_dev_ops_adoption.yml2
-rw-r--r--config/metrics/counts_all/20210427212450_geo_secondary_web_oauth_users.yml2
-rw-r--r--config/metrics/counts_all/20210428142406_users_viewing_analytics_group_devops_adoption.yml2
-rw-r--r--config/metrics/counts_all/20210502045402_ci_runners_instance_type_active.yml2
-rw-r--r--config/metrics/counts_all/20210502050341_ci_runners_group_type_active.yml2
-rw-r--r--config/metrics/counts_all/20210502050834_ci_runners_project_type_active.yml2
-rw-r--r--config/metrics/counts_all/20210502050942_ci_runners_online.yml2
-rw-r--r--config/metrics/counts_all/20210502051651_ci_runners_instance_type_active_online.yml2
-rw-r--r--config/metrics/counts_all/20210502051922_ci_runners_group_type_active_online.yml2
-rw-r--r--config/metrics/counts_all/20210502052036_ci_runners_project_type_active_online.yml2
-rw-r--r--config/metrics/counts_all/20210510201537_in_product_marketing_email_create_0_sent.yml2
-rw-r--r--config/metrics/counts_all/20210510201919_in_product_marketing_email_create_0_cta_clicked.yml2
-rw-r--r--config/metrics/counts_all/20210510202148_in_product_marketing_email_create_1_sent.yml2
-rw-r--r--config/metrics/counts_all/20210510202356_in_product_marketing_email_create_1_cta_clicked.yml2
-rw-r--r--config/metrics/counts_all/20210510202604_in_product_marketing_email_create_2_sent.yml2
-rw-r--r--config/metrics/counts_all/20210510202724_in_product_marketing_email_create_2_cta_clicked.yml2
-rw-r--r--config/metrics/counts_all/20210510202807_in_product_marketing_email_verify_0_sent.yml2
-rw-r--r--config/metrics/counts_all/20210510202943_in_product_marketing_email_verify_0_cta_clicked.yml2
-rw-r--r--config/metrics/counts_all/20210510202955_in_product_marketing_email_verify_1_sent.yml2
-rw-r--r--config/metrics/counts_all/20210510203005_in_product_marketing_email_verify_1_cta_clicked.yml2
-rw-r--r--config/metrics/counts_all/20210510203015_in_product_marketing_email_verify_2_sent.yml2
-rw-r--r--config/metrics/counts_all/20210510203025_in_product_marketing_email_verify_2_cta_clicked.yml2
-rw-r--r--config/metrics/counts_all/20210510203035_in_product_marketing_email_trial_0_sent.yml2
-rw-r--r--config/metrics/counts_all/20210510203044_in_product_marketing_email_trial_0_cta_clicked.yml2
-rw-r--r--config/metrics/counts_all/20210510203054_in_product_marketing_email_trial_1_sent.yml2
-rw-r--r--config/metrics/counts_all/20210510203104_in_product_marketing_email_trial_1_cta_clicked.yml2
-rw-r--r--config/metrics/counts_all/20210510203114_in_product_marketing_email_trial_2_sent.yml2
-rw-r--r--config/metrics/counts_all/20210510203124_in_product_marketing_email_trial_2_cta_clicked.yml2
-rw-r--r--config/metrics/counts_all/20210510203134_in_product_marketing_email_team_0_sent.yml2
-rw-r--r--config/metrics/counts_all/20210510203143_in_product_marketing_email_team_0_cta_clicked.yml2
-rw-r--r--config/metrics/counts_all/20210510203153_in_product_marketing_email_team_1_sent.yml2
-rw-r--r--config/metrics/counts_all/20210510203203_in_product_marketing_email_team_1_cta_clicked.yml2
-rw-r--r--config/metrics/counts_all/20210510203213_in_product_marketing_email_team_2_sent.yml2
-rw-r--r--config/metrics/counts_all/20210510203223_in_product_marketing_email_team_2_cta_clicked.yml2
-rw-r--r--config/metrics/counts_all/20210518081225_in_product_marketing_email_experience_0_sent.yml2
-rw-r--r--config/metrics/schema.json4
-rw-r--r--danger/commit_messages/Dangerfile147
-rw-r--r--doc/api/deployments.md99
-rw-r--r--doc/api/feature_flag_specs.md292
-rw-r--r--doc/api/feature_flags_legacy.md314
-rw-r--r--doc/api/resource_access_tokens.md6
-rw-r--r--doc/api/status_checks.md4
-rw-r--r--doc/development/pipelines.md9
-rw-r--r--doc/development/usage_ping/dictionary.md198
-rw-r--r--doc/development/usage_ping/metrics_dictionary.md10
-rw-r--r--doc/user/project/merge_requests/img/status_checks_branches_selector_v14_0.pngbin0 -> 5460 bytes
-rw-r--r--doc/user/project/merge_requests/img/status_checks_create_form_v14_0.pngbin0 -> 11913 bytes
-rw-r--r--doc/user/project/merge_requests/img/status_checks_delete_modal_v14_0.pngbin0 -> 5662 bytes
-rw-r--r--doc/user/project/merge_requests/img/status_checks_list_view_v14_0.pngbin0 -> 15958 bytes
-rw-r--r--doc/user/project/merge_requests/img/status_checks_update_form_v14_0.pngbin0 -> 13348 bytes
-rw-r--r--doc/user/project/merge_requests/status_checks.md179
-rw-r--r--doc/user/project/settings/index.md1
-rw-r--r--generator_templates/usage_metric_definition/metric_definition.yml1
-rw-r--r--lib/api/api.rb1
-rw-r--r--lib/api/feature_flag_scopes.rb160
-rw-r--r--lib/api/feature_flags.rb52
-rw-r--r--lib/api/unleash.rb16
-rw-r--r--lib/gitlab/ci/config/entry/reports.rb2
-rw-r--r--lib/gitlab/ci/templates/Managed-Cluster-Applications.gitlab-ci.yml2
-rw-r--r--lib/gitlab/kubernetes/helm/parsers/list_v2.rb37
-rw-r--r--lib/gitlab/project_search_results.rb13
-rw-r--r--locale/gitlab.pot15
-rw-r--r--package.json2
-rw-r--r--spec/controllers/projects/feature_flags_controller_spec.rb82
-rw-r--r--spec/factories/ci/job_artifacts.rb15
-rw-r--r--spec/factories/clusters/applications/helm.rb6
-rw-r--r--spec/factories/clusters/clusters.rb1
-rw-r--r--spec/factories/operations/feature_flag_scopes.rb2
-rw-r--r--spec/factories/operations/feature_flags.rb1
-rw-r--r--spec/features/projects/feature_flags/user_sees_feature_flag_list_spec.rb58
-rw-r--r--spec/features/projects/feature_flags/user_updates_feature_flag_spec.rb8
-rw-r--r--spec/finders/feature_flags_finder_spec.rb22
-rw-r--r--spec/fixtures/api/schemas/cluster_status.json1
-rw-r--r--spec/fixtures/helm/helm_list_v2_cilium_deployed.json.gzbin302 -> 0 bytes
-rw-r--r--spec/fixtures/helm/helm_list_v2_cilium_failed.json.gzbin304 -> 0 bytes
-rw-r--r--spec/fixtures/helm/helm_list_v2_cilium_missing.json.gzbin320 -> 0 bytes
-rw-r--r--spec/fixtures/helm/helm_list_v2_empty_blob.json.gzbin81 -> 0 bytes
-rw-r--r--spec/fixtures/helm/helm_list_v2_prometheus_deployed.json.gzbin338 -> 0 bytes
-rw-r--r--spec/fixtures/helm/helm_list_v2_prometheus_failed.json.gzbin339 -> 0 bytes
-rw-r--r--spec/fixtures/helm/helm_list_v2_prometheus_missing.json.gzbin320 -> 0 bytes
-rw-r--r--spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric.yml1
-rw-r--r--spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_ee.yml1
-rw-r--r--spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_name_suggestions.yml1
-rw-r--r--spec/frontend/packages/shared/components/__snapshots__/package_list_row_spec.js.snap4
-rw-r--r--spec/frontend/runner/runner_list/runner_search_utils_spec.js (renamed from spec/frontend/runner/runner_list/filtered_search_utils_spec.js)84
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_utils_spec.js75
-rw-r--r--spec/graphql/resolvers/concerns/caching_array_resolver_spec.rb1
-rw-r--r--spec/graphql/resolvers/package_details_resolver_spec.rb1
-rw-r--r--spec/lib/gitlab/kubernetes/helm/parsers/list_v2_spec.rb100
-rw-r--r--spec/lib/gitlab/project_search_results_spec.rb35
-rw-r--r--spec/models/clusters/applications/fluentd_spec.rb71
-rw-r--r--spec/models/operations/feature_flag_scope_spec.rb4
-rw-r--r--spec/models/operations/feature_flag_spec.rb8
-rw-r--r--spec/requests/api/feature_flag_scopes_spec.rb319
-rw-r--r--spec/requests/api/feature_flags_spec.rb278
-rw-r--r--spec/requests/api/unleash_spec.rb188
-rw-r--r--spec/serializers/cluster_application_entity_spec.rb11
-rw-r--r--spec/services/ci/job_artifacts/create_service_spec.rb47
-rw-r--r--spec/services/clusters/parse_cluster_applications_artifact_service_spec.rb126
-rw-r--r--spec/services/feature_flags/disable_service_spec.rb92
-rw-r--r--spec/services/feature_flags/enable_service_spec.rb154
-rw-r--r--spec/services/feature_flags/update_service_spec.rb145
-rw-r--r--spec/support/helpers/feature_flag_helpers.rb2
-rw-r--r--spec/support/helpers/graphql_helpers.rb4
-rw-r--r--spec/support/shared_examples/services/clusters/parse_cluster_applications_artifact_shared_examples.rb89
-rw-r--r--spec/tooling/danger/project_helper_spec.rb10
-rw-r--r--tooling/danger/project_helper.rb1
-rw-r--r--vendor/fluentd/values.yaml18
-rw-r--r--yarn.lock8
208 files changed, 1105 insertions, 3649 deletions
diff --git a/.gitlab/ci/global.gitlab-ci.yml b/.gitlab/ci/global.gitlab-ci.yml
index 5d17fad0c47..ba49ddfce9d 100644
--- a/.gitlab/ci/global.gitlab-ci.yml
+++ b/.gitlab/ci/global.gitlab-ci.yml
@@ -181,6 +181,15 @@
- *node-modules-cache-push
- *assets-cache-push
+.use-pg11:
+ image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.7.2.patched-golang-1.16-git-2.31-lfs-2.9-chrome-89-node-14.15-yarn-1.22-postgresql-11-graphicsmagick-1.3.36"
+ services:
+ - name: postgres:11.6
+ command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
+ - name: redis:5.0-alpine
+ variables:
+ POSTGRES_HOST_AUTH_METHOD: trust
+
.use-pg12:
image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.7.2.patched-golang-1.16-git-2.31-lfs-2.9-chrome-89-node-14.15-yarn-1.22-postgresql-12-graphicsmagick-1.3.36"
services:
@@ -190,6 +199,17 @@
variables:
POSTGRES_HOST_AUTH_METHOD: trust
+.use-pg11-ee:
+ image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.7.2.patched-golang-1.16-git-2.31-lfs-2.9-chrome-89-node-14.15-yarn-1.22-postgresql-11-graphicsmagick-1.3.36"
+ services:
+ - name: postgres:11.6
+ command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
+ - name: redis:5.0-alpine
+ - name: elasticsearch:7.11.1
+ command: ["elasticsearch", "-E", "discovery.type=single-node"]
+ variables:
+ POSTGRES_HOST_AUTH_METHOD: trust
+
.use-pg12-ee:
image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.7.2.patched-golang-1.16-git-2.31-lfs-2.9-chrome-89-node-14.15-yarn-1.22-postgresql-12-graphicsmagick-1.3.36"
services:
diff --git a/.gitlab/ci/rails.gitlab-ci.yml b/.gitlab/ci/rails.gitlab-ci.yml
index c4d393eb16c..b74c8ebf575 100644
--- a/.gitlab/ci/rails.gitlab-ci.yml
+++ b/.gitlab/ci/rails.gitlab-ci.yml
@@ -58,6 +58,11 @@
- !reference [.base-script, script]
- rspec_paralellized_job "--tag ~quarantine --tag ~geo --tag level:migration"
+.rspec-base-pg11:
+ extends:
+ - .rspec-base
+ - .use-pg11
+
.rspec-base-pg12:
extends:
- .rspec-base
@@ -70,6 +75,11 @@
- .use-pg12
needs: ["setup-test-env", "retrieve-tests-metadata", "compile-test-assets as-if-foss", "detect-tests"]
+.rspec-ee-base-pg11:
+ extends:
+ - .rspec-base
+ - .use-pg11-ee
+
.rspec-ee-base-pg12:
extends:
- .rspec-base
@@ -81,6 +91,11 @@
- !reference [.base-script, script]
- rspec_paralellized_job "--tag ~quarantine --tag geo"
+.rspec-ee-base-geo-pg11:
+ extends:
+ - .rspec-ee-base-geo
+ - .use-pg11-ee
+
.rspec-ee-base-geo-pg12:
extends:
- .rspec-ee-base-geo
@@ -277,6 +292,16 @@ rspec system pg12 minimal:
- .minimal-rspec-tests
- .rails:rules:ee-and-foss-system:minimal
+# Dedicated job to test DB library code against PG11.
+# Note that these are already tested against PG12 in the `rspec unit pg12` / `rspec-ee unit pg12` jobs.
+rspec db-library-code pg11:
+ extends:
+ - .rspec-base-pg11
+ - .rails:rules:ee-and-foss-db-library-code
+ script:
+ - !reference [.base-script, script]
+ - rspec_db_library_code
+
rspec fast_spec_helper:
extends:
- .rspec-base-pg12
@@ -637,6 +662,80 @@ db:rollback geo:
# EE: default refs (MRs, default branch, schedules) jobs #
##################################################
+##########################################
+# EE/FOSS: default branch nightly scheduled jobs #
+rspec migration pg11:
+ extends:
+ - .rspec-base-pg11
+ - .rspec-base-migration
+ - .rails:rules:default-branch-schedule-nightly--code-backstage
+ - .rspec-migration-parallel
+
+rspec unit pg11:
+ extends:
+ - .rspec-base-pg11
+ - .rails:rules:default-branch-schedule-nightly--code-backstage
+ - .rspec-unit-parallel
+
+rspec integration pg11:
+ extends:
+ - .rspec-base-pg11
+ - .rails:rules:default-branch-schedule-nightly--code-backstage
+ - .rspec-integration-parallel
+
+rspec system pg11:
+ extends:
+ - .rspec-base-pg11
+ - .rails:rules:default-branch-schedule-nightly--code-backstage
+ - .rspec-system-parallel
+# EE/FOSS: default branch nightly scheduled jobs #
+##########################################
+
+#####################################
+# EE: default branch nightly scheduled jobs #
+rspec-ee migration pg11:
+ extends:
+ - .rspec-ee-base-pg11
+ - .rspec-base-migration
+ - .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
+ - .rspec-ee-migration-parallel
+
+rspec-ee unit pg11:
+ extends:
+ - .rspec-ee-base-pg11
+ - .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
+ - .rspec-ee-unit-parallel
+
+rspec-ee integration pg11:
+ extends:
+ - .rspec-ee-base-pg11
+ - .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
+ - .rspec-ee-integration-parallel
+
+rspec-ee system pg11:
+ extends:
+ - .rspec-ee-base-pg11
+ - .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
+ - .rspec-ee-system-parallel
+
+rspec-ee unit pg11 geo:
+ extends:
+ - .rspec-ee-base-geo-pg11
+ - .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
+ - .rspec-ee-unit-geo-parallel
+
+rspec-ee integration pg11 geo:
+ extends:
+ - .rspec-ee-base-geo-pg11
+ - .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
+
+rspec-ee system pg11 geo:
+ extends:
+ - .rspec-ee-base-geo-pg11
+ - .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
+# EE: default branch nightly scheduled jobs #
+#####################################
+
##################################################
# EE: Canonical MR pipelines
rspec fail-fast:
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index b6b02e5ce0e..ad59f7f93a8 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-c50b0080e9996e5db5eb4d75dfc3811618812798
+56aaf62b7d7045b9f6bdcd25566c005e5eca72fd
diff --git a/Gemfile b/Gemfile
index c8f3d5c6855..d6461e5f028 100644
--- a/Gemfile
+++ b/Gemfile
@@ -402,7 +402,7 @@ group :development, :test do
end
group :development, :test, :danger do
- gem 'gitlab-dangerfiles', '~> 2.0.0', require: false
+ gem 'gitlab-dangerfiles', '~> 2.1.2', require: false
end
group :development, :test, :coverage do
diff --git a/Gemfile.lock b/Gemfile.lock
index fc257672822..323353d61ce 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -451,7 +451,7 @@ GEM
terminal-table (~> 1.5, >= 1.5.1)
gitlab-chronic (0.10.5)
numerizer (~> 0.2)
- gitlab-dangerfiles (2.0.0)
+ gitlab-dangerfiles (2.1.2)
danger-gitlab
gitlab-experiment (0.5.4)
activesupport (>= 3.0)
@@ -1474,7 +1474,7 @@ DEPENDENCIES
gitaly (~> 13.12.0.pre.rc1)
github-markup (~> 1.7.0)
gitlab-chronic (~> 0.10.5)
- gitlab-dangerfiles (~> 2.0.0)
+ gitlab-dangerfiles (~> 2.1.2)
gitlab-experiment (~> 0.5.4)
gitlab-fog-azure-rm (~> 1.1.1)
gitlab-fog-google (~> 1.13)
diff --git a/app/assets/javascripts/ci_settings_pipeline_triggers/components/triggers_list.vue b/app/assets/javascripts/ci_settings_pipeline_triggers/components/triggers_list.vue
index bc1e401d373..77ec1f1af47 100644
--- a/app/assets/javascripts/ci_settings_pipeline_triggers/components/triggers_list.vue
+++ b/app/assets/javascripts/ci_settings_pipeline_triggers/components/triggers_list.vue
@@ -93,7 +93,7 @@ export default {
placement="top"
class="trigger-description gl-display-flex"
>
- <div class="gl-flex-fill-1 gl-text-truncate">{{ item.description }}</div>
+ <div class="gl-flex-grow-1 gl-text-truncate">{{ item.description }}</div>
</tooltip-on-truncate>
</template>
<template #cell(owner)="{ item }">
diff --git a/app/assets/javascripts/emoji/components/picker.vue b/app/assets/javascripts/emoji/components/picker.vue
index 78ba2aabcf8..dc3eac0cd0c 100644
--- a/app/assets/javascripts/emoji/components/picker.vue
+++ b/app/assets/javascripts/emoji/components/picker.vue
@@ -111,7 +111,7 @@ export default {
'gl-text-body! emoji-picker-category-active': index === currentCategory,
}"
type="button"
- class="gl-border-0 gl-border-b-2 gl-border-b-solid gl-flex-fill-1 gl-text-gray-300 gl-pt-3 gl-pb-3 gl-bg-transparent emoji-picker-category-tab"
+ class="gl-border-0 gl-border-b-2 gl-border-b-solid gl-flex-grow-1 gl-text-gray-300 gl-pt-3 gl-pb-3 gl-bg-transparent emoji-picker-category-tab"
:aria-label="category.name"
@click="scrollToCategory(category.name)"
>
diff --git a/app/assets/javascripts/environments/components/environment_actions.vue b/app/assets/javascripts/environments/components/environment_actions.vue
index 8911380290a..542b8c9219d 100644
--- a/app/assets/javascripts/environments/components/environment_actions.vue
+++ b/app/assets/javascripts/environments/components/environment_actions.vue
@@ -89,7 +89,7 @@ export default {
data-testid="manual-action-link"
@click="onClickAction(action)"
>
- <span class="gl-flex-fill-1">{{ action.name }}</span>
+ <span class="gl-flex-grow-1">{{ action.name }}</span>
<span v-if="action.scheduledAt" class="gl-text-gray-500 float-right">
<gl-icon name="clock" />
{{ remainingTime(action) }}
diff --git a/app/assets/javascripts/environments/components/environments_app.vue b/app/assets/javascripts/environments/components/environments_app.vue
index 602639f09a6..8bd71db957c 100644
--- a/app/assets/javascripts/environments/components/environments_app.vue
+++ b/app/assets/javascripts/environments/components/environments_app.vue
@@ -121,7 +121,7 @@ export default {
variant="info"
category="secondary"
type="button"
- class="gl-mb-3 gl-flex-fill-1"
+ class="gl-mb-3 gl-flex-grow-1"
>{{ $options.i18n.reviewAppButtonLabel }}</gl-button
>
<gl-button
diff --git a/app/assets/javascripts/environments/components/stop_environment_modal.vue b/app/assets/javascripts/environments/components/stop_environment_modal.vue
index 828a7098b36..7a9233048a9 100644
--- a/app/assets/javascripts/environments/components/stop_environment_modal.vue
+++ b/app/assets/javascripts/environments/components/stop_environment_modal.vue
@@ -58,7 +58,7 @@ export default {
<span
v-gl-tooltip
:title="environment.name"
- class="gl-text-truncate gl-ml-2 gl-mr-2 gl-flex-fill"
+ class="gl-text-truncate gl-ml-2 gl-mr-2 gl-flex-grow-1"
>
{{ environment.name }}?
</span>
diff --git a/app/assets/javascripts/error_tracking/components/error_tracking_list.vue b/app/assets/javascripts/error_tracking/components/error_tracking_list.vue
index 0f564fc3c60..2e27f51b71f 100644
--- a/app/assets/javascripts/error_tracking/components/error_tracking_list.vue
+++ b/app/assets/javascripts/error_tracking/components/error_tracking_list.vue
@@ -260,7 +260,7 @@ export default {
</template>
<div v-else class="px-3">{{ __("You don't have any recent searches") }}</div>
</gl-dropdown>
- <div class="filtered-search-input-container gl-flex-fill-1">
+ <div class="filtered-search-input-container gl-flex-grow-1">
<gl-form-input
v-model="errorSearchQuery"
class="pl-2 filtered-search"
diff --git a/app/assets/javascripts/import_entities/import_groups/components/import_table_row.vue b/app/assets/javascripts/import_entities/import_groups/components/import_table_row.vue
index e86c418f216..63c18f4d78e 100644
--- a/app/assets/javascripts/import_entities/import_groups/components/import_table_row.vue
+++ b/app/assets/javascripts/import_entities/import_groups/components/import_table_row.vue
@@ -157,7 +157,7 @@ export default {
:text="importTarget.target_namespace"
:disabled="isAlreadyImported"
toggle-class="gl-rounded-top-right-none! gl-rounded-bottom-right-none!"
- class="import-entities-namespace-dropdown gl-h-7 gl-flex-fill-1"
+ class="import-entities-namespace-dropdown gl-h-7 gl-flex-grow-1"
data-qa-selector="target_namespace_selector_dropdown"
>
<gl-dropdown-item @click="$emit('update-target-namespace', '')">{{
@@ -184,7 +184,7 @@ export default {
>
/
</div>
- <div class="gl-flex-fill-1">
+ <div class="gl-flex-grow-1">
<gl-form-input
class="gl-rounded-top-left-none gl-rounded-bottom-left-none"
:class="{ 'is-invalid': isInvalid && !isAlreadyImported }"
diff --git a/app/assets/javascripts/issuable_list/components/issuable_tabs.vue b/app/assets/javascripts/issuable_list/components/issuable_tabs.vue
index dfe158ae2b0..977d03e62be 100644
--- a/app/assets/javascripts/issuable_list/components/issuable_tabs.vue
+++ b/app/assets/javascripts/issuable_list/components/issuable_tabs.vue
@@ -36,7 +36,7 @@ export default {
<template>
<div class="top-area">
<gl-tabs
- class="gl-display-flex gl-flex-fill-1 gl-p-0 gl-m-0 mobile-separator issuable-state-filters"
+ class="gl-display-flex gl-flex-grow-1 gl-p-0 gl-m-0 mobile-separator issuable-state-filters"
nav-class="gl-border-b-0"
>
<gl-tab
diff --git a/app/assets/javascripts/packages/details/components/package_files.vue b/app/assets/javascripts/packages/details/components/package_files.vue
index 3c71ac5137e..0563b612d04 100644
--- a/app/assets/javascripts/packages/details/components/package_files.vue
+++ b/app/assets/javascripts/packages/details/components/package_files.vue
@@ -148,7 +148,7 @@ export default {
<template #row-details="{ item }">
<div
- class="gl-display-flex gl-flex-direction-column gl-flex-fill-1 gl-bg-gray-10 gl-rounded-base gl-inset-border-1-gray-100"
+ class="gl-display-flex gl-flex-direction-column gl-flex-grow-1 gl-bg-gray-10 gl-rounded-base gl-inset-border-1-gray-100"
>
<file-sha
v-if="item.file_sha256"
diff --git a/app/assets/javascripts/pages/projects/shared/permissions/components/project_feature_setting.vue b/app/assets/javascripts/pages/projects/shared/permissions/components/project_feature_setting.vue
index c110c1d4d62..9fb8be3fdb9 100644
--- a/app/assets/javascripts/pages/projects/shared/permissions/components/project_feature_setting.vue
+++ b/app/assets/javascripts/pages/projects/shared/permissions/components/project_feature_setting.vue
@@ -91,7 +91,7 @@ export default {
label-position="hidden"
@change="toggleFeature"
/>
- <div class="select-wrapper gl-flex-fill-1">
+ <div class="select-wrapper gl-flex-grow-1">
<select
:disabled="displaySelectInput"
class="form-control project-repo-select select-control"
diff --git a/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue b/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue
index 0b7b4c0ded1..11e6b4577e0 100644
--- a/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue
+++ b/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue
@@ -381,7 +381,7 @@ export default {
:label="s__('ProjectSettings|Project visibility')"
>
<div class="project-feature-controls gl-display-flex gl-align-items-center gl-my-3 gl-mx-0">
- <div class="select-wrapper gl-flex-fill-1">
+ <div class="select-wrapper gl-flex-grow-1">
<select
v-model="visibilityLevel"
:disabled="!canChangeVisibilityLevel"
diff --git a/app/assets/javascripts/reports/codequality_report/components/codequality_issue_body.vue b/app/assets/javascripts/reports/codequality_report/components/codequality_issue_body.vue
index dabfb623f43..736c8668a34 100644
--- a/app/assets/javascripts/reports/codequality_report/components/codequality_issue_body.vue
+++ b/app/assets/javascripts/reports/codequality_report/components/codequality_issue_body.vue
@@ -61,7 +61,7 @@ export default {
<span :class="severityClass" class="gl-mr-5" data-testid="codequality-severity-icon">
<gl-icon v-tooltip="severityLabel" :name="severityIcon" :size="12" />
</span>
- <div class="gl-flex-fill-1">
+ <div class="gl-flex-grow-1">
<div>
<strong v-if="isStatusSuccess">{{ s__('ciReport|Fixed:') }}</strong>
{{ issueName }}
diff --git a/app/assets/javascripts/runner/constants.js b/app/assets/javascripts/runner/constants.js
index d47efc85eff..a57d18ba745 100644
--- a/app/assets/javascripts/runner/constants.js
+++ b/app/assets/javascripts/runner/constants.js
@@ -10,6 +10,7 @@ export const RUNNER_ENTITY_TYPE = 'Ci::Runner';
// - Used for URL params names
// - GlFilteredSearch tokens type
+export const PARAM_KEY_SEARCH = 'search';
export const PARAM_KEY_STATUS = 'status';
export const PARAM_KEY_RUNNER_TYPE = 'runner_type';
export const PARAM_KEY_SORT = 'sort';
diff --git a/app/assets/javascripts/runner/graphql/get_runners.query.graphql b/app/assets/javascripts/runner/graphql/get_runners.query.graphql
index 84b7e2547f5..45df9c625a6 100644
--- a/app/assets/javascripts/runner/graphql/get_runners.query.graphql
+++ b/app/assets/javascripts/runner/graphql/get_runners.query.graphql
@@ -6,6 +6,7 @@ query getRunners(
$after: String
$first: Int
$last: Int
+ $search: String
$status: CiRunnerStatus
$type: CiRunnerType
$sort: CiRunnerSort
@@ -15,6 +16,7 @@ query getRunners(
after: $after
first: $first
last: $last
+ search: $search
status: $status
type: $type
sort: $sort
diff --git a/app/assets/javascripts/runner/runner_list/runner_list_app.vue b/app/assets/javascripts/runner/runner_list/runner_list_app.vue
index d53774709ba..b4eacb911a2 100644
--- a/app/assets/javascripts/runner/runner_list/runner_list_app.vue
+++ b/app/assets/javascripts/runner/runner_list/runner_list_app.vue
@@ -12,7 +12,7 @@ import {
fromUrlQueryToSearch,
fromSearchToUrl,
fromSearchToVariables,
-} from './filtered_search_utils';
+} from './runner_search_utils';
export default {
components: {
diff --git a/app/assets/javascripts/runner/runner_list/filtered_search_utils.js b/app/assets/javascripts/runner/runner_list/runner_search_utils.js
index 2303dd587e1..e45972b81db 100644
--- a/app/assets/javascripts/runner/runner_list/filtered_search_utils.js
+++ b/app/assets/javascripts/runner/runner_list/runner_search_utils.js
@@ -1,5 +1,12 @@
import { queryToObject, setUrlParams } from '~/lib/utils/url_utility';
import {
+ filterToQueryObject,
+ processFilters,
+ urlQueryToFilter,
+ prepareTokens,
+} from '~/vue_shared/components/filtered_search_bar/filtered_search_utils';
+import {
+ PARAM_KEY_SEARCH,
PARAM_KEY_STATUS,
PARAM_KEY_RUNNER_TYPE,
PARAM_KEY_SORT,
@@ -10,30 +17,6 @@ import {
RUNNER_PAGE_SIZE,
} from '../constants';
-const getValuesFromFilters = (paramKey, filters) => {
- return filters
- .filter(({ type, value }) => type === paramKey && value.operator === '=')
- .map(({ value }) => value.data);
-};
-
-const getFilterFromParams = (paramKey, params) => {
- const value = params[paramKey];
- if (!value) {
- return [];
- }
-
- const values = Array.isArray(value) ? value : [value];
- return values.map((data) => {
- return {
- type: paramKey,
- value: {
- data,
- operator: '=',
- },
- };
- });
-};
-
const getPaginationFromParams = (params) => {
const page = parseInt(params[PARAM_KEY_PAGE], 10);
const after = params[PARAM_KEY_AFTER];
@@ -55,10 +38,13 @@ export const fromUrlQueryToSearch = (query = window.location.search) => {
const params = queryToObject(query, { gatherArrays: true });
return {
- filters: [
- ...getFilterFromParams(PARAM_KEY_STATUS, params),
- ...getFilterFromParams(PARAM_KEY_RUNNER_TYPE, params),
- ],
+ filters: prepareTokens(
+ urlQueryToFilter(query, {
+ filterNamesAllowList: [PARAM_KEY_STATUS, PARAM_KEY_RUNNER_TYPE],
+ filteredSearchTermKey: PARAM_KEY_SEARCH,
+ legacySpacesDecode: false,
+ }),
+ ),
sort: params[PARAM_KEY_SORT] || DEFAULT_SORT,
pagination: getPaginationFromParams(params),
};
@@ -68,37 +54,44 @@ export const fromSearchToUrl = (
{ filters = [], sort = null, pagination = {} },
url = window.location.href,
) => {
- const urlParams = {
- [PARAM_KEY_STATUS]: getValuesFromFilters(PARAM_KEY_STATUS, filters),
- [PARAM_KEY_RUNNER_TYPE]: getValuesFromFilters(PARAM_KEY_RUNNER_TYPE, filters),
+ const filterParams = {
+ // Defaults
+ [PARAM_KEY_SEARCH]: null,
+ [PARAM_KEY_STATUS]: [],
+ [PARAM_KEY_RUNNER_TYPE]: [],
+ // Current filters
+ ...filterToQueryObject(processFilters(filters), {
+ filteredSearchTermKey: PARAM_KEY_SEARCH,
+ }),
};
- if (sort && sort !== DEFAULT_SORT) {
- urlParams[PARAM_KEY_SORT] = sort;
- }
-
- // Remove pagination params for first page
- if (pagination?.page === 1) {
- urlParams[PARAM_KEY_PAGE] = null;
- urlParams[PARAM_KEY_BEFORE] = null;
- urlParams[PARAM_KEY_AFTER] = null;
- } else {
- urlParams[PARAM_KEY_PAGE] = pagination.page;
- urlParams[PARAM_KEY_BEFORE] = pagination.before;
- urlParams[PARAM_KEY_AFTER] = pagination.after;
- }
+ const isDefaultSort = sort !== DEFAULT_SORT;
+ const isFirstPage = pagination?.page === 1;
+ const otherParams = {
+ // Sorting & Pagination
+ [PARAM_KEY_SORT]: isDefaultSort ? sort : null,
+ [PARAM_KEY_PAGE]: isFirstPage ? null : pagination.page,
+ [PARAM_KEY_BEFORE]: isFirstPage ? null : pagination.before,
+ [PARAM_KEY_AFTER]: isFirstPage ? null : pagination.after,
+ };
- return setUrlParams(urlParams, url, false, true, true);
+ return setUrlParams({ ...filterParams, ...otherParams }, url, false, true, true);
};
export const fromSearchToVariables = ({ filters = [], sort = null, pagination = {} } = {}) => {
const variables = {};
+ const queryObj = filterToQueryObject(processFilters(filters), {
+ filteredSearchTermKey: PARAM_KEY_SEARCH,
+ });
+
+ variables.search = queryObj[PARAM_KEY_SEARCH];
+
// TODO Get more than one value when GraphQL API supports OR for "status"
- [variables.status] = getValuesFromFilters(PARAM_KEY_STATUS, filters);
+ [variables.status] = queryObj[PARAM_KEY_STATUS] || [];
// TODO Get more than one value when GraphQL API supports OR for "runner type"
- [variables.type] = getValuesFromFilters(PARAM_KEY_RUNNER_TYPE, filters);
+ [variables.type] = queryObj[PARAM_KEY_RUNNER_TYPE] || [];
if (sort) {
variables.sort = sort;
diff --git a/app/assets/javascripts/search/topbar/components/app.vue b/app/assets/javascripts/search/topbar/components/app.vue
index 2439ab55923..a490adbc11a 100644
--- a/app/assets/javascripts/search/topbar/components/app.vue
+++ b/app/assets/javascripts/search/topbar/components/app.vue
@@ -48,7 +48,7 @@ export default {
<template>
<gl-form class="search-page-form" @submit.prevent="applyQuery">
<section class="gl-lg-display-flex gl-align-items-flex-end">
- <div class="gl-flex-fill-1 gl-mb-4 gl-lg-mb-0 gl-lg-mr-2">
+ <div class="gl-flex-grow-1 gl-mb-4 gl-lg-mb-0 gl-lg-mr-2">
<label>{{ __('What are you searching for?') }}</label>
<gl-search-box-by-type
id="dashboard_search"
diff --git a/app/assets/javascripts/sidebar/components/severity/sidebar_severity.vue b/app/assets/javascripts/sidebar/components/severity/sidebar_severity.vue
index 6a6300dcde0..592cfea5e32 100644
--- a/app/assets/javascripts/sidebar/components/severity/sidebar_severity.vue
+++ b/app/assets/javascripts/sidebar/components/severity/sidebar_severity.vue
@@ -148,7 +148,9 @@ export default {
</div>
<div class="hide-collapsed">
- <p class="title gl-display-flex gl-justify-content-space-between">
+ <p
+ class="gl-line-height-20 gl-mb-0 gl-text-gray-900 gl-display-flex gl-justify-content-space-between"
+ >
{{ $options.i18n.SEVERITY }}
<gl-link
data-testid="editButton"
diff --git a/app/assets/javascripts/user_lists/components/user_list_form.vue b/app/assets/javascripts/user_lists/components/user_list_form.vue
index a0364089d68..b53aaf46ace 100644
--- a/app/assets/javascripts/user_lists/components/user_list_form.vue
+++ b/app/assets/javascripts/user_lists/components/user_list_form.vue
@@ -75,7 +75,7 @@ export default {
</template>
</gl-sprintf>
</div>
- <div class="gl-flex-fill-1 gl-ml-7">
+ <div class="gl-flex-grow-1 gl-ml-7">
<gl-form-group
label-for="user-list-name"
:label="$options.translations.nameLabel"
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_expandable_section.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_expandable_section.vue
index c368399ed6f..f8c4ad69e39 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_expandable_section.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_expandable_section.vue
@@ -51,7 +51,7 @@ export default {
<gl-icon :name="iconName" :size="24" />
</span>
- <div class="gl-display-flex gl-flex-fill-1 gl-flex-direction-column gl-md-flex-direction-row">
+ <div class="gl-display-flex gl-flex-grow-1 gl-flex-direction-column gl-md-flex-direction-row">
<slot name="header"></slot>
<div>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue
index fa46b4b1364..6c162a06161 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue
@@ -160,7 +160,7 @@ export default {
<div class="ci-widget media">
<template v-if="hasCIError">
<gl-icon name="status_failed" class="gl-text-red-500" :size="24" />
- <p class="gl-flex-fill-1 gl-ml-5 gl-mb-0" data-testid="ci-error-message">
+ <p class="gl-flex-grow-1 gl-ml-5 gl-mb-0" data-testid="ci-error-message">
<gl-sprintf :message="$options.errorText">
<template #link="{ content }">
<gl-link :href="mrTroubleshootingDocsPath">{{ content }}</gl-link>
@@ -171,7 +171,7 @@ export default {
<template v-else-if="!hasPipeline">
<gl-loading-icon size="md" />
<p
- class="gl-flex-fill-1 gl-display-flex gl-ml-5 gl-mb-0"
+ class="gl-flex-grow-1 gl-display-flex gl-ml-5 gl-mb-0"
data-testid="monitoring-pipeline-message"
>
{{ $options.monitoringPipelineText }}
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/terraform/mr_widget_terraform_container.vue b/app/assets/javascripts/vue_merge_request_widget/components/terraform/mr_widget_terraform_container.vue
index 25f339b362f..2ba945a3ecf 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/terraform/mr_widget_terraform_container.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/terraform/mr_widget_terraform_container.vue
@@ -107,7 +107,7 @@ export default {
<template #header>
<div
data-testid="terraform-header-text"
- class="gl-flex-fill-1 gl-display-flex gl-flex-direction-column"
+ class="gl-flex-grow-1 gl-display-flex gl-flex-direction-column"
>
<p v-if="validPlanCountText" class="gl-m-0">
<gl-sprintf :message="validPlanCountText">
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/terraform/terraform_plan.vue b/app/assets/javascripts/vue_merge_request_widget/components/terraform/terraform_plan.vue
index 25e3dae92e8..427ab0842ea 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/terraform/terraform_plan.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/terraform/terraform_plan.vue
@@ -71,8 +71,8 @@ export default {
<gl-icon :name="iconType" :size="16" data-testid="change-type-icon" />
</span>
- <div class="gl-display-flex gl-flex-fill-1 gl-flex-direction-column flex-md-row gl-pl-3">
- <div class="gl-flex-fill-1 gl-display-flex gl-flex-direction-column gl-pr-3">
+ <div class="gl-display-flex gl-flex-grow-1 gl-flex-direction-column flex-md-row gl-pl-3">
+ <div class="gl-flex-grow-1 gl-display-flex gl-flex-direction-column gl-pr-3">
<p class="gl-mb-3 gl-line-height-normal">
<gl-sprintf :message="reportHeaderText">
<template #name>
diff --git a/app/assets/javascripts/vue_shared/components/filtered_search_bar/filtered_search_utils.js b/app/assets/javascripts/vue_shared/components/filtered_search_bar/filtered_search_utils.js
index 4b1b09adcfd..37436de907f 100644
--- a/app/assets/javascripts/vue_shared/components/filtered_search_bar/filtered_search_utils.js
+++ b/app/assets/javascripts/vue_shared/components/filtered_search_bar/filtered_search_utils.js
@@ -2,7 +2,7 @@ import { isEmpty, uniqWith, isEqual } from 'lodash';
import AccessorUtilities from '~/lib/utils/accessor';
import { queryToObject } from '~/lib/utils/url_utility';
-import { MAX_RECENT_TOKENS_SIZE } from './constants';
+import { MAX_RECENT_TOKENS_SIZE, FILTERED_SEARCH_TERM } from './constants';
/**
* Strips enclosing quotations from a string if it has one.
@@ -23,7 +23,7 @@ export const stripQuotes = (value) => value.replace(/^('|")(.*)('|")$/, '$2');
export const uniqueTokens = (tokens) => {
const knownTokens = [];
return tokens.reduce((uniques, token) => {
- if (typeof token === 'object' && token.type !== 'filtered-search-term') {
+ if (typeof token === 'object' && token.type !== FILTERED_SEARCH_TERM) {
const tokenString = `${token.type}${token.value.operator}${token.value.data}`;
if (!knownTokens.includes(tokenString)) {
uniques.push(token);
@@ -86,21 +86,37 @@ export function processFilters(filters) {
}, {});
}
+function filteredSearchQueryParam(filter) {
+ return filter
+ .map(({ value }) => value)
+ .join(' ')
+ .trim();
+}
+
/**
* This function takes a filter object and maps it into a query object. Example filter:
- * { myFilterName: { value: 'foo', operator: '=' } }
+ * { myFilterName: { value: 'foo', operator: '=' }, search: [{ value: 'my' }, { value: 'search' }] }
* gets translated into:
- * { myFilterName: 'foo', 'not[myFilterName]': null }
+ * { myFilterName: 'foo', 'not[myFilterName]': null, search: 'my search' }
* @param {Object} filters
- * @param {Object.myFilterName} a single filter value or an array of filters
+ * @param {Object} filters.myFilterName a single filter value or an array of filters
+ * @param {Object} options
+ * @param {Object} [options.filteredSearchTermKey] if set, 'filtered-search-term' filters are assigned to this key, 'search' is suggested
* @return {Object} query object with both filter name and not-name with values
*/
-export function filterToQueryObject(filters = {}) {
+export function filterToQueryObject(filters = {}, options = {}) {
+ const { filteredSearchTermKey } = options;
+
return Object.keys(filters).reduce((memo, key) => {
const filter = filters[key];
+ if (typeof filteredSearchTermKey === 'string' && key === FILTERED_SEARCH_TERM) {
+ return { ...memo, [filteredSearchTermKey]: filteredSearchQueryParam(filter) };
+ }
+
let selected;
let unselected;
+
if (Array.isArray(filter)) {
selected = filter.filter((item) => item.operator === '=').map((item) => item.value);
unselected = filter.filter((item) => item.operator === '!=').map((item) => item.value);
@@ -125,7 +141,7 @@ export function filterToQueryObject(filters = {}) {
* and returns the operator with it depending on the filter name
* @param {String} filterName from url
* @return {Object}
- * @return {Object.filterName} extracted filtern ame
+ * @return {Object.filterName} extracted filter name
* @return {Object.operator} `=` or `!=`
*/
function extractNameAndOperator(filterName) {
@@ -138,21 +154,52 @@ function extractNameAndOperator(filterName) {
}
/**
+ * Gathers search term as values
+ * @param {String|Array} value
+ * @returns {Array} List of search terms split by word
+ */
+function filteredSearchTermValue(value) {
+ const values = Array.isArray(value) ? value : [value];
+ return values
+ .filter((term) => term)
+ .join(' ')
+ .split(' ')
+ .map((term) => ({ value: term }));
+}
+
+/**
* This function takes a URL query string and maps it into a filter object. Example query string:
* '?myFilterName=foo'
* gets translated into:
* { myFilterName: { value: 'foo', operator: '=' } }
* @param {String} query URL query string, e.g. from `window.location.search`
+ * @param {Object} options
+ * @param {Object} options
+ * @param {String} [options.filteredSearchTermKey] if set, a FILTERED_SEARCH_TERM filter is created to this parameter. `'search'` is suggested
+ * @param {String[]} [options.filterNamesAllowList] if set, only this list of filters names is mapped
+ * @param {Boolean} [options.legacySpacesDecode] if set, plus symbols (+) are not encoded as spaces. `false` is suggested
* @return {Object} filter object with filter names and their values
*/
-export function urlQueryToFilter(query = '') {
- const filters = queryToObject(query, { gatherArrays: true, legacySpacesDecode: true });
+export function urlQueryToFilter(query = '', options = {}) {
+ const { filteredSearchTermKey, filterNamesAllowList, legacySpacesDecode = true } = options;
+
+ const filters = queryToObject(query, { gatherArrays: true, legacySpacesDecode });
return Object.keys(filters).reduce((memo, key) => {
const value = filters[key];
if (!value) {
return memo;
}
+ if (key === filteredSearchTermKey) {
+ return {
+ ...memo,
+ [FILTERED_SEARCH_TERM]: filteredSearchTermValue(value),
+ };
+ }
+
const { filterName, operator } = extractNameAndOperator(key);
+ if (filterNamesAllowList && !filterNamesAllowList.includes(filterName)) {
+ return memo;
+ }
let previousValues = [];
if (Array.isArray(memo[filterName])) {
previousValues = memo[filterName];
diff --git a/app/assets/javascripts/vue_shared/components/registry/list_item.vue b/app/assets/javascripts/vue_shared/components/registry/list_item.vue
index b9e916bc199..933a215112b 100644
--- a/app/assets/javascripts/vue_shared/components/registry/list_item.vue
+++ b/app/assets/javascripts/vue_shared/components/registry/list_item.vue
@@ -62,7 +62,7 @@ export default {
<slot name="left-action"></slot>
</div>
<div
- class="gl-display-flex gl-xs-flex-direction-column gl-justify-content-space-between gl-align-items-stretch gl-flex-fill-1"
+ class="gl-display-flex gl-xs-flex-direction-column gl-justify-content-space-between gl-align-items-stretch gl-flex-grow-1"
>
<div class="gl-display-flex gl-flex-direction-column gl-xs-mb-3 gl-min-w-0 gl-flex-grow-1">
<div
@@ -81,7 +81,7 @@ export default {
</div>
<div
v-if="$slots['left-secondary']"
- class="gl-display-flex gl-align-items-center gl-text-gray-500 gl-min-h-6 gl-min-w-0 gl-flex-fill-1"
+ class="gl-display-flex gl-align-items-center gl-text-gray-500 gl-min-h-6 gl-min-w-0 gl-flex-grow-1"
>
<slot name="left-secondary"></slot>
</div>
@@ -114,7 +114,7 @@ export default {
<div class="gl-w-7"></div>
<div
v-if="isDetailsShown"
- class="gl-display-flex gl-flex-direction-column gl-flex-fill-1 gl-bg-gray-10 gl-rounded-base gl-inset-border-1-gray-100 gl-mb-3"
+ class="gl-display-flex gl-flex-direction-column gl-flex-grow-1 gl-bg-gray-10 gl-rounded-base gl-inset-border-1-gray-100 gl-mb-3"
>
<div
v-for="(row, detailIndex) in detailsSlots"
diff --git a/app/assets/javascripts/vue_shared/components/registry/registry_search.vue b/app/assets/javascripts/vue_shared/components/registry/registry_search.vue
index 0825c3a76ea..767a108dde5 100644
--- a/app/assets/javascripts/vue_shared/components/registry/registry_search.vue
+++ b/app/assets/javascripts/vue_shared/components/registry/registry_search.vue
@@ -109,7 +109,7 @@ export default {
<div class="gl-display-flex gl-p-5 gl-bg-gray-10 gl-border-solid gl-border-1 gl-border-gray-100">
<gl-filtered-search
v-model="internalFilter"
- class="gl-mr-4 gl-flex-fill-1"
+ class="gl-mr-4 gl-flex-grow-1"
:placeholder="__('Filter results')"
:available-tokens="tokens"
@submit="submitSearch"
diff --git a/app/assets/javascripts/vue_shared/components/runner_instructions/runner_instructions_modal.vue b/app/assets/javascripts/vue_shared/components/runner_instructions/runner_instructions_modal.vue
index 1f70644eb2c..580e1668f41 100644
--- a/app/assets/javascripts/vue_shared/components/runner_instructions/runner_instructions_modal.vue
+++ b/app/assets/javascripts/vue_shared/components/runner_instructions/runner_instructions_modal.vue
@@ -225,7 +225,7 @@ export default {
<template v-if="!instructionsEmpty">
<div class="gl-display-flex">
<pre
- class="gl-bg-gray gl-flex-fill-1 gl-white-space-pre-line"
+ class="gl-bg-gray gl-flex-grow-1 gl-white-space-pre-line"
data-testid="binary-instructions"
>{{ instructions.installInstructions }}</pre
>
@@ -241,7 +241,7 @@ export default {
<h5 class="gl-mb-3">{{ $options.i18n.registerRunnerCommand }}</h5>
<div class="gl-display-flex">
<pre
- class="gl-bg-gray gl-flex-fill-1 gl-white-space-pre-line"
+ class="gl-bg-gray gl-flex-grow-1 gl-white-space-pre-line"
data-testid="register-command"
>{{ instructions.registerInstructions }}</pre
>
diff --git a/app/assets/stylesheets/framework.scss b/app/assets/stylesheets/framework.scss
index 603747aa490..2fbdaaaf467 100644
--- a/app/assets/stylesheets/framework.scss
+++ b/app/assets/stylesheets/framework.scss
@@ -47,6 +47,7 @@
@import 'framework/toggle';
@import 'framework/typography';
@import 'framework/zen';
+@import 'framework/blank';
@import 'framework/wells';
@import 'framework/page_header';
@import 'framework/page_title';
diff --git a/app/assets/stylesheets/framework/blank.scss b/app/assets/stylesheets/framework/blank.scss
new file mode 100644
index 00000000000..7dd7ab339dd
--- /dev/null
+++ b/app/assets/stylesheets/framework/blank.scss
@@ -0,0 +1,118 @@
+.blank-state-parent-container {
+ .section-container {
+ padding: 10px;
+ }
+
+ .section-body {
+ width: 100%;
+ height: 100%;
+ padding-bottom: 25px;
+ border-radius: $border-radius-default;
+ }
+}
+
+.blank-state-row {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: space-between;
+}
+
+.blank-state-welcome {
+ text-align: center;
+ padding: $gl-padding 0 ($gl-padding * 2);
+
+ .blank-state-welcome-title {
+ font-size: 24px;
+ }
+
+ .blank-state-text {
+ margin-bottom: 0;
+ }
+}
+
+.blank-state-link {
+ color: $gl-text-color;
+ margin-bottom: 15px;
+
+ &:hover {
+ background-color: $gray-light;
+ text-decoration: none;
+ color: $gl-text-color;
+ }
+}
+
+.blank-state-center {
+ padding-top: 20px;
+ padding-bottom: 20px;
+ text-align: center;
+}
+
+.blank-state {
+ display: flex;
+ align-items: center;
+ padding: 20px 50px;
+ border: 1px solid $border-color;
+ border-radius: $border-radius-default;
+ min-height: 240px;
+ margin-bottom: $gl-padding;
+ width: calc(50% - #{$gl-padding-8});
+
+ @include media-breakpoint-down(sm) {
+ width: 100%;
+ flex-direction: column;
+ justify-content: center;
+ padding: 50px 20px;
+
+ .column-small & {
+ width: 100%;
+ }
+
+ }
+}
+
+.blank-state,
+.blank-state-center {
+ .blank-state-icon {
+ svg {
+ display: block;
+ margin: auto;
+ }
+ }
+
+ .blank-state-title {
+ margin-top: 0;
+ font-size: 18px;
+ }
+
+ .blank-state-body {
+ @include media-breakpoint-down(sm) {
+ text-align: center;
+ margin-top: 20px;
+ }
+
+ @include media-breakpoint-up(sm) {
+ padding-left: 20px;
+ }
+ }
+}
+
+@include media-breakpoint-up(lg) {
+ .column-large {
+ flex: 2;
+ }
+
+ .column-small {
+ flex: 1;
+ margin-bottom: 15px;
+
+ .blank-state {
+ max-width: 400px;
+ flex-wrap: wrap;
+ margin-left: 15px;
+ }
+
+ .blank-state-icon {
+ margin-bottom: 30px;
+ }
+ }
+}
diff --git a/app/controllers/clusters/applications_controller.rb b/app/controllers/clusters/applications_controller.rb
index 5c1d85f4374..91003e9580d 100644
--- a/app/controllers/clusters/applications_controller.rb
+++ b/app/controllers/clusters/applications_controller.rb
@@ -47,7 +47,7 @@ class Clusters::ApplicationsController < Clusters::BaseController
end
def cluster_application_params
- params.permit(:application, :hostname, :pages_domain_id, :email, :stack, :host, :port, :protocol, :cilium_log_enabled)
+ params.permit(:application, :hostname, :pages_domain_id, :email, :stack, :host, :port, :protocol)
end
def cluster_application_destroy_params
diff --git a/app/controllers/concerns/membership_actions.rb b/app/controllers/concerns/membership_actions.rb
index 565484495ba..8fd4e98d557 100644
--- a/app/controllers/concerns/membership_actions.rb
+++ b/app/controllers/concerns/membership_actions.rb
@@ -140,39 +140,15 @@ module MembershipActions
end
def root_params_key
- case membershipable
- when Namespace
- :group_member
- when Project
- :project_member
- else
- raise "Unknown membershipable type: #{membershipable}!"
- end
+ raise NotImplementedError
end
def members_page_url
- case membershipable
- when Namespace
- polymorphic_url([membershipable, :members])
- when Project
- project_project_members_path(membershipable)
- else
- raise "Unknown membershipable type: #{membershipable}!"
- end
+ raise NotImplementedError
end
def source_type
- @source_type ||=
- begin
- case membershipable
- when Namespace
- _("group")
- when Project
- _("project")
- else
- raise "Unknown membershipable type: #{membershipable}!"
- end
- end
+ raise NotImplementedError
end
def plain_source_type
diff --git a/app/controllers/groups/group_members_controller.rb b/app/controllers/groups/group_members_controller.rb
index f3b1d71d06e..8d9059d271f 100644
--- a/app/controllers/groups/group_members_controller.rb
+++ b/app/controllers/groups/group_members_controller.rb
@@ -82,6 +82,18 @@ class Groups::GroupMembersController < Groups::ApplicationController
def plain_source_type
'group'
end
+
+ def source_type
+ _("group")
+ end
+
+ def members_page_url
+ polymorphic_url([group, :members])
+ end
+
+ def root_params_key
+ :group_member
+ end
end
Groups::GroupMembersController.prepend_mod_with('Groups::GroupMembersController')
diff --git a/app/controllers/projects/feature_flags_controller.rb b/app/controllers/projects/feature_flags_controller.rb
index 03561e73828..a59824b1085 100644
--- a/app/controllers/projects/feature_flags_controller.rb
+++ b/app/controllers/projects/feature_flags_controller.rb
@@ -11,6 +11,7 @@ class Projects::FeatureFlagsController < Projects::ApplicationController
before_action :feature_flag, only: [:edit, :update, :destroy]
before_action :ensure_flag_writable!, only: [:update]
+ before_action :exclude_legacy_flags_check, only: [:edit]
before_action do
push_frontend_feature_flag(:feature_flag_permissions)
@@ -63,7 +64,6 @@ class Projects::FeatureFlagsController < Projects::ApplicationController
end
def edit
- exclude_legacy_flags_check
end
def update
@@ -108,6 +108,12 @@ class Projects::FeatureFlagsController < Projects::ApplicationController
end
end
+ def exclude_legacy_flags_check
+ if feature_flag.legacy_flag?
+ not_found
+ end
+ end
+
def create_params
params.require(:operations_feature_flag)
.permit(:name, :description, :active, :version,
@@ -159,12 +165,4 @@ class Projects::FeatureFlagsController < Projects::ApplicationController
render json: { message: messages },
status: status
end
-
- def exclude_legacy_flags_check
- if Feature.enabled?(:remove_legacy_flags, project, default_enabled: :yaml) &&
- Feature.disabled?(:remove_legacy_flags_override, project, default_enabled: :yaml) &&
- feature_flag.legacy_flag?
- not_found
- end
- end
end
diff --git a/app/controllers/projects/project_members_controller.rb b/app/controllers/projects/project_members_controller.rb
index 4f342980bf0..370cd2b02a1 100644
--- a/app/controllers/projects/project_members_controller.rb
+++ b/app/controllers/projects/project_members_controller.rb
@@ -66,6 +66,18 @@ class Projects::ProjectMembersController < Projects::ApplicationController
def plain_source_type
'project'
end
+
+ def source_type
+ _("project")
+ end
+
+ def members_page_url
+ project_project_members_path(project)
+ end
+
+ def root_params_key
+ :project_member
+ end
end
Projects::ProjectMembersController.prepend_mod_with('Projects::ProjectMembersController')
diff --git a/app/finders/feature_flags_finder.rb b/app/finders/feature_flags_finder.rb
index 0ab65d3630e..20b18c62f7a 100644
--- a/app/finders/feature_flags_finder.rb
+++ b/app/finders/feature_flags_finder.rb
@@ -24,11 +24,7 @@ class FeatureFlagsFinder
private
def feature_flags
- if exclude_legacy_flags?
- project.operations_feature_flags.new_version_only
- else
- project.operations_feature_flags
- end
+ project.operations_feature_flags.new_version_only
end
def by_scope(items)
@@ -41,9 +37,4 @@ class FeatureFlagsFinder
items
end
end
-
- def exclude_legacy_flags?
- Feature.enabled?(:remove_legacy_flags, project, default_enabled: :yaml) &&
- Feature.disabled?(:remove_legacy_flags_override, project, default_enabled: :yaml)
- end
end
diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb
index 1f4c98d6f28..e07ee22339a 100644
--- a/app/helpers/search_helper.rb
+++ b/app/helpers/search_helper.rb
@@ -9,7 +9,8 @@ module SearchHelper
:repository_ref,
:snippets,
:sort,
- :force_search_results
+ :force_search_results,
+ :project_ids
].freeze
def search_autocomplete_opts(term)
diff --git a/app/models/ci/job_artifact.rb b/app/models/ci/job_artifact.rb
index 586142a7646..6a7a2b3f6bd 100644
--- a/app/models/ci/job_artifact.rb
+++ b/app/models/ci/job_artifact.rb
@@ -43,7 +43,7 @@ module Ci
dotenv: '.env',
cobertura: 'cobertura-coverage.xml',
terraform: 'tfplan.json',
- cluster_applications: 'gl-cluster-applications.json',
+ cluster_applications: 'gl-cluster-applications.json', # DEPRECATED: https://gitlab.com/gitlab-org/gitlab/-/issues/333441
requirements: 'requirements.json',
coverage_fuzzing: 'gl-coverage-fuzzing.json',
api_fuzzing: 'gl-api-fuzzing-report.json'
diff --git a/app/models/clusters/applications/fluentd.rb b/app/models/clusters/applications/fluentd.rb
deleted file mode 100644
index c5d674c1908..00000000000
--- a/app/models/clusters/applications/fluentd.rb
+++ /dev/null
@@ -1,121 +0,0 @@
-# frozen_string_literal: true
-
-module Clusters
- module Applications
- class Fluentd < ApplicationRecord
- VERSION = '2.4.0'
- CILIUM_CONTAINER_NAME = 'cilium-monitor'
-
- self.table_name = 'clusters_applications_fluentd'
-
- include ::Clusters::Concerns::ApplicationCore
- include ::Clusters::Concerns::ApplicationStatus
- include ::Clusters::Concerns::ApplicationVersion
- include ::Clusters::Concerns::ApplicationData
- include IgnorableColumns
-
- default_value_for :version, VERSION
- default_value_for :port, 514
- default_value_for :protocol, :tcp
-
- ignore_column :waf_log_enabled, remove_with: '14.2', remove_after: '2021-07-22'
-
- enum protocol: { tcp: 0, udp: 1 }
-
- validate :has_at_least_one_log_enabled?
-
- def chart
- 'fluentd/fluentd'
- end
-
- def repository
- 'https://gitlab-org.gitlab.io/cluster-integration/helm-stable-archive'
- end
-
- def install_command
- helm_command_module::InstallCommand.new(
- name: 'fluentd',
- repository: repository,
- version: VERSION,
- rbac: cluster.platform_kubernetes_rbac?,
- chart: chart,
- files: files
- )
- end
-
- def values
- content_values.to_yaml
- end
-
- private
-
- def has_at_least_one_log_enabled?
- errors.add(:base, _("At least one logging option is required to be enabled")) unless cilium_log_enabled
- end
-
- def content_values
- YAML.load_file(chart_values_file).deep_merge!(specification)
- end
-
- def specification
- {
- "configMaps" => {
- "output.conf" => output_configuration_content,
- "general.conf" => general_configuration_content
- }
- }
- end
-
- def output_configuration_content
- <<~EOF
- <match kubernetes.**>
- @type remote_syslog
- @id out_kube_remote_syslog
- host #{host}
- port #{port}
- program fluentd
- hostname ${kubernetes_host}
- protocol #{protocol}
- packet_size 131072
- <buffer kubernetes_host>
- </buffer>
- <format>
- @type ltsv
- </format>
- </match>
- EOF
- end
-
- def general_configuration_content
- <<~EOF
- <match fluent.**>
- @type null
- </match>
- <source>
- @type http
- port 9880
- bind 0.0.0.0
- </source>
- <source>
- @type tail
- @id in_tail_container_logs
- path #{path_to_logs}
- pos_file /var/log/fluentd-containers.log.pos
- tag kubernetes.*
- read_from_head true
- <parse>
- @type json
- time_format %Y-%m-%dT%H:%M:%S.%NZ
- </parse>
- </source>
- EOF
- end
-
- def path_to_logs
- path = []
- path << "/var/log/containers/*#{CILIUM_CONTAINER_NAME}*.log" if cilium_log_enabled
- path.join(',')
- end
- end
- end
-end
diff --git a/app/models/clusters/cluster.rb b/app/models/clusters/cluster.rb
index aeebd2b368e..13ec8953353 100644
--- a/app/models/clusters/cluster.rb
+++ b/app/models/clusters/cluster.rb
@@ -21,7 +21,6 @@ module Clusters
Clusters::Applications::Jupyter.application_name => Clusters::Applications::Jupyter,
Clusters::Applications::Knative.application_name => Clusters::Applications::Knative,
Clusters::Applications::ElasticStack.application_name => Clusters::Applications::ElasticStack,
- Clusters::Applications::Fluentd.application_name => Clusters::Applications::Fluentd,
Clusters::Applications::Cilium.application_name => Clusters::Applications::Cilium
}.freeze
DEFAULT_ENVIRONMENT = '*'
@@ -68,7 +67,6 @@ module Clusters
has_one_cluster_application :jupyter
has_one_cluster_application :knative
has_one_cluster_application :elastic_stack
- has_one_cluster_application :fluentd
has_one_cluster_application :cilium
has_many :kubernetes_namespaces
diff --git a/app/serializers/cluster_application_entity.rb b/app/serializers/cluster_application_entity.rb
index fab590dbe09..f57ac4af113 100644
--- a/app/serializers/cluster_application_entity.rb
+++ b/app/serializers/cluster_application_entity.rb
@@ -17,5 +17,4 @@ class ClusterApplicationEntity < Grape::Entity
expose :host, if: -> (e, _) { e.respond_to?(:host) }
expose :port, if: -> (e, _) { e.respond_to?(:port) }
expose :protocol, if: -> (e, _) { e.respond_to?(:protocol) }
- expose :cilium_log_enabled, if: -> (e, _) { e.respond_to?(:cilium_log_enabled) }
end
diff --git a/app/services/ci/job_artifacts/create_service.rb b/app/services/ci/job_artifacts/create_service.rb
index a22ac87f660..9fc7c3b4d40 100644
--- a/app/services/ci/job_artifacts/create_service.rb
+++ b/app/services/ci/job_artifacts/create_service.rb
@@ -115,7 +115,6 @@ module Ci
case artifact.file_type
when 'dotenv' then parse_dotenv_artifact(artifact)
- when 'cluster_applications' then parse_cluster_applications_artifact(artifact)
else success
end
end
@@ -165,10 +164,6 @@ module Ci
def parse_dotenv_artifact(artifact)
Ci::ParseDotenvArtifactService.new(project, current_user).execute(artifact)
end
-
- def parse_cluster_applications_artifact(artifact)
- Clusters::ParseClusterApplicationsArtifactService.new(job, job.user).execute(artifact)
- end
end
end
end
diff --git a/app/services/clusters/applications/base_service.rb b/app/services/clusters/applications/base_service.rb
index 47d6fbbeda2..c6f22cfa04c 100644
--- a/app/services/clusters/applications/base_service.rb
+++ b/app/services/clusters/applications/base_service.rb
@@ -5,8 +5,6 @@ module Clusters
class BaseService
InvalidApplicationError = Class.new(StandardError)
- FLUENTD_KNOWN_ATTRS = %i[host protocol port cilium_log_enabled].freeze
-
attr_reader :cluster, :current_user, :params
def initialize(cluster, user, params = {})
@@ -29,8 +27,6 @@ module Clusters
application.stack = params[:stack]
end
- apply_fluentd_related_attributes(application)
-
if application.respond_to?(:oauth_application)
application.oauth_application = create_oauth_application(application, request)
end
@@ -95,12 +91,6 @@ module Clusters
::Applications::CreateService.new(current_user, oauth_application_params).execute(request)
end
-
- def apply_fluentd_related_attributes(application)
- FLUENTD_KNOWN_ATTRS.each do |attr|
- application[attr] = params[attr] if application.has_attribute?(attr)
- end
- end
end
end
end
diff --git a/app/services/clusters/parse_cluster_applications_artifact_service.rb b/app/services/clusters/parse_cluster_applications_artifact_service.rb
deleted file mode 100644
index b9b2953b6bd..00000000000
--- a/app/services/clusters/parse_cluster_applications_artifact_service.rb
+++ /dev/null
@@ -1,94 +0,0 @@
-# frozen_string_literal: true
-
-module Clusters
- class ParseClusterApplicationsArtifactService < ::BaseService
- include Gitlab::Utils::StrongMemoize
-
- MAX_ACCEPTABLE_ARTIFACT_SIZE = 5.kilobytes
- RELEASE_NAMES = %w[cilium].freeze
-
- def initialize(job, current_user)
- @job = job
-
- super(job.project, current_user)
- end
-
- def execute(artifact)
- raise ArgumentError, 'Artifact is not cluster_applications file type' unless artifact&.cluster_applications?
-
- return error(too_big_error_message, :bad_request) unless artifact.file.size < MAX_ACCEPTABLE_ARTIFACT_SIZE
- return error(no_deployment_message, :bad_request) unless job.deployment
- return error(no_deployment_cluster_message, :bad_request) unless cluster
-
- parse!(artifact)
-
- success
- rescue Gitlab::Kubernetes::Helm::Parsers::ListV2::ParserError, ActiveRecord::RecordInvalid => error
- Gitlab::ErrorTracking.track_exception(error, job_id: artifact.job_id)
- error(error.message, :bad_request)
- end
-
- private
-
- attr_reader :job
-
- def cluster
- strong_memoize(:cluster) do
- deployment_cluster = job.deployment&.cluster
-
- deployment_cluster if Ability.allowed?(current_user, :admin_cluster, deployment_cluster)
- end
- end
-
- def parse!(artifact)
- releases = []
-
- artifact.each_blob do |blob|
- next if blob.empty?
-
- releases.concat(Gitlab::Kubernetes::Helm::Parsers::ListV2.new(blob).releases)
- end
-
- update_cluster_application_statuses!(releases)
- end
-
- def update_cluster_application_statuses!(releases)
- release_by_name = releases.index_by { |release| release['Name'] }
-
- Clusters::Cluster.transaction do
- RELEASE_NAMES.each do |release_name|
- application_class = Clusters::Cluster::APPLICATIONS[release_name]
- application = cluster.find_or_build_application(application_class)
-
- release = release_by_name[release_name]
-
- if release
- case release['Status']
- when 'DEPLOYED'
- application.make_externally_installed!
- when 'FAILED'
- application.make_errored!(s_('ClusterIntegration|Helm release failed to install'))
- end
- else
- # missing, so by definition, we consider this uninstalled
- application.make_externally_uninstalled! if application.persisted?
- end
- end
- end
- end
-
- def too_big_error_message
- human_size = ActiveSupport::NumberHelper.number_to_human_size(MAX_ACCEPTABLE_ARTIFACT_SIZE)
-
- s_('ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}') % { human_size: human_size }
- end
-
- def no_deployment_message
- s_('ClusterIntegration|No deployment found for this job')
- end
-
- def no_deployment_cluster_message
- s_('ClusterIntegration|No deployment cluster found for this job')
- end
- end
-end
diff --git a/app/services/feature_flags/disable_service.rb b/app/services/feature_flags/disable_service.rb
deleted file mode 100644
index 8a443ac1795..00000000000
--- a/app/services/feature_flags/disable_service.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-# frozen_string_literal: true
-
-module FeatureFlags
- class DisableService < BaseService
- def execute
- return error('Feature Flag not found', 404) unless feature_flag_by_name
- return error('Feature Flag Scope not found', 404) unless feature_flag_scope_by_environment_scope
- return error('Strategy not found', 404) unless strategy_exist_in_persisted_data?
-
- ::FeatureFlags::UpdateService
- .new(project, current_user, update_params)
- .execute(feature_flag_by_name)
- end
-
- private
-
- def update_params
- if remaining_strategies.empty?
- params_to_destroy_scope
- else
- params_to_update_scope
- end
- end
-
- def remaining_strategies
- strong_memoize(:remaining_strategies) do
- feature_flag_scope_by_environment_scope.strategies.reject do |strategy|
- strategy['name'] == params[:strategy]['name'] &&
- strategy['parameters'] == params[:strategy]['parameters']
- end
- end
- end
-
- def strategy_exist_in_persisted_data?
- feature_flag_scope_by_environment_scope.strategies != remaining_strategies
- end
-
- def params_to_destroy_scope
- { scopes_attributes: [{ id: feature_flag_scope_by_environment_scope.id, _destroy: true }] }
- end
-
- def params_to_update_scope
- { scopes_attributes: [{ id: feature_flag_scope_by_environment_scope.id, strategies: remaining_strategies }] }
- end
- end
-end
diff --git a/app/services/feature_flags/enable_service.rb b/app/services/feature_flags/enable_service.rb
deleted file mode 100644
index b4cbb32e003..00000000000
--- a/app/services/feature_flags/enable_service.rb
+++ /dev/null
@@ -1,93 +0,0 @@
-# frozen_string_literal: true
-
-module FeatureFlags
- class EnableService < BaseService
- def execute
- if feature_flag_by_name
- update_feature_flag
- else
- create_feature_flag
- end
- end
-
- private
-
- def create_feature_flag
- ::FeatureFlags::CreateService
- .new(project, current_user, create_params)
- .execute
- end
-
- def update_feature_flag
- ::FeatureFlags::UpdateService
- .new(project, current_user, update_params)
- .execute(feature_flag_by_name)
- end
-
- def create_params
- if params[:environment_scope] == '*'
- params_to_create_flag_with_default_scope
- else
- params_to_create_flag_with_additional_scope
- end
- end
-
- def update_params
- if feature_flag_scope_by_environment_scope
- params_to_update_scope
- else
- params_to_create_scope
- end
- end
-
- def params_to_create_flag_with_default_scope
- {
- name: params[:name],
- scopes_attributes: [
- {
- active: true,
- environment_scope: '*',
- strategies: [params[:strategy]]
- }
- ]
- }
- end
-
- def params_to_create_flag_with_additional_scope
- {
- name: params[:name],
- scopes_attributes: [
- {
- active: false,
- environment_scope: '*'
- },
- {
- active: true,
- environment_scope: params[:environment_scope],
- strategies: [params[:strategy]]
- }
- ]
- }
- end
-
- def params_to_create_scope
- {
- scopes_attributes: [{
- active: true,
- environment_scope: params[:environment_scope],
- strategies: [params[:strategy]]
- }]
- }
- end
-
- def params_to_update_scope
- {
- scopes_attributes: [{
- id: feature_flag_scope_by_environment_scope.id,
- active: true,
- strategies: feature_flag_scope_by_environment_scope.strategies | [params[:strategy]]
- }]
- }
- end
- end
-end
diff --git a/app/services/search/project_service.rb b/app/services/search/project_service.rb
index 3181c0098cc..3e93346bfdf 100644
--- a/app/services/search/project_service.rb
+++ b/app/services/search/project_service.rb
@@ -8,8 +8,8 @@ module Search
attr_accessor :project, :current_user, :params
- def initialize(project, user, params)
- @project = project
+ def initialize(project_or_projects, user, params)
+ @project = project_or_projects
@current_user = user
@params = params.dup
end
diff --git a/app/services/search_service.rb b/app/services/search_service.rb
index 389cf17e115..cce7821a226 100644
--- a/app/services/search_service.rb
+++ b/app/services/search_service.rb
@@ -41,6 +41,10 @@ class SearchService
end
# rubocop: enable CodeReuse/ActiveRecord
+ def projects
+ # overridden in EE
+ end
+
def show_snippets?
return @show_snippets if defined?(@show_snippets)
diff --git a/app/views/dashboard/todos/index.html.haml b/app/views/dashboard/todos/index.html.haml
index 52e41946ed1..ca10861115b 100644
--- a/app/views/dashboard/todos/index.html.haml
+++ b/app/views/dashboard/todos/index.html.haml
@@ -37,7 +37,7 @@
.todos-filters
.issues-details-filters.row-content-block.second-block
= form_tag todos_filter_path(without: [:project_id, :author_id, :type, :action_id]), method: :get, class: 'filter-form gl-display-flex gl-flex-direction-column gl-sm-flex-direction-row' do
- .filter-categories.gl-display-flex.gl-flex-direction-column.gl-md-flex-direction-row.gl-flex-fill-1.gl-flex-wrap.gl-mx-n2
+ .filter-categories.gl-display-flex.gl-flex-direction-column.gl-md-flex-direction-row.gl-flex-grow-1.gl-flex-wrap.gl-mx-n2
.filter-item.gl-m-2
- if params[:group_id].present?
= hidden_field_tag(:group_id, params[:group_id])
diff --git a/app/views/layouts/fullscreen.html.haml b/app/views/layouts/fullscreen.html.haml
index b2536090520..2a865aeda40 100644
--- a/app/views/layouts/fullscreen.html.haml
+++ b/app/views/layouts/fullscreen.html.haml
@@ -13,5 +13,5 @@
= render "layouts/flash"
.content-wrapper.hide-when-top-nav-responsive-open{ id: "content-body", class: "d-flex flex-column align-items-stretch" }
= yield
- = render "layouts/nav/top_nav_responsive", class: "gl-flex-fill-1 gl-overflow-y-auto"
+ = render "layouts/nav/top_nav_responsive", class: "gl-flex-grow-1 gl-overflow-y-auto"
= footer_message
diff --git a/app/views/projects/empty.html.haml b/app/views/projects/empty.html.haml
index 365f9fb46fa..027b81d6c68 100644
--- a/app/views/projects/empty.html.haml
+++ b/app/views/projects/empty.html.haml
@@ -44,6 +44,7 @@
:preserve
git clone #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
cd #{h @project.path}
+ git switch -c #{default_branch_name}
touch README.md
git add README.md
git commit -m "add README"
@@ -56,7 +57,7 @@
%pre.bg-light
:preserve
cd existing_folder
- git init
+ git init --initial-branch=#{default_branch_name}
git remote add origin #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
git add .
git commit -m "Initial commit"
diff --git a/app/views/search/_results.html.haml b/app/views/search/_results.html.haml
index d5fbee34fa0..4ba906dd02f 100644
--- a/app/views/search/_results.html.haml
+++ b/app/views/search/_results.html.haml
@@ -4,7 +4,7 @@
.gl-md-display-flex
- if %w(issues merge_requests).include?(@scope)
#js-search-sidebar{ class: search_bar_classes }
- .gl-w-full.gl-flex-fill-1.gl-overflow-x-hidden
+ .gl-w-full.gl-flex-grow-1.gl-overflow-x-hidden
= render partial: "search/results/empty"
= render_if_exists 'shared/promotions/promote_advanced_search'
- else
@@ -14,7 +14,7 @@
.results.gl-md-display-flex.gl-mt-3
- if %w(issues merge_requests).include?(@scope)
#js-search-sidebar{ class: search_bar_classes }
- .gl-w-full.gl-flex-fill-1.gl-overflow-x-hidden
+ .gl-w-full.gl-flex-grow-1.gl-overflow-x-hidden
- if @scope == 'commits'
%ul.content-list.commit-list
= render partial: "search/results/commit", collection: @search_objects
diff --git a/app/views/shared/wikis/diff.html.haml b/app/views/shared/wikis/diff.html.haml
index 19167f04855..0eeceac28c8 100644
--- a/app/views/shared/wikis/diff.html.haml
+++ b/app/views/shared/wikis/diff.html.haml
@@ -5,7 +5,7 @@
.wiki-page-header.top-area.has-sidebar-toggle.flex-column.flex-lg-row
= wiki_sidebar_toggle_button
- %h3.page-title.gl-flex-fill-1
+ %h3.page-title.gl-flex-grow-1
= link_to_wiki_page @page
%span.light
&middot;
diff --git a/app/views/shared/wikis/edit.html.haml b/app/views/shared/wikis/edit.html.haml
index 4bdeee3996f..729646c2731 100644
--- a/app/views/shared/wikis/edit.html.haml
+++ b/app/views/shared/wikis/edit.html.haml
@@ -7,7 +7,7 @@
.wiki-page-header.top-area.has-sidebar-toggle.flex-column.flex-lg-row
= wiki_sidebar_toggle_button
- %h3.page-title.gl-flex-fill-1
+ %h3.page-title.gl-flex-grow-1
- if @page.persisted?
= link_to_wiki_page @page
%span.light
diff --git a/app/views/shared/wikis/pages.html.haml b/app/views/shared/wikis/pages.html.haml
index 1889b6501c9..c1918198594 100644
--- a/app/views/shared/wikis/pages.html.haml
+++ b/app/views/shared/wikis/pages.html.haml
@@ -5,7 +5,7 @@
- add_page_specific_style 'page_bundles/wiki'
.wiki-page-header.top-area.flex-column.flex-lg-row
- %h3.page-title.gl-flex-fill-1
+ %h3.page-title.gl-flex-grow-1
= s_("Wiki|Wiki Pages")
.nav-controls.pb-md-3.pb-lg-0
diff --git a/config/feature_flags/development/remove_legacy_flags.yml b/config/feature_flags/development/advanced_search_multi_project_select.yml
index 68723af2de9..4f38955fa71 100644
--- a/config/feature_flags/development/remove_legacy_flags.yml
+++ b/config/feature_flags/development/advanced_search_multi_project_select.yml
@@ -1,8 +1,8 @@
---
-name: remove_legacy_flags
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62484
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/332243
+name: advanced_search_multi_project_select
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62606
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/333011
milestone: '14.0'
type: development
-group: group::release
+group: group::global search
default_enabled: false
diff --git a/config/feature_flags/development/feature_flag_api.yml b/config/feature_flags/development/feature_flag_api.yml
deleted file mode 100644
index 167b5ff4cf2..00000000000
--- a/config/feature_flags/development/feature_flag_api.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: feature_flag_api
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/18198
-rollout_issue_url:
-milestone: '12.4'
-type: development
-group: group::release
-default_enabled: false
diff --git a/config/feature_flags/development/remove_legacy_flags_override.yml b/config/feature_flags/development/remove_legacy_flags_override.yml
deleted file mode 100644
index 17b0ae48505..00000000000
--- a/config/feature_flags/development/remove_legacy_flags_override.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: remove_legacy_flags_override
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62484
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/332243
-milestone: '14.0'
-type: development
-group: group::release
-default_enabled: false
diff --git a/config/metrics/counts_28d/20210421144352_i_code_review_click_single_file_mode_setting_monthly.yml b/config/metrics/counts_28d/20210421144352_i_code_review_click_single_file_mode_setting_monthly.yml
index 2bcd2a448ec..a3d27ec7fd9 100644
--- a/config/metrics/counts_28d/20210421144352_i_code_review_click_single_file_mode_setting_monthly.yml
+++ b/config/metrics/counts_28d/20210421144352_i_code_review_click_single_file_mode_setting_monthly.yml
@@ -6,7 +6,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: implemented
+status: data_available
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210421145818_i_code_review_click_file_browser_setting_monthly.yml b/config/metrics/counts_28d/20210421145818_i_code_review_click_file_browser_setting_monthly.yml
index 3b7c5be9b84..1bacc4d30dc 100644
--- a/config/metrics/counts_28d/20210421145818_i_code_review_click_file_browser_setting_monthly.yml
+++ b/config/metrics/counts_28d/20210421145818_i_code_review_click_file_browser_setting_monthly.yml
@@ -6,7 +6,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: implemented
+status: data_available
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210421145945_i_code_review_click_whitespace_setting_monthly.yml b/config/metrics/counts_28d/20210421145945_i_code_review_click_whitespace_setting_monthly.yml
index 31fe497fe0e..b9c7d00b8b3 100644
--- a/config/metrics/counts_28d/20210421145945_i_code_review_click_whitespace_setting_monthly.yml
+++ b/config/metrics/counts_28d/20210421145945_i_code_review_click_whitespace_setting_monthly.yml
@@ -6,7 +6,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: implemented
+status: data_available
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210422101516_i_code_review_diff_view_inline_monthly.yml b/config/metrics/counts_28d/20210422101516_i_code_review_diff_view_inline_monthly.yml
index 821f7244209..dc7f22008a7 100644
--- a/config/metrics/counts_28d/20210422101516_i_code_review_diff_view_inline_monthly.yml
+++ b/config/metrics/counts_28d/20210422101516_i_code_review_diff_view_inline_monthly.yml
@@ -6,7 +6,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: implemented
+status: data_available
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210422101613_i_code_review_diff_view_parallel_monthly.yml b/config/metrics/counts_28d/20210422101613_i_code_review_diff_view_parallel_monthly.yml
index 04ff06143af..a6102f8f936 100644
--- a/config/metrics/counts_28d/20210422101613_i_code_review_diff_view_parallel_monthly.yml
+++ b/config/metrics/counts_28d/20210422101613_i_code_review_diff_view_parallel_monthly.yml
@@ -6,7 +6,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: implemented
+status: data_available
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210422101753_i_code_review_file_browser_tree_view_monthly.yml b/config/metrics/counts_28d/20210422101753_i_code_review_file_browser_tree_view_monthly.yml
index ad5b5e835c1..e8539fa483b 100644
--- a/config/metrics/counts_28d/20210422101753_i_code_review_file_browser_tree_view_monthly.yml
+++ b/config/metrics/counts_28d/20210422101753_i_code_review_file_browser_tree_view_monthly.yml
@@ -6,7 +6,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: implemented
+status: data_available
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210422101852_i_code_review_file_browser_list_view_monthly.yml b/config/metrics/counts_28d/20210422101852_i_code_review_file_browser_list_view_monthly.yml
index c71bacd6004..b3b1cb0b54e 100644
--- a/config/metrics/counts_28d/20210422101852_i_code_review_file_browser_list_view_monthly.yml
+++ b/config/metrics/counts_28d/20210422101852_i_code_review_file_browser_list_view_monthly.yml
@@ -6,7 +6,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: implemented
+status: data_available
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210422101928_i_code_review_diff_show_whitespace_monthly.yml b/config/metrics/counts_28d/20210422101928_i_code_review_diff_show_whitespace_monthly.yml
index 0d17fa0d965..006e345f0f0 100644
--- a/config/metrics/counts_28d/20210422101928_i_code_review_diff_show_whitespace_monthly.yml
+++ b/config/metrics/counts_28d/20210422101928_i_code_review_diff_show_whitespace_monthly.yml
@@ -6,7 +6,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: implemented
+status: data_available
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210422102010_i_code_review_diff_hide_whitespace_monthly.yml b/config/metrics/counts_28d/20210422102010_i_code_review_diff_hide_whitespace_monthly.yml
index 6038bb5cda8..273a98da172 100644
--- a/config/metrics/counts_28d/20210422102010_i_code_review_diff_hide_whitespace_monthly.yml
+++ b/config/metrics/counts_28d/20210422102010_i_code_review_diff_hide_whitespace_monthly.yml
@@ -6,7 +6,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: implemented
+status: data_available
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210422102121_i_code_review_diff_single_file_monthly.yml b/config/metrics/counts_28d/20210422102121_i_code_review_diff_single_file_monthly.yml
index 3cfcdf23a47..17ce7101133 100644
--- a/config/metrics/counts_28d/20210422102121_i_code_review_diff_single_file_monthly.yml
+++ b/config/metrics/counts_28d/20210422102121_i_code_review_diff_single_file_monthly.yml
@@ -6,7 +6,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: implemented
+status: data_available
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210422102202_i_code_review_diff_multiple_files_monthly.yml b/config/metrics/counts_28d/20210422102202_i_code_review_diff_multiple_files_monthly.yml
index 16784a0c408..cde5800cf60 100644
--- a/config/metrics/counts_28d/20210422102202_i_code_review_diff_multiple_files_monthly.yml
+++ b/config/metrics/counts_28d/20210422102202_i_code_review_diff_multiple_files_monthly.yml
@@ -6,7 +6,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: implemented
+status: data_available
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210427102618_code_review_category_monthly_active_users.yml b/config/metrics/counts_28d/20210427102618_code_review_category_monthly_active_users.yml
index 224fd6477cc..53757c27ca2 100644
--- a/config/metrics/counts_28d/20210427102618_code_review_category_monthly_active_users.yml
+++ b/config/metrics/counts_28d/20210427102618_code_review_category_monthly_active_users.yml
@@ -7,7 +7,7 @@ product_stage:
product_group:
product_category:
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url:
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210427103010_code_review_extension_category_monthly_active_users.yml b/config/metrics/counts_28d/20210427103010_code_review_extension_category_monthly_active_users.yml
index ba872d725df..9d79661bf27 100644
--- a/config/metrics/counts_28d/20210427103010_code_review_extension_category_monthly_active_users.yml
+++ b/config/metrics/counts_28d/20210427103010_code_review_extension_category_monthly_active_users.yml
@@ -7,7 +7,7 @@ product_stage:
product_group:
product_category:
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url:
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210427103119_code_review_group_monthly_active_users.yml b/config/metrics/counts_28d/20210427103119_code_review_group_monthly_active_users.yml
index e0e6bb0567d..492c50c4838 100644
--- a/config/metrics/counts_28d/20210427103119_code_review_group_monthly_active_users.yml
+++ b/config/metrics/counts_28d/20210427103119_code_review_group_monthly_active_users.yml
@@ -7,7 +7,7 @@ product_stage:
product_group:
product_category:
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url:
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210427105033_pipeline_authoring_total_unique_counts_monthly.yml b/config/metrics/counts_28d/20210427105033_pipeline_authoring_total_unique_counts_monthly.yml
index 594df7ebe26..edd385da9ce 100644
--- a/config/metrics/counts_28d/20210427105033_pipeline_authoring_total_unique_counts_monthly.yml
+++ b/config/metrics/counts_28d/20210427105033_pipeline_authoring_total_unique_counts_monthly.yml
@@ -7,7 +7,7 @@ product_stage:
product_group:
product_category:
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url:
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210427213346_geo_secondary_web_oauth_users.yml b/config/metrics/counts_28d/20210427213346_geo_secondary_web_oauth_users.yml
index 0f68989cc1d..dc08952bb18 100644
--- a/config/metrics/counts_28d/20210427213346_geo_secondary_web_oauth_users.yml
+++ b/config/metrics/counts_28d/20210427213346_geo_secondary_web_oauth_users.yml
@@ -7,7 +7,7 @@ product_stage:
product_group:
product_category:
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url:
time_frame: 28d
diff --git a/config/metrics/counts_28d/20210514013545_i_code_review_user_resolve_conflict_monthly.yml b/config/metrics/counts_28d/20210514013545_i_code_review_user_resolve_conflict_monthly.yml
index 2a39317f76c..c685e277215 100644
--- a/config/metrics/counts_28d/20210514013545_i_code_review_user_resolve_conflict_monthly.yml
+++ b/config/metrics/counts_28d/20210514013545_i_code_review_user_resolve_conflict_monthly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
time_frame: 28d
data_source: redis_hll
diff --git a/config/metrics/counts_28d/20210514013549_i_code_review_user_load_conflict_ui_monthly.yml b/config/metrics/counts_28d/20210514013549_i_code_review_user_load_conflict_ui_monthly.yml
index f031fb33c88..e421203a195 100644
--- a/config/metrics/counts_28d/20210514013549_i_code_review_user_load_conflict_ui_monthly.yml
+++ b/config/metrics/counts_28d/20210514013549_i_code_review_user_load_conflict_ui_monthly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
time_frame: 28d
data_source: redis_hll
diff --git a/config/metrics/counts_28d/20210607113556_i_code_review_click_diff_view_setting_monthly.yml b/config/metrics/counts_28d/20210607113556_i_code_review_click_diff_view_setting_monthly.yml
index b172f85dc1f..04edbaf1ec1 100644
--- a/config/metrics/counts_28d/20210607113556_i_code_review_click_diff_view_setting_monthly.yml
+++ b/config/metrics/counts_28d/20210607113556_i_code_review_click_diff_view_setting_monthly.yml
@@ -6,7 +6,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: implemented
+status: data_available
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 28d
diff --git a/config/metrics/counts_7d/20210421144349_i_code_review_click_single_file_mode_setting_weekly.yml b/config/metrics/counts_7d/20210421144349_i_code_review_click_single_file_mode_setting_weekly.yml
index 179d2fa6e47..050ca64f03c 100644
--- a/config/metrics/counts_7d/20210421144349_i_code_review_click_single_file_mode_setting_weekly.yml
+++ b/config/metrics/counts_7d/20210421144349_i_code_review_click_single_file_mode_setting_weekly.yml
@@ -6,7 +6,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: implemented
+status: data_available
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210421145814_i_code_review_click_file_browser_setting_weekly.yml b/config/metrics/counts_7d/20210421145814_i_code_review_click_file_browser_setting_weekly.yml
index 50264bf27cf..eb73d4841b4 100644
--- a/config/metrics/counts_7d/20210421145814_i_code_review_click_file_browser_setting_weekly.yml
+++ b/config/metrics/counts_7d/20210421145814_i_code_review_click_file_browser_setting_weekly.yml
@@ -6,7 +6,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: implemented
+status: data_available
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210421145942_i_code_review_click_whitespace_setting_weekly.yml b/config/metrics/counts_7d/20210421145942_i_code_review_click_whitespace_setting_weekly.yml
index 3206bac8b49..4159716f919 100644
--- a/config/metrics/counts_7d/20210421145942_i_code_review_click_whitespace_setting_weekly.yml
+++ b/config/metrics/counts_7d/20210421145942_i_code_review_click_whitespace_setting_weekly.yml
@@ -6,7 +6,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: implemented
+status: data_available
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210422101512_i_code_review_diff_view_inline_weekly.yml b/config/metrics/counts_7d/20210422101512_i_code_review_diff_view_inline_weekly.yml
index 7a3a606c886..0c53c7733b1 100644
--- a/config/metrics/counts_7d/20210422101512_i_code_review_diff_view_inline_weekly.yml
+++ b/config/metrics/counts_7d/20210422101512_i_code_review_diff_view_inline_weekly.yml
@@ -6,7 +6,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: implemented
+status: data_available
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210422101609_i_code_review_diff_view_parallel_weekly.yml b/config/metrics/counts_7d/20210422101609_i_code_review_diff_view_parallel_weekly.yml
index 36dbeae82e7..3d956eea357 100644
--- a/config/metrics/counts_7d/20210422101609_i_code_review_diff_view_parallel_weekly.yml
+++ b/config/metrics/counts_7d/20210422101609_i_code_review_diff_view_parallel_weekly.yml
@@ -6,7 +6,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: implemented
+status: data_available
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210422101750_i_code_review_file_browser_tree_view_weekly.yml b/config/metrics/counts_7d/20210422101750_i_code_review_file_browser_tree_view_weekly.yml
index ef74ff6613f..97067bcc02f 100644
--- a/config/metrics/counts_7d/20210422101750_i_code_review_file_browser_tree_view_weekly.yml
+++ b/config/metrics/counts_7d/20210422101750_i_code_review_file_browser_tree_view_weekly.yml
@@ -6,7 +6,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: implemented
+status: data_available
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210422101849_i_code_review_file_browser_list_view_weekly.yml b/config/metrics/counts_7d/20210422101849_i_code_review_file_browser_list_view_weekly.yml
index e2b9f141bb7..094d2ee6ce8 100644
--- a/config/metrics/counts_7d/20210422101849_i_code_review_file_browser_list_view_weekly.yml
+++ b/config/metrics/counts_7d/20210422101849_i_code_review_file_browser_list_view_weekly.yml
@@ -6,7 +6,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: implemented
+status: data_available
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210422101925_i_code_review_diff_show_whitespace_weekly.yml b/config/metrics/counts_7d/20210422101925_i_code_review_diff_show_whitespace_weekly.yml
index 6cca3840faa..c58b03ce909 100644
--- a/config/metrics/counts_7d/20210422101925_i_code_review_diff_show_whitespace_weekly.yml
+++ b/config/metrics/counts_7d/20210422101925_i_code_review_diff_show_whitespace_weekly.yml
@@ -6,7 +6,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: implemented
+status: data_available
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210422102007_i_code_review_diff_hide_whitespace_weekly.yml b/config/metrics/counts_7d/20210422102007_i_code_review_diff_hide_whitespace_weekly.yml
index c1fccc9f774..b0a04b9bff5 100644
--- a/config/metrics/counts_7d/20210422102007_i_code_review_diff_hide_whitespace_weekly.yml
+++ b/config/metrics/counts_7d/20210422102007_i_code_review_diff_hide_whitespace_weekly.yml
@@ -6,7 +6,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: implemented
+status: data_available
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210422102118_i_code_review_diff_single_file_weekly.yml b/config/metrics/counts_7d/20210422102118_i_code_review_diff_single_file_weekly.yml
index 3b1abf6e0e1..64f3f452d79 100644
--- a/config/metrics/counts_7d/20210422102118_i_code_review_diff_single_file_weekly.yml
+++ b/config/metrics/counts_7d/20210422102118_i_code_review_diff_single_file_weekly.yml
@@ -6,7 +6,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: implemented
+status: data_available
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210422102159_i_code_review_diff_multiple_files_weekly.yml b/config/metrics/counts_7d/20210422102159_i_code_review_diff_multiple_files_weekly.yml
index b3105b041f8..fe0bd0ba906 100644
--- a/config/metrics/counts_7d/20210422102159_i_code_review_diff_multiple_files_weekly.yml
+++ b/config/metrics/counts_7d/20210422102159_i_code_review_diff_multiple_files_weekly.yml
@@ -6,7 +6,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: implemented
+status: data_available
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210427103328_code_review_group_monthly_active_users.yml b/config/metrics/counts_7d/20210427103328_code_review_group_monthly_active_users.yml
index 31b36bc8ad7..eb1a803ad08 100644
--- a/config/metrics/counts_7d/20210427103328_code_review_group_monthly_active_users.yml
+++ b/config/metrics/counts_7d/20210427103328_code_review_group_monthly_active_users.yml
@@ -7,7 +7,7 @@ product_stage:
product_group:
product_category:
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url:
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210427103407_code_review_category_monthly_active_users.yml b/config/metrics/counts_7d/20210427103407_code_review_category_monthly_active_users.yml
index aaf9350cdaa..efed507fca3 100644
--- a/config/metrics/counts_7d/20210427103407_code_review_category_monthly_active_users.yml
+++ b/config/metrics/counts_7d/20210427103407_code_review_category_monthly_active_users.yml
@@ -7,7 +7,7 @@ product_stage:
product_group:
product_category:
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url:
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210427103452_code_review_extension_category_monthly_active_users.yml b/config/metrics/counts_7d/20210427103452_code_review_extension_category_monthly_active_users.yml
index ded67e19e10..0452b4a418b 100644
--- a/config/metrics/counts_7d/20210427103452_code_review_extension_category_monthly_active_users.yml
+++ b/config/metrics/counts_7d/20210427103452_code_review_extension_category_monthly_active_users.yml
@@ -7,7 +7,7 @@ product_stage:
product_group:
product_category:
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url:
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210427105030_pipeline_authoring_total_unique_counts_weekly.yml b/config/metrics/counts_7d/20210427105030_pipeline_authoring_total_unique_counts_weekly.yml
index 7f782d90f8d..da3b2f7bccd 100644
--- a/config/metrics/counts_7d/20210427105030_pipeline_authoring_total_unique_counts_weekly.yml
+++ b/config/metrics/counts_7d/20210427105030_pipeline_authoring_total_unique_counts_weekly.yml
@@ -7,7 +7,7 @@ product_stage:
product_group:
product_category:
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url:
time_frame: 7d
diff --git a/config/metrics/counts_7d/20210514013544_i_code_review_user_load_conflict_ui_weekly.yml b/config/metrics/counts_7d/20210514013544_i_code_review_user_load_conflict_ui_weekly.yml
index 0a2410b9ed5..0ab87e2917e 100644
--- a/config/metrics/counts_7d/20210514013544_i_code_review_user_load_conflict_ui_weekly.yml
+++ b/config/metrics/counts_7d/20210514013544_i_code_review_user_load_conflict_ui_weekly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
time_frame: 7d
data_source: redis_hll
diff --git a/config/metrics/counts_7d/20210514013545_i_code_review_user_resolve_conflict_weekly.yml b/config/metrics/counts_7d/20210514013545_i_code_review_user_resolve_conflict_weekly.yml
index 4ea6c847c49..417483200e3 100644
--- a/config/metrics/counts_7d/20210514013545_i_code_review_user_resolve_conflict_weekly.yml
+++ b/config/metrics/counts_7d/20210514013545_i_code_review_user_resolve_conflict_weekly.yml
@@ -7,7 +7,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
time_frame: 28d
data_source: redis_hll
diff --git a/config/metrics/counts_7d/20210607113552_i_code_review_click_diff_view_setting_weekly.yml b/config/metrics/counts_7d/20210607113552_i_code_review_click_diff_view_setting_weekly.yml
index 1770980aa3a..6d7f47cede4 100644
--- a/config/metrics/counts_7d/20210607113552_i_code_review_click_diff_view_setting_weekly.yml
+++ b/config/metrics/counts_7d/20210607113552_i_code_review_click_diff_view_setting_weekly.yml
@@ -6,7 +6,7 @@ product_stage: create
product_group: group::code review
product_category: code_review
value_type: number
-status: implemented
+status: data_available
milestone: '13.12'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59979
time_frame: 7d
diff --git a/config/metrics/counts_all/20210423005644_i_analytics_dev_ops_adoption.yml b/config/metrics/counts_all/20210423005644_i_analytics_dev_ops_adoption.yml
index 54dffb5573a..25b6c0f4e93 100644
--- a/config/metrics/counts_all/20210423005644_i_analytics_dev_ops_adoption.yml
+++ b/config/metrics/counts_all/20210423005644_i_analytics_dev_ops_adoption.yml
@@ -7,7 +7,7 @@ product_stage:
product_group:
product_category:
value_type: number
-status: implemented
+status: data_available
milestone: "13.11"
introduced_by_url:
time_frame: all
diff --git a/config/metrics/counts_all/20210427212450_geo_secondary_web_oauth_users.yml b/config/metrics/counts_all/20210427212450_geo_secondary_web_oauth_users.yml
index 0ce05fb84e2..d1a818fe3e1 100644
--- a/config/metrics/counts_all/20210427212450_geo_secondary_web_oauth_users.yml
+++ b/config/metrics/counts_all/20210427212450_geo_secondary_web_oauth_users.yml
@@ -7,7 +7,7 @@ product_stage:
product_group:
product_category:
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url:
time_frame: all
diff --git a/config/metrics/counts_all/20210428142406_users_viewing_analytics_group_devops_adoption.yml b/config/metrics/counts_all/20210428142406_users_viewing_analytics_group_devops_adoption.yml
index c3fb808541a..2a6a56a1f5a 100644
--- a/config/metrics/counts_all/20210428142406_users_viewing_analytics_group_devops_adoption.yml
+++ b/config/metrics/counts_all/20210428142406_users_viewing_analytics_group_devops_adoption.yml
@@ -7,7 +7,7 @@ product_stage:
product_group:
product_category:
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url:
time_frame: all
diff --git a/config/metrics/counts_all/20210502045402_ci_runners_instance_type_active.yml b/config/metrics/counts_all/20210502045402_ci_runners_instance_type_active.yml
index 425869d5a81..f66bb2c85c9 100644
--- a/config/metrics/counts_all/20210502045402_ci_runners_instance_type_active.yml
+++ b/config/metrics/counts_all/20210502045402_ci_runners_instance_type_active.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58197
time_frame: all
diff --git a/config/metrics/counts_all/20210502050341_ci_runners_group_type_active.yml b/config/metrics/counts_all/20210502050341_ci_runners_group_type_active.yml
index 7896738aab6..c6abe0905a4 100644
--- a/config/metrics/counts_all/20210502050341_ci_runners_group_type_active.yml
+++ b/config/metrics/counts_all/20210502050341_ci_runners_group_type_active.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58197
time_frame: all
diff --git a/config/metrics/counts_all/20210502050834_ci_runners_project_type_active.yml b/config/metrics/counts_all/20210502050834_ci_runners_project_type_active.yml
index 94d4956899d..fda2b529b30 100644
--- a/config/metrics/counts_all/20210502050834_ci_runners_project_type_active.yml
+++ b/config/metrics/counts_all/20210502050834_ci_runners_project_type_active.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58197
time_frame: all
diff --git a/config/metrics/counts_all/20210502050942_ci_runners_online.yml b/config/metrics/counts_all/20210502050942_ci_runners_online.yml
index 8922524c4c2..201ffaeb415 100644
--- a/config/metrics/counts_all/20210502050942_ci_runners_online.yml
+++ b/config/metrics/counts_all/20210502050942_ci_runners_online.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58197
time_frame: all
diff --git a/config/metrics/counts_all/20210502051651_ci_runners_instance_type_active_online.yml b/config/metrics/counts_all/20210502051651_ci_runners_instance_type_active_online.yml
index 04f9bc3e762..920ec24e9e7 100644
--- a/config/metrics/counts_all/20210502051651_ci_runners_instance_type_active_online.yml
+++ b/config/metrics/counts_all/20210502051651_ci_runners_instance_type_active_online.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58197
time_frame: all
diff --git a/config/metrics/counts_all/20210502051922_ci_runners_group_type_active_online.yml b/config/metrics/counts_all/20210502051922_ci_runners_group_type_active_online.yml
index 9c24740eca1..e88530d97c8 100644
--- a/config/metrics/counts_all/20210502051922_ci_runners_group_type_active_online.yml
+++ b/config/metrics/counts_all/20210502051922_ci_runners_group_type_active_online.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58197
time_frame: all
diff --git a/config/metrics/counts_all/20210502052036_ci_runners_project_type_active_online.yml b/config/metrics/counts_all/20210502052036_ci_runners_project_type_active_online.yml
index 64c39337be2..7ce3ee6ce8b 100644
--- a/config/metrics/counts_all/20210502052036_ci_runners_project_type_active_online.yml
+++ b/config/metrics/counts_all/20210502052036_ci_runners_project_type_active_online.yml
@@ -7,7 +7,7 @@ product_stage: verify
product_group: group::pipeline execution
product_category: continuous_integration
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58197
time_frame: all
diff --git a/config/metrics/counts_all/20210510201537_in_product_marketing_email_create_0_sent.yml b/config/metrics/counts_all/20210510201537_in_product_marketing_email_create_0_sent.yml
index bbfae3eb114..52dd38bab8d 100644
--- a/config/metrics/counts_all/20210510201537_in_product_marketing_email_create_0_sent.yml
+++ b/config/metrics/counts_all/20210510201537_in_product_marketing_email_create_0_sent.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510201919_in_product_marketing_email_create_0_cta_clicked.yml b/config/metrics/counts_all/20210510201919_in_product_marketing_email_create_0_cta_clicked.yml
index a2cf7c6d813..65440e73542 100644
--- a/config/metrics/counts_all/20210510201919_in_product_marketing_email_create_0_cta_clicked.yml
+++ b/config/metrics/counts_all/20210510201919_in_product_marketing_email_create_0_cta_clicked.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510202148_in_product_marketing_email_create_1_sent.yml b/config/metrics/counts_all/20210510202148_in_product_marketing_email_create_1_sent.yml
index 85552f42431..3701f0a3ba3 100644
--- a/config/metrics/counts_all/20210510202148_in_product_marketing_email_create_1_sent.yml
+++ b/config/metrics/counts_all/20210510202148_in_product_marketing_email_create_1_sent.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510202356_in_product_marketing_email_create_1_cta_clicked.yml b/config/metrics/counts_all/20210510202356_in_product_marketing_email_create_1_cta_clicked.yml
index 7a1e5f28c22..70c0257481d 100644
--- a/config/metrics/counts_all/20210510202356_in_product_marketing_email_create_1_cta_clicked.yml
+++ b/config/metrics/counts_all/20210510202356_in_product_marketing_email_create_1_cta_clicked.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510202604_in_product_marketing_email_create_2_sent.yml b/config/metrics/counts_all/20210510202604_in_product_marketing_email_create_2_sent.yml
index 02d5ae115bb..8d8eb4630d3 100644
--- a/config/metrics/counts_all/20210510202604_in_product_marketing_email_create_2_sent.yml
+++ b/config/metrics/counts_all/20210510202604_in_product_marketing_email_create_2_sent.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510202724_in_product_marketing_email_create_2_cta_clicked.yml b/config/metrics/counts_all/20210510202724_in_product_marketing_email_create_2_cta_clicked.yml
index 75eafa3a54f..965efa41883 100644
--- a/config/metrics/counts_all/20210510202724_in_product_marketing_email_create_2_cta_clicked.yml
+++ b/config/metrics/counts_all/20210510202724_in_product_marketing_email_create_2_cta_clicked.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510202807_in_product_marketing_email_verify_0_sent.yml b/config/metrics/counts_all/20210510202807_in_product_marketing_email_verify_0_sent.yml
index 0a5a9ef936f..2e5bbc29d2c 100644
--- a/config/metrics/counts_all/20210510202807_in_product_marketing_email_verify_0_sent.yml
+++ b/config/metrics/counts_all/20210510202807_in_product_marketing_email_verify_0_sent.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510202943_in_product_marketing_email_verify_0_cta_clicked.yml b/config/metrics/counts_all/20210510202943_in_product_marketing_email_verify_0_cta_clicked.yml
index 17e677ba29d..23ed471a295 100644
--- a/config/metrics/counts_all/20210510202943_in_product_marketing_email_verify_0_cta_clicked.yml
+++ b/config/metrics/counts_all/20210510202943_in_product_marketing_email_verify_0_cta_clicked.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510202955_in_product_marketing_email_verify_1_sent.yml b/config/metrics/counts_all/20210510202955_in_product_marketing_email_verify_1_sent.yml
index 2bad6d31db2..992b39fbd1c 100644
--- a/config/metrics/counts_all/20210510202955_in_product_marketing_email_verify_1_sent.yml
+++ b/config/metrics/counts_all/20210510202955_in_product_marketing_email_verify_1_sent.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510203005_in_product_marketing_email_verify_1_cta_clicked.yml b/config/metrics/counts_all/20210510203005_in_product_marketing_email_verify_1_cta_clicked.yml
index 66080d46e7f..bd9378867e6 100644
--- a/config/metrics/counts_all/20210510203005_in_product_marketing_email_verify_1_cta_clicked.yml
+++ b/config/metrics/counts_all/20210510203005_in_product_marketing_email_verify_1_cta_clicked.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510203015_in_product_marketing_email_verify_2_sent.yml b/config/metrics/counts_all/20210510203015_in_product_marketing_email_verify_2_sent.yml
index 2beabb8b007..5b74bfd8d8c 100644
--- a/config/metrics/counts_all/20210510203015_in_product_marketing_email_verify_2_sent.yml
+++ b/config/metrics/counts_all/20210510203015_in_product_marketing_email_verify_2_sent.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510203025_in_product_marketing_email_verify_2_cta_clicked.yml b/config/metrics/counts_all/20210510203025_in_product_marketing_email_verify_2_cta_clicked.yml
index 7213c463fa9..e30f41d003a 100644
--- a/config/metrics/counts_all/20210510203025_in_product_marketing_email_verify_2_cta_clicked.yml
+++ b/config/metrics/counts_all/20210510203025_in_product_marketing_email_verify_2_cta_clicked.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510203035_in_product_marketing_email_trial_0_sent.yml b/config/metrics/counts_all/20210510203035_in_product_marketing_email_trial_0_sent.yml
index dc566f03898..555c0f1e47f 100644
--- a/config/metrics/counts_all/20210510203035_in_product_marketing_email_trial_0_sent.yml
+++ b/config/metrics/counts_all/20210510203035_in_product_marketing_email_trial_0_sent.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510203044_in_product_marketing_email_trial_0_cta_clicked.yml b/config/metrics/counts_all/20210510203044_in_product_marketing_email_trial_0_cta_clicked.yml
index a3cf714e5ad..23d8a6be343 100644
--- a/config/metrics/counts_all/20210510203044_in_product_marketing_email_trial_0_cta_clicked.yml
+++ b/config/metrics/counts_all/20210510203044_in_product_marketing_email_trial_0_cta_clicked.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510203054_in_product_marketing_email_trial_1_sent.yml b/config/metrics/counts_all/20210510203054_in_product_marketing_email_trial_1_sent.yml
index f5215090b7e..794eaaf01c8 100644
--- a/config/metrics/counts_all/20210510203054_in_product_marketing_email_trial_1_sent.yml
+++ b/config/metrics/counts_all/20210510203054_in_product_marketing_email_trial_1_sent.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510203104_in_product_marketing_email_trial_1_cta_clicked.yml b/config/metrics/counts_all/20210510203104_in_product_marketing_email_trial_1_cta_clicked.yml
index 651c5426e2a..d8172d035b3 100644
--- a/config/metrics/counts_all/20210510203104_in_product_marketing_email_trial_1_cta_clicked.yml
+++ b/config/metrics/counts_all/20210510203104_in_product_marketing_email_trial_1_cta_clicked.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510203114_in_product_marketing_email_trial_2_sent.yml b/config/metrics/counts_all/20210510203114_in_product_marketing_email_trial_2_sent.yml
index 4be98d45ce2..f781a32cd65 100644
--- a/config/metrics/counts_all/20210510203114_in_product_marketing_email_trial_2_sent.yml
+++ b/config/metrics/counts_all/20210510203114_in_product_marketing_email_trial_2_sent.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510203124_in_product_marketing_email_trial_2_cta_clicked.yml b/config/metrics/counts_all/20210510203124_in_product_marketing_email_trial_2_cta_clicked.yml
index 6be928da906..a79425144ac 100644
--- a/config/metrics/counts_all/20210510203124_in_product_marketing_email_trial_2_cta_clicked.yml
+++ b/config/metrics/counts_all/20210510203124_in_product_marketing_email_trial_2_cta_clicked.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510203134_in_product_marketing_email_team_0_sent.yml b/config/metrics/counts_all/20210510203134_in_product_marketing_email_team_0_sent.yml
index ac9ffa730f1..d84f9b6d794 100644
--- a/config/metrics/counts_all/20210510203134_in_product_marketing_email_team_0_sent.yml
+++ b/config/metrics/counts_all/20210510203134_in_product_marketing_email_team_0_sent.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510203143_in_product_marketing_email_team_0_cta_clicked.yml b/config/metrics/counts_all/20210510203143_in_product_marketing_email_team_0_cta_clicked.yml
index cf51512c6eb..35a9797f2fe 100644
--- a/config/metrics/counts_all/20210510203143_in_product_marketing_email_team_0_cta_clicked.yml
+++ b/config/metrics/counts_all/20210510203143_in_product_marketing_email_team_0_cta_clicked.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510203153_in_product_marketing_email_team_1_sent.yml b/config/metrics/counts_all/20210510203153_in_product_marketing_email_team_1_sent.yml
index b860b08e391..79c2b1362c0 100644
--- a/config/metrics/counts_all/20210510203153_in_product_marketing_email_team_1_sent.yml
+++ b/config/metrics/counts_all/20210510203153_in_product_marketing_email_team_1_sent.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510203203_in_product_marketing_email_team_1_cta_clicked.yml b/config/metrics/counts_all/20210510203203_in_product_marketing_email_team_1_cta_clicked.yml
index c0f63cadbf2..b4e08bd5d90 100644
--- a/config/metrics/counts_all/20210510203203_in_product_marketing_email_team_1_cta_clicked.yml
+++ b/config/metrics/counts_all/20210510203203_in_product_marketing_email_team_1_cta_clicked.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510203213_in_product_marketing_email_team_2_sent.yml b/config/metrics/counts_all/20210510203213_in_product_marketing_email_team_2_sent.yml
index 887334c65c7..175c7171dba 100644
--- a/config/metrics/counts_all/20210510203213_in_product_marketing_email_team_2_sent.yml
+++ b/config/metrics/counts_all/20210510203213_in_product_marketing_email_team_2_sent.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210510203223_in_product_marketing_email_team_2_cta_clicked.yml b/config/metrics/counts_all/20210510203223_in_product_marketing_email_team_2_cta_clicked.yml
index 6dac2db454a..d6ec214b836 100644
--- a/config/metrics/counts_all/20210510203223_in_product_marketing_email_team_2_cta_clicked.yml
+++ b/config/metrics/counts_all/20210510203223_in_product_marketing_email_team_2_cta_clicked.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56752
time_frame: all
diff --git a/config/metrics/counts_all/20210518081225_in_product_marketing_email_experience_0_sent.yml b/config/metrics/counts_all/20210518081225_in_product_marketing_email_experience_0_sent.yml
index 816fee89f4c..f8a2b99b87e 100644
--- a/config/metrics/counts_all/20210518081225_in_product_marketing_email_experience_0_sent.yml
+++ b/config/metrics/counts_all/20210518081225_in_product_marketing_email_experience_0_sent.yml
@@ -7,7 +7,7 @@ product_stage: growth
product_group: group::activation
product_category: onboarding
value_type: number
-status: implemented
+status: data_available
milestone: "13.12"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61347
time_frame: all
diff --git a/config/metrics/schema.json b/config/metrics/schema.json
index 300a56a0b94..476e292e5c0 100644
--- a/config/metrics/schema.json
+++ b/config/metrics/schema.json
@@ -57,6 +57,10 @@
"type": "string",
"enum": ["database", "redis", "redis_hll", "prometheus", "system", "license"]
},
+ "data_category": {
+ "type": "string",
+ "enum": ["Operational", "Optional", "Subscription", "Standard"]
+ },
"instrumentation_class": {
"type": "string",
"pattern": "^(([A-Z][a-z]+)+::)*(([A-Z]+[a-z]+)+)$"
diff --git a/danger/commit_messages/Dangerfile b/danger/commit_messages/Dangerfile
deleted file mode 100644
index ac3d41adcf4..00000000000
--- a/danger/commit_messages/Dangerfile
+++ /dev/null
@@ -1,147 +0,0 @@
-# frozen_string_literal: true
-
-require 'gitlab/dangerfiles/commit_linter'
-require 'gitlab/dangerfiles/merge_request_linter'
-
-COMMIT_MESSAGE_GUIDELINES = "https://docs.gitlab.com/ee/development/contributing/merge_request_workflow.html#commit-messages-guidelines"
-MORE_INFO = "For more information, take a look at our [Commit message guidelines](#{COMMIT_MESSAGE_GUIDELINES})."
-THE_DANGER_JOB_TEXT = "the `danger-review` job"
-MAX_COMMITS_COUNT = 10
-MAX_COMMITS_COUNT_EXCEEDED_MESSAGE = <<~MSG
-This merge request includes more than %<max_commits_count>d commits. Each commit should meet the following criteria:
-
-1. Have a well-written commit message.
-1. Has all tests passing when used on its own (e.g. when using git checkout SHA).
-1. Can be reverted on its own without also requiring the revert of commit that came before it.
-1. Is small enough that it can be reviewed in isolation in under 30 minutes or so.
-
-If this merge request contains commits that do not meet this criteria and/or contains intermediate work, please rebase these commits into a smaller number of commits or split this merge request into multiple smaller merge requests.
-MSG
-
-def fail_commit(commit, message, more_info: true)
- self.fail(build_message(commit, message, more_info: more_info))
-end
-
-def warn_commit(commit, message, more_info: true)
- self.warn(build_message(commit, message, more_info: more_info))
-end
-
-def build_message(commit, message, more_info: true)
- [message].tap do |full_message|
- full_message << ". #{MORE_INFO}" if more_info
- full_message.unshift("#{commit.sha}: ") if commit.sha
- end.join
-end
-
-def squash_mr?
- # Locally, we assume the MR is set to be squashed so that the user only sees warnings instead of errors.
- helper.ci? ? gitlab.mr_json['squash'] : true
-end
-
-def wip_mr?
- helper.ci? ? gitlab.mr_json['work_in_progress'] : false
-end
-
-def danger_job_link
- helper.ci? ? "[#{THE_DANGER_JOB_TEXT}](#{ENV['CI_JOB_URL']})" : THE_DANGER_JOB_TEXT
-end
-
-# Perform various checks against commits. We're not using
-# https://github.com/jonallured/danger-commit_lint because its output is not
-# very helpful, and it doesn't offer the means of ignoring merge commits.
-def lint_commit(commit)
- linter = Gitlab::Dangerfiles::CommitLinter.new(commit)
-
- # For now we'll ignore merge commits, as getting rid of those is a problem
- # separate from enforcing good commit messages.
- return linter if linter.merge?
-
- # We ignore revert commits as they are well structured by Git already
- return linter if linter.revert?
-
- # If MR is set to squash, we ignore fixup commits
- return linter if linter.fixup? && squash_mr?
-
- if linter.fixup?
- msg = "Squash or fixup commits must be squashed before merge, or enable squash merge option and re-run #{danger_job_link}."
- if wip_mr? || squash_mr?
- warn_commit(commit, msg, more_info: false)
- else
- fail_commit(commit, msg, more_info: false)
- end
-
- # Makes no sense to process other rules for fixup commits, they trigger just more noise
- return linter
- end
-
- # Fail if a suggestion commit is used and squash is not enabled
- if linter.suggestion?
- unless squash_mr?
- fail_commit(commit, "If you are applying suggestions, enable squash in the merge request and re-run #{danger_job_link}.", more_info: false)
- end
-
- return linter
- end
-
- linter.lint
-end
-
-def lint_mr_title(mr_title)
- commit = Struct.new(:message, :sha).new(mr_title)
-
- Gitlab::Dangerfiles::MergeRequestLinter.new(commit).lint
-end
-
-def count_non_fixup_commits(commit_linters)
- commit_linters.count { |commit_linter| !commit_linter.fixup? }
-end
-
-def lint_commits(commits)
- commit_linters = commits.map { |commit| lint_commit(commit) }
-
- if squash_mr?
- multi_line_commit_linter = commit_linters.detect { |commit_linter| !commit_linter.merge? && commit_linter.multi_line? }
-
- if multi_line_commit_linter && multi_line_commit_linter.failed?
- warn_or_fail_commits(multi_line_commit_linter)
- commit_linters.delete(multi_line_commit_linter) # Don't show an error (here) and a warning (below)
- elsif helper.ci? # We don't have access to the MR title locally
- title_linter = lint_mr_title(gitlab.mr_json['title'])
- if title_linter.failed?
- warn_or_fail_commits(title_linter)
- end
- end
- else
- if count_non_fixup_commits(commit_linters) > MAX_COMMITS_COUNT
- self.warn(format(MAX_COMMITS_COUNT_EXCEEDED_MESSAGE, max_commits_count: MAX_COMMITS_COUNT))
- end
- end
-
- failed_commit_linters = commit_linters.select { |commit_linter| commit_linter.failed? }
- warn_or_fail_commits(failed_commit_linters, default_to_fail: !squash_mr?)
-end
-
-def warn_or_fail_commits(failed_linters, default_to_fail: true)
- level = default_to_fail ? :fail : :warn
-
- Array(failed_linters).each do |linter|
- linter.problems.each do |problem_key, problem_desc|
- case problem_key
- when :subject_too_short, :subject_above_warning, :details_too_many_changes, :details_line_too_long
- warn_commit(linter.commit, problem_desc)
- else
- self.__send__("#{level}_commit", linter.commit, problem_desc) # rubocop:disable GitlabSecurity/PublicSend
- end
- end
- end
-end
-
-# As part of https://gitlab.com/groups/gitlab-org/-/epics/4826 we are
-# vendoring workhorse commits from the stand-alone gitlab-workhorse
-# repo. There is no point in linting commits that we want to vendor as
-# is.
-def workhorse_changes?
- git.diff.any? { |file| file.path.start_with?('workhorse/') }
-end
-
-lint_commits(git.commits) unless workhorse_changes?
diff --git a/doc/api/deployments.md b/doc/api/deployments.md
index b7aa7e12e16..586f3edf51e 100644
--- a/doc/api/deployments.md
+++ b/doc/api/deployments.md
@@ -9,6 +9,9 @@ type: concepts, howto
## List project deployments
+> The `updated_after` and `updated_before` attributes were removed and replaced
+ by `finished_after` and `finished_before` respectively in GitLab 14.0.
+
Get a list of deployments in a project.
```plaintext
@@ -17,27 +20,19 @@ GET /projects/:id/deployments
| Attribute | Type | Required | Description |
|------------------|----------------|----------|-----------------------------------------------------------------------------------------------------------------|
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
-| `order_by` | string | no | Return deployments ordered by `id` or `iid` or `created_at` or `updated_at` or `ref` fields. Default is `id` |
-| `sort` | string | no | Return deployments sorted in `asc` or `desc` order. Default is `asc` |
-| `updated_after` | datetime | no | Return deployments updated after the specified date. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
-| `updated_before` | datetime | no | Return deployments updated before the specified date. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
-| `environment` | string | no | The [name of the environment](../ci/environments/index.md) to filter deployments by |
-| `status` | string | no | The status to filter deployments by |
-
-The status attribute can be one of the following values:
-
-- created
-- running
-- success
-- failed
-- canceled
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user. |
+| `order_by` | string | no | Return deployments ordered by either one of `id`, `iid`, `created_at`, `updated_at` or `ref` fields. Default is `id`. |
+| `sort` | string | no | Return deployments sorted in `asc` or `desc` order. Default is `asc`. |
+| `finished_after` | datetime | no | Return deployments updated after the specified date. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). |
+| `finished_before` | datetime | no | Return deployments updated before the specified date. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). |
+| `environment` | string | no | The [name of the environment](../ci/environments/index.md) to filter deployments by. |
+| `status` | string | no | The status to filter deployments by. One of `created`, `running`, `success`, `failed`, `canceled`.
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/deployments"
```
-Example of response
+Example response:
```json
[
@@ -51,16 +46,16 @@ Example of response
"author_name": "Administrator",
"created_at": "2016-08-11T09:36:01.000+02:00",
"id": "99d03678b90d914dbb1b109132516d71a4a03ea8",
- "message": "Merge branch 'new-title' into 'master'\r\n\r\nUpdate README\r\n\r\n\r\n\r\nSee merge request !1",
+ "message": "Merge branch 'new-title' into 'main'\r\n\r\nUpdate README\r\n\r\n\r\n\r\nSee merge request !1",
"short_id": "99d03678",
- "title": "Merge branch 'new-title' into 'master'\r"
+ "title": "Merge branch 'new-title' into 'main'\r"
},
"coverage": null,
"created_at": "2016-08-11T07:36:27.357Z",
"finished_at": "2016-08-11T07:36:39.851Z",
"id": 657,
"name": "deploy",
- "ref": "master",
+ "ref": "main",
"runner": null,
"stage": "deploy",
"started_at": null,
@@ -86,7 +81,7 @@ Example of response
"pipeline": {
"created_at": "2016-08-11T02:12:10.222Z",
"id": 36,
- "ref": "master",
+ "ref": "main",
"sha": "99d03678b90d914dbb1b109132516d71a4a03ea8",
"status": "success",
"updated_at": "2016-08-11T02:12:10.222Z",
@@ -100,7 +95,7 @@ Example of response
},
"id": 41,
"iid": 1,
- "ref": "master",
+ "ref": "main",
"sha": "99d03678b90d914dbb1b109132516d71a4a03ea8",
"user": {
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
@@ -121,16 +116,16 @@ Example of response
"author_name": "Administrator",
"created_at": "2016-08-11T13:28:26.000+02:00",
"id": "a91957a858320c0e17f3a0eca7cfacbff50ea29a",
- "message": "Merge branch 'rename-readme' into 'master'\r\n\r\nRename README\r\n\r\n\r\n\r\nSee merge request !2",
+ "message": "Merge branch 'rename-readme' into 'main'\r\n\r\nRename README\r\n\r\n\r\n\r\nSee merge request !2",
"short_id": "a91957a8",
- "title": "Merge branch 'rename-readme' into 'master'\r"
+ "title": "Merge branch 'rename-readme' into 'main'\r"
},
"coverage": null,
"created_at": "2016-08-11T11:32:24.456Z",
"finished_at": "2016-08-11T11:32:35.145Z",
"id": 664,
"name": "deploy",
- "ref": "master",
+ "ref": "main",
"runner": null,
"stage": "deploy",
"started_at": null,
@@ -156,7 +151,7 @@ Example of response
"pipeline": {
"created_at": "2016-08-11T07:43:52.143Z",
"id": 37,
- "ref": "master",
+ "ref": "main",
"sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a",
"status": "success",
"updated_at": "2016-08-11T07:43:52.143Z",
@@ -170,7 +165,7 @@ Example of response
},
"id": 42,
"iid": 2,
- "ref": "master",
+ "ref": "main",
"sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a",
"user": {
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
@@ -199,13 +194,13 @@ GET /projects/:id/deployments/:deployment_id
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/deployments/1"
```
-Example of response
+Example response:
```json
{
"id": 42,
"iid": 2,
- "ref": "master",
+ "ref": "main",
"sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a",
"created_at": "2016-08-11T11:32:35.444Z",
"updated_at": "2016-08-11T11:34:01.123Z",
@@ -227,7 +222,7 @@ Example of response
"status": "success",
"stage": "deploy",
"name": "deploy",
- "ref": "master",
+ "ref": "main",
"tag": false,
"coverage": null,
"created_at": "2016-08-11T11:32:24.456Z",
@@ -252,16 +247,16 @@ Example of response
"commit": {
"id": "a91957a858320c0e17f3a0eca7cfacbff50ea29a",
"short_id": "a91957a8",
- "title": "Merge branch 'rename-readme' into 'master'\r",
+ "title": "Merge branch 'rename-readme' into 'main'\r",
"author_name": "Administrator",
"author_email": "admin@example.com",
"created_at": "2016-08-11T13:28:26.000+02:00",
- "message": "Merge branch 'rename-readme' into 'master'\r\n\r\nRename README\r\n\r\n\r\n\r\nSee merge request !2"
+ "message": "Merge branch 'rename-readme' into 'main'\r\n\r\nRename README\r\n\r\n\r\n\r\nSee merge request !2"
},
"pipeline": {
"created_at": "2016-08-11T07:43:52.143Z",
"id": 42,
- "ref": "master",
+ "ref": "main",
"sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a",
"status": "success",
"updated_at": "2016-08-11T07:43:52.143Z",
@@ -280,33 +275,25 @@ POST /projects/:id/deployments
| Attribute | Type | Required | Description |
|---------------|----------------|----------|-----------------------------------------------------------------------------------------------------------------|
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
-| `environment` | string | yes | The [name of the environment](../ci/environments/index.md) to create the deployment for |
-| `sha` | string | yes | The SHA of the commit that is deployed |
-| `ref` | string | yes | The name of the branch or tag that is deployed |
-| `tag` | boolean | yes | A boolean that indicates if the deployed ref is a tag (true) or not (false) |
-| `status` | string | yes | The status of the deployment |
-
-The status can be one of the following values:
-
-- created
-- running
-- success
-- failed
-- canceled
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user.|
+| `environment` | string | yes | The [name of the environment](../ci/environments/index.md) to create the deployment for. |
+| `sha` | string | yes | The SHA of the commit that is deployed. |
+| `ref` | string | yes | The name of the branch or tag that is deployed. |
+| `tag` | boolean | yes | A boolean that indicates if the deployed ref is a tag (`true`) or not (`false`). |
+| `status` | string | no | The status to filter deployments by. One of `created`, `running`, `success`, `failed`, or `canceled`. |
```shell
-curl --data "environment=production&sha=a91957a858320c0e17f3a0eca7cfacbff50ea29a&ref=master&tag=false&status=success" \
+curl --data "environment=production&sha=a91957a858320c0e17f3a0eca7cfacbff50ea29a&ref=main&tag=false&status=success" \
--header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/deployments"
```
-Example of a response:
+Example response:
```json
{
"id": 42,
"iid": 2,
- "ref": "master",
+ "ref": "main",
"sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a",
"created_at": "2016-08-11T11:32:35.444Z",
"status": "success",
@@ -327,7 +314,7 @@ Example of a response:
}
```
-## Updating a deployment
+## Update a deployment
```plaintext
PUT /projects/:id/deployments/:deployment_id
@@ -335,21 +322,21 @@ PUT /projects/:id/deployments/:deployment_id
| Attribute | Type | Required | Description |
|------------------|----------------|----------|---------------------|
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
-| `deployment_id` | integer | yes | The ID of the deployment to update |
-| `status` | string | yes | The new status of the deployment |
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user. |
+| `deployment_id` | integer | yes | The ID of the deployment to update. |
+| `status` | string | no | The new status of the deployment. One of `created`, `running`, `success`, `failed`, or `canceled`. |
```shell
curl --request PUT --data "status=success" --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/deployments/42"
```
-Example of a response:
+Example response:
```json
{
"id": 42,
"iid": 2,
- "ref": "master",
+ "ref": "main",
"sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a",
"created_at": "2016-08-11T11:32:35.444Z",
"status": "success",
@@ -383,5 +370,5 @@ GET /projects/:id/deployments/:deployment_id/merge_requests
It supports the same parameters as the [Merge Requests API](merge_requests.md#list-merge-requests) and returns a response using the same format:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/deployments/42"
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/deployments/42/merge_requests"
```
diff --git a/doc/api/feature_flag_specs.md b/doc/api/feature_flag_specs.md
index 45db47f5ffe..33e454d50c4 100644
--- a/doc/api/feature_flag_specs.md
+++ b/doc/api/feature_flag_specs.md
@@ -8,293 +8,5 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9566) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.5.
-WARNING:
-This API is deprecated and [scheduled for removal in GitLab 14.0](https://gitlab.com/gitlab-org/gitlab/-/issues/213369).
-
-The API for creating, updating, reading and deleting Feature Flag Specs.
-Automation engineers benefit from this API by being able to modify Feature Flag Specs without accessing user interface.
-To manage the [Feature Flag](../operations/feature_flags.md) resources via public API, please refer to the [Feature Flags API](feature_flags.md) document.
-
-Users with Developer or higher [permissions](../user/permissions.md) can access Feature Flag Specs API.
-
-## List all effective feature flag specs under the specified environment
-
-Get all effective feature flag specs under the specified [environment](../ci/environments/index.md).
-
-For instance, there are two specs, `staging` and `production`, for a feature flag.
-When you pass `production` as a parameter to this endpoint, the system returns
-the `production` feature flag spec only.
-
-```plaintext
-GET /projects/:id/feature_flag_scopes
-```
-
-| Attribute | Type | Required | Description |
-| ------------------- | ---------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------- |
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding). |
-| `environment` | string | yes | The [environment](../ci/environments/index.md) name |
-
-```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/feature_flag_scopes?environment=production"
-```
-
-Example response:
-
-```json
-[
- {
- "id": 88,
- "active": true,
- "environment_scope": "production",
- "strategies": [
- {
- "name": "userWithId",
- "parameters": {
- "userIds": "1,2,3"
- }
- }
- ],
- "created_at": "2019-11-04T08:36:41.327Z",
- "updated_at": "2019-11-04T08:36:41.327Z",
- "name": "awesome_feature"
- },
- {
- "id": 82,
- "active": true,
- "environment_scope": "*",
- "strategies": [
- {
- "name": "default",
- "parameters": {}
- }
- ],
- "created_at": "2019-11-04T08:13:51.425Z",
- "updated_at": "2019-11-04T08:39:45.751Z",
- "name": "merge_train"
- },
- {
- "id": 81,
- "active": false,
- "environment_scope": "production",
- "strategies": [
- {
- "name": "default",
- "parameters": {}
- }
- ],
- "created_at": "2019-11-04T08:13:10.527Z",
- "updated_at": "2019-11-04T08:13:10.527Z",
- "name": "new_live_trace"
- }
-]
-```
-
-## List all specs of a feature flag
-
-Get all specs of a feature flag.
-
-```plaintext
-GET /projects/:id/feature_flags/:name/scopes
-```
-
-| Attribute | Type | Required | Description |
-| ------------------- | ---------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------- |
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding). |
-| `name` | string | yes | The name of the feature flag. |
-
-```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/feature_flags/new_live_trace/scopes"
-```
-
-Example response:
-
-```json
-[
- {
- "id": 79,
- "active": false,
- "environment_scope": "*",
- "strategies": [
- {
- "name": "default",
- "parameters": {}
- }
- ],
- "created_at": "2019-11-04T08:13:10.516Z",
- "updated_at": "2019-11-04T08:13:10.516Z"
- },
- {
- "id": 80,
- "active": true,
- "environment_scope": "staging",
- "strategies": [
- {
- "name": "default",
- "parameters": {}
- }
- ],
- "created_at": "2019-11-04T08:13:10.525Z",
- "updated_at": "2019-11-04T08:13:10.525Z"
- },
- {
- "id": 81,
- "active": false,
- "environment_scope": "production",
- "strategies": [
- {
- "name": "default",
- "parameters": {}
- }
- ],
- "created_at": "2019-11-04T08:13:10.527Z",
- "updated_at": "2019-11-04T08:13:10.527Z"
- }
-]
-```
-
-## New feature flag spec
-
-Creates a new feature flag spec.
-
-```plaintext
-POST /projects/:id/feature_flags/:name/scopes
-```
-
-| Attribute | Type | Required | Description |
-| ------------------- | ---------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------- |
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding). |
-| `name` | string | yes | The name of the feature flag. |
-| `environment_scope` | string | yes | The [environment spec](../ci/environments/index.md#scoping-environments-with-specs) of the feature flag. |
-| `active` | boolean | yes | Whether the spec is active. |
-| `strategies` | JSON | yes | The [strategies](../operations/feature_flags.md#feature-flag-strategies) of the feature flag spec. |
-
-```shell
-curl "https://gitlab.example.com/api/v4/projects/1/feature_flags/new_live_trace/scopes" \
- --header "PRIVATE-TOKEN: <your_access_token>" \
- --header "Content-type: application/json" \
- --data @- << EOF
-{
- "environment_scope": "*",
- "active": false,
- "strategies": [{ "name": "default", "parameters": {} }]
-}
-EOF
-```
-
-Example response:
-
-```json
-{
- "id": 81,
- "active": false,
- "environment_scope": "*",
- "strategies": [
- {
- "name": "default",
- "parameters": {}
- }
- ],
- "created_at": "2019-11-04T08:13:10.527Z",
- "updated_at": "2019-11-04T08:13:10.527Z"
-}
-```
-
-## Single feature flag spec
-
-Gets a single feature flag spec.
-
-```plaintext
-GET /projects/:id/feature_flags/:name/scopes/:environment_scope
-```
-
-| Attribute | Type | Required | Description |
-| ------------------- | ---------------- | ---------- | ---------------------------------------------------------------------------------------|
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding). |
-| `name` | string | yes | The name of the feature flag. |
-| `environment_scope` | string | yes | The URL-encoded [environment spec](../ci/environments/index.md#scoping-environments-with-specs) of the feature flag. |
-
-```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/:id/feature_flags/new_live_trace/scopes/production"
-```
-
-Example response:
-
-```json
-{
- "id": 81,
- "active": false,
- "environment_scope": "production",
- "strategies": [
- {
- "name": "default",
- "parameters": {}
- }
- ],
- "created_at": "2019-11-04T08:13:10.527Z",
- "updated_at": "2019-11-04T08:13:10.527Z"
-}
-```
-
-## Edit feature flag spec
-
-Updates an existing feature flag spec.
-
-```plaintext
-PUT /projects/:id/feature_flags/:name/scopes/:environment_scope
-```
-
-| Attribute | Type | Required | Description |
-| ------------------- | ---------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------- |
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding). |
-| `name` | string | yes | The name of the feature flag. |
-| `environment_scope` | string | yes | The URL-encoded [environment spec](../ci/environments/index.md#scoping-environments-with-specs) of the feature flag. |
-| `active` | boolean | yes | Whether the spec is active. |
-| `strategies` | JSON | yes | The [strategies](../operations/feature_flags.md#feature-flag-strategies) of the feature flag spec. |
-
-```shell
-curl "https://gitlab.example.com/api/v4/projects/1/feature_flags/new_live_trace/scopes/production" \
- --header "PRIVATE-TOKEN: <your_access_token>" \
- --header "Content-type: application/json" \
- --data @- << EOF
-{
- "active": true,
- "strategies": [{ "name": "userWithId", "parameters": { "userIds": "1,2,3" } }]
-}
-EOF
-```
-
-Example response:
-
-```json
-{
- "id": 81,
- "active": true,
- "environment_scope": "production",
- "strategies": [
- {
- "name": "userWithId",
- "parameters": { "userIds": "1,2,3" }
- }
- ],
- "created_at": "2019-11-04T08:13:10.527Z",
- "updated_at": "2019-11-04T08:13:10.527Z"
-}
-```
-
-## Delete feature flag spec
-
-Deletes a feature flag spec.
-
-```plaintext
-DELETE /projects/:id/feature_flags/:name/scopes/:environment_scope
-```
-
-| Attribute | Type | Required | Description |
-| ------------------- | ---------------- | ---------- | ---------------------------------------------------------------------------------------|
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding). |
-| `name` | string | yes | The name of the feature flag. |
-| `environment_scope` | string | yes | The URL-encoded [environment spec](../ci/environments/index.md#scoping-environments-with-specs) of the feature flag. |
-
-```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" --request DELETE "https://gitlab.example.com/api/v4/projects/1/feature_flags/new_live_trace/scopes/production"
-```
+This API was removed in [GitLab 14.0](https://gitlab.com/gitlab-org/gitlab/-/issues/213369).
+Please use [the new API](feature_flags.md) instead.
diff --git a/doc/api/feature_flags_legacy.md b/doc/api/feature_flags_legacy.md
index 6e0763b6015..262e1c537a4 100644
--- a/doc/api/feature_flags_legacy.md
+++ b/doc/api/feature_flags_legacy.md
@@ -9,315 +9,5 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9566) in GitLab Premium 12.5.
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212318) to GitLab Free in 13.5.
-WARNING:
-This API is deprecated and [scheduled for removal in GitLab 14.0](https://gitlab.com/gitlab-org/gitlab/-/issues/213369). Use [this API](feature_flags.md) instead.
-
-API for accessing resources of [GitLab Feature Flags](../operations/feature_flags.md).
-
-Users with Developer or higher [permissions](../user/permissions.md) can access Feature Flag API.
-
-## Feature Flags pagination
-
-By default, `GET` requests return 20 results at a time because the API results
-are [paginated](README.md#pagination).
-
-## List feature flags for a project
-
-Gets all feature flags of the requested project.
-
-```plaintext
-GET /projects/:id/feature_flags
-```
-
-| Attribute | Type | Required | Description |
-| ------------------- | ---------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------- |
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding). |
-| `scope` | string | no | The condition of feature flags, one of: `enabled`, `disabled`. |
-
-```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/feature_flags"
-```
-
-Example response:
-
-```json
-[
- {
- "name":"merge_train",
- "description":"This feature is about merge train",
- "active": true,
- "created_at":"2019-11-04T08:13:51.423Z",
- "updated_at":"2019-11-04T08:13:51.423Z",
- "scopes":[
- {
- "id":82,
- "active":false,
- "environment_scope":"*",
- "strategies":[
- {
- "name":"default",
- "parameters":{
-
- }
- }
- ],
- "created_at":"2019-11-04T08:13:51.425Z",
- "updated_at":"2019-11-04T08:13:51.425Z"
- },
- {
- "id":83,
- "active":true,
- "environment_scope":"review/*",
- "strategies":[
- {
- "name":"default",
- "parameters":{
-
- }
- }
- ],
- "created_at":"2019-11-04T08:13:51.427Z",
- "updated_at":"2019-11-04T08:13:51.427Z"
- },
- {
- "id":84,
- "active":false,
- "environment_scope":"production",
- "strategies":[
- {
- "name":"default",
- "parameters":{
-
- }
- }
- ],
- "created_at":"2019-11-04T08:13:51.428Z",
- "updated_at":"2019-11-04T08:13:51.428Z"
- }
- ]
- },
- {
- "name":"new_live_trace",
- "description":"This is a new live trace feature",
- "active": true,
- "created_at":"2019-11-04T08:13:10.507Z",
- "updated_at":"2019-11-04T08:13:10.507Z",
- "scopes":[
- {
- "id":79,
- "active":false,
- "environment_scope":"*",
- "strategies":[
- {
- "name":"default",
- "parameters":{
-
- }
- }
- ],
- "created_at":"2019-11-04T08:13:10.516Z",
- "updated_at":"2019-11-04T08:13:10.516Z"
- },
- {
- "id":80,
- "active":true,
- "environment_scope":"staging",
- "strategies":[
- {
- "name":"default",
- "parameters":{
-
- }
- }
- ],
- "created_at":"2019-11-04T08:13:10.525Z",
- "updated_at":"2019-11-04T08:13:10.525Z"
- },
- {
- "id":81,
- "active":false,
- "environment_scope":"production",
- "strategies":[
- {
- "name":"default",
- "parameters":{
-
- }
- }
- ],
- "created_at":"2019-11-04T08:13:10.527Z",
- "updated_at":"2019-11-04T08:13:10.527Z"
- }
- ]
- }
-]
-```
-
-## New feature flag
-
-Creates a new feature flag.
-
-```plaintext
-POST /projects/:id/feature_flags
-```
-
-| Attribute | Type | Required | Description |
-| ------------------- | ---------------- | ---------- | ---------------------------------------------------------------------------------------|
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding). |
-| `name` | string | yes | The name of the feature flag. |
-| `description` | string | no | The description of the feature flag. |
-| `active` | boolean | no | The active state of the flag. Defaults to true. [Supported](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38350) in GitLab 13.3 and later. |
-| `scopes` | JSON | no | The feature flag specs of the feature flag. |
-| `scopes:environment_scope` | string | no | The environment spec. |
-| `scopes:active` | boolean | no | Whether the spec is active. |
-| `scopes:strategies` | JSON | no | The [strategies](../operations/feature_flags.md#feature-flag-strategies) of the feature flag spec. |
-
-```shell
-curl "https://gitlab.example.com/api/v4/projects/1/feature_flags" \
- --header "PRIVATE-TOKEN: <your_access_token>" \
- --header "Content-type: application/json" \
- --data @- << EOF
-{
- "name": "awesome_feature",
- "scopes": [{ "environment_scope": "*", "active": false, "strategies": [{ "name": "default", "parameters": {} }] },
- { "environment_scope": "production", "active": true, "strategies": [{ "name": "userWithId", "parameters": { "userIds": "1,2,3" } }] }]
-}
-EOF
-```
-
-Example response:
-
-```json
-{
- "name":"awesome_feature",
- "description":null,
- "active": true,
- "created_at":"2019-11-04T08:32:27.288Z",
- "updated_at":"2019-11-04T08:32:27.288Z",
- "scopes":[
- {
- "id":85,
- "active":false,
- "environment_scope":"*",
- "strategies":[
- {
- "name":"default",
- "parameters":{
-
- }
- }
- ],
- "created_at":"2019-11-04T08:32:29.324Z",
- "updated_at":"2019-11-04T08:32:29.324Z"
- },
- {
- "id":86,
- "active":true,
- "environment_scope":"production",
- "strategies":[
- {
- "name":"userWithId",
- "parameters":{
- "userIds":"1,2,3"
- }
- }
- ],
- "created_at":"2019-11-04T08:32:29.328Z",
- "updated_at":"2019-11-04T08:32:29.328Z"
- }
- ]
-}
-```
-
-## Single feature flag
-
-Gets a single feature flag.
-
-```plaintext
-GET /projects/:id/feature_flags/:name
-```
-
-| Attribute | Type | Required | Description |
-| ------------------- | ---------------- | ---------- | ---------------------------------------------------------------------------------------|
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding). |
-| `name` | string | yes | The name of the feature flag. |
-
-```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/feature_flags/new_live_trace"
-```
-
-Example response:
-
-```json
-{
- "name":"new_live_trace",
- "description":"This is a new live trace feature",
- "active": true,
- "created_at":"2019-11-04T08:13:10.507Z",
- "updated_at":"2019-11-04T08:13:10.507Z",
- "scopes":[
- {
- "id":79,
- "active":false,
- "environment_scope":"*",
- "strategies":[
- {
- "name":"default",
- "parameters":{
-
- }
- }
- ],
- "created_at":"2019-11-04T08:13:10.516Z",
- "updated_at":"2019-11-04T08:13:10.516Z"
- },
- {
- "id":80,
- "active":true,
- "environment_scope":"staging",
- "strategies":[
- {
- "name":"default",
- "parameters":{
-
- }
- }
- ],
- "created_at":"2019-11-04T08:13:10.525Z",
- "updated_at":"2019-11-04T08:13:10.525Z"
- },
- {
- "id":81,
- "active":false,
- "environment_scope":"production",
- "strategies":[
- {
- "name":"default",
- "parameters":{
-
- }
- }
- ],
- "created_at":"2019-11-04T08:13:10.527Z",
- "updated_at":"2019-11-04T08:13:10.527Z"
- }
- ]
-}
-```
-
-## Delete feature flag
-
-Deletes a feature flag.
-
-```plaintext
-DELETE /projects/:id/feature_flags/:name
-```
-
-| Attribute | Type | Required | Description |
-| ------------------- | ---------------- | ---------- | ---------------------------------------------------------------------------------------|
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding). |
-| `name` | string | yes | The name of the feature flag. |
-
-```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" --request DELETE "https://gitlab.example.com/api/v4/projects/1/feature_flags/awesome_feature"
-```
+This API was removed in [GitLab 14.0](https://gitlab.com/gitlab-org/gitlab/-/issues/213369).
+Please use [the new API](feature_flags.md) instead.
diff --git a/doc/api/resource_access_tokens.md b/doc/api/resource_access_tokens.md
index 2d458cbe2ad..3b443dbb8f8 100644
--- a/doc/api/resource_access_tokens.md
+++ b/doc/api/resource_access_tokens.md
@@ -10,7 +10,7 @@ You can read more about [project access tokens](../user/project/settings/project
## List project access tokens
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/238991) in GitLab 13.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/238991) in GitLab 13.9.
Get a list of project access tokens.
@@ -45,7 +45,7 @@ curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/a
## Create a project access token
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/238991) in GitLab 13.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55408) in GitLab 13.10.
Create a project access token.
@@ -86,7 +86,7 @@ curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
## Revoke a project access token
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/238991) in GitLab 13.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/238991) in GitLab 13.9.
Revoke a project access token.
diff --git a/doc/api/status_checks.md b/doc/api/status_checks.md
index e4640e26a47..f4e384a2efb 100644
--- a/doc/api/status_checks.md
+++ b/doc/api/status_checks.md
@@ -195,3 +195,7 @@ Feature.disable(:ff_compliance_approval_gates)
# For a single project
Feature.disable(:ff_compliance_approval_gates, Project.find(<project id>)
```
+
+## Related links
+
+- [External status checks](../user/project/merge_requests/status_checks.md)
diff --git a/doc/development/pipelines.md b/doc/development/pipelines.md
index 437b2d04e1e..c3fb66cb085 100644
--- a/doc/development/pipelines.md
+++ b/doc/development/pipelines.md
@@ -480,7 +480,11 @@ because of 2 reasons:
### PostgreSQL versions testing
Our test suite runs against PG12 as GitLab.com runs on PG12 and
-[Omnibus defaults to PG12 for new installs and upgrades](https://docs.gitlab.com/omnibus/package-information/postgresql_versions.html).
+[Omnibus defaults to PG12 for new installs and upgrades](https://docs.gitlab.com/omnibus/package-information/postgresql_versions.html),
+Our test suite is currently running against PG11, since GitLab.com still runs on PG11.
+
+We do run our test suite against PG11 on nightly scheduled pipelines as well as upon specific
+database library changes in MRs and `master` pipelines (with the `rspec db-library-code pg11` job).
#### Current versions testing
@@ -498,6 +502,7 @@ We follow the [PostgreSQL versions shipped with Omnibus GitLab](https://docs.git
| PostgreSQL version | 13.11 (April 2021) | 13.12 (May 2021) | 14.0 (June 2021?) |
| -------------------| ---------------------- | ---------------------- | ---------------------- |
| PG12 | `nightly` | MRs/`2-hour`/`nightly` | MRs/`2-hour`/`nightly` |
+| PG11 | MRs/`2-hour`/`nightly` | `nightly` | `nightly` |
### Test jobs
@@ -726,6 +731,8 @@ that are scoped to a single [configuration keyword](../ci/yaml/README.md#job-key
| `.qa-cache` | Allows a job to use a default `cache` definition suitable for QA tasks. |
| `.yarn-cache` | Allows a job to use a default `cache` definition suitable for frontend jobs that do a `yarn install`. |
| `.assets-compile-cache` | Allows a job to use a default `cache` definition suitable for frontend jobs that compile assets. |
+| `.use-pg11` | Allows a job to run the `postgres` 11 and `redis` services (see [`.gitlab/ci/global.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/ci/global.gitlab-ci.yml) for the specific versions of the services). |
+| `.use-pg11-ee` | Same as `.use-pg11` but also use an `elasticsearch` service (see [`.gitlab/ci/global.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/ci/global.gitlab-ci.yml) for the specific version of the service). |
| `.use-pg12` | Allows a job to use the `postgres` 12 and `redis` services (see [`.gitlab/ci/global.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/ci/global.gitlab-ci.yml) for the specific versions of the services). |
| `.use-pg12-ee` | Same as `.use-pg12` but also use an `elasticsearch` service (see [`.gitlab/ci/global.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/ci/global.gitlab-ci.yml) for the specific version of the service). |
| `.use-kaniko` | Allows a job to use the `kaniko` tool to build Docker images. |
diff --git a/doc/development/usage_ping/dictionary.md b/doc/development/usage_ping/dictionary.md
index 4b31fd113e1..e76fb302b9c 100644
--- a/doc/development/usage_ping/dictionary.md
+++ b/doc/development/usage_ping/dictionary.md
@@ -162,7 +162,7 @@ Missing description
Group: ``
-Status: `implemented`
+Status: `data_available`
Tiers:
@@ -282,7 +282,7 @@ Missing description
Group: ``
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -594,7 +594,7 @@ Total active instance Runners
Group: `group::pipeline execution`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -606,7 +606,7 @@ Total active and online group Runners
Group: `group::pipeline execution`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -618,7 +618,7 @@ Total active group Runners
Group: `group::pipeline execution`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -630,7 +630,7 @@ Total active and online instance Runners
Group: `group::pipeline execution`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -642,7 +642,7 @@ Total online Runners
Group: `group::pipeline execution`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -654,7 +654,7 @@ Total active project Runners
Group: `group::pipeline execution`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -666,7 +666,7 @@ Total active and online project Runners
Group: `group::pipeline execution`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -2118,7 +2118,7 @@ Total clicks on the create track's first email
Group: `group::activation`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -2130,7 +2130,7 @@ Total sent emails of the create track's first email
Group: `group::activation`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -2142,7 +2142,7 @@ Total clicks on the create track's second email
Group: `group::activation`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -2154,7 +2154,7 @@ Total sent emails of the create track's second email
Group: `group::activation`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -2166,7 +2166,7 @@ Total clicks on the create track's third email
Group: `group::activation`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -2178,7 +2178,7 @@ Total sent emails of the create track's third email
Group: `group::activation`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -2190,7 +2190,7 @@ Total sent emails of the experience track's first email
Group: `group::activation`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -2202,7 +2202,7 @@ Total clicks on the team track's first email
Group: `group::activation`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -2214,7 +2214,7 @@ Total sent emails of the team track's first email
Group: `group::activation`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -2226,7 +2226,7 @@ Total clicks on the team track's second email
Group: `group::activation`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -2238,7 +2238,7 @@ Total sent emails of the team track's second email
Group: `group::activation`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -2250,7 +2250,7 @@ Total clicks on the team track's third email
Group: `group::activation`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -2262,7 +2262,7 @@ Total sent emails of the team track's third email
Group: `group::activation`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -2274,7 +2274,7 @@ Total clicks on the verify trial's first email
Group: `group::activation`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -2286,7 +2286,7 @@ Total sent emails of the trial track's first email
Group: `group::activation`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -2298,7 +2298,7 @@ Total clicks on the trial track's second email
Group: `group::activation`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -2310,7 +2310,7 @@ Total sent emails of the trial track's second email
Group: `group::activation`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -2322,7 +2322,7 @@ Total clicks on the trial track's third email
Group: `group::activation`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -2334,7 +2334,7 @@ Total sent emails of the trial track's third email
Group: `group::activation`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -2346,7 +2346,7 @@ Total clicks on the verify track's first email
Group: `group::activation`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -2358,7 +2358,7 @@ Total sent emails of the verify track's first email
Group: `group::activation`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -2370,7 +2370,7 @@ Total clicks on the verify track's second email
Group: `group::activation`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -2382,7 +2382,7 @@ Total sent emails of the verify track's second email
Group: `group::activation`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -2394,7 +2394,7 @@ Total clicks on the verify track's third email
Group: `group::activation`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -2406,7 +2406,7 @@ Total sent emails of the verify track's third email
Group: `group::activation`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -3186,7 +3186,7 @@ Count of Kubernetes API proxy requests
Group: `group::configure`
-Status: `implemented`
+Status: `data_available`
Tiers: `premium`, `ultimate`
@@ -6570,7 +6570,7 @@ Missing description
Group: ``
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -6582,7 +6582,7 @@ Missing description
Group: ``
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -6594,7 +6594,7 @@ Missing description
Group: ``
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -6786,7 +6786,7 @@ Missing description
Group: ``
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -6798,7 +6798,7 @@ Missing description
Group: ``
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -6810,7 +6810,7 @@ Missing description
Group: ``
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -8166,7 +8166,7 @@ Counts visits to DevOps Adoption page per month
Group: `group::optimize`
-Status: `implemented`
+Status: `data_available`
Tiers: `premium`, `ultimate`
@@ -8178,7 +8178,7 @@ Counts visits to DevOps Adoption page per week
Group: `group::optimize`
-Status: `implemented`
+Status: `data_available`
Tiers: `premium`, `ultimate`
@@ -8622,7 +8622,7 @@ Count of users clicking diff view setting
Group: `group::code review`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -8634,7 +8634,7 @@ Count of users clicking diff view setting
Group: `group::code review`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -8646,7 +8646,7 @@ Count of users clicking merge request file browser setting
Group: `group::code review`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -8658,7 +8658,7 @@ Count of users with merge request file list setting
Group: `group::code review`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -8670,7 +8670,7 @@ Count of users clicking single file mode setting
Group: `group::code review`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -8682,7 +8682,7 @@ Count of users clicking single file mode setting
Group: `group::code review`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -8694,7 +8694,7 @@ Count of users clicking merge request whitespae setting
Group: `group::code review`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -8706,7 +8706,7 @@ Count of users clicking merge request whitespae setting
Group: `group::code review`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -8718,7 +8718,7 @@ Count of users with show whitespace disabled
Group: `group::code review`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -8730,7 +8730,7 @@ Count of users with show whitespace disabled
Group: `group::code review`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -8742,7 +8742,7 @@ Count of users with single mode disabled
Group: `group::code review`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -8754,7 +8754,7 @@ Count of users with single mode disabled
Group: `group::code review`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -8766,7 +8766,7 @@ Count of users with show whitespace enabled
Group: `group::code review`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -8778,7 +8778,7 @@ Count of users with show whitespace enabled
Group: `group::code review`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -8790,7 +8790,7 @@ Count of users with single file mode enabled
Group: `group::code review`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -8802,7 +8802,7 @@ Count of users with single file mode enabled
Group: `group::code review`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -8814,7 +8814,7 @@ Count of users with merge request view type as inline
Group: `group::code review`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -8826,7 +8826,7 @@ Count of users with merge request view type as inline
Group: `group::code review`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -8838,7 +8838,7 @@ Count of users with merge request view type as parallel
Group: `group::code review`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -8850,7 +8850,7 @@ Count of users with merge request view type as parallel
Group: `group::code review`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -8910,7 +8910,7 @@ Count of users with merge request file list setting
Group: `group::code review`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -8922,7 +8922,7 @@ Count of users with merge request file list setting
Group: `group::code review`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -8934,7 +8934,7 @@ Count of users with merge request file tree setting
Group: `group::code review`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -8946,7 +8946,7 @@ Count of users with merge request file tree setting
Group: `group::code review`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -9414,7 +9414,7 @@ Count of unique users per week who load the conflict resolution page
Group: `group::code review`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -9426,7 +9426,7 @@ Count of unique users per week who load the conflict resolution page
Group: `group::code review`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -9654,7 +9654,7 @@ Count of unique users per week who attempt to resolve a conflict through the ui
Group: `group::code review`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -9666,7 +9666,7 @@ Count of unique users per week who attempt to resolve a conflict through the ui
Group: `group::code review`
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -10782,7 +10782,7 @@ Missing description
Group: ``
-Status: `implemented`
+Status: `data_available`
Tiers: `ultimate`
@@ -10794,7 +10794,7 @@ Missing description
Group: ``
-Status: `implemented`
+Status: `data_available`
Tiers: `ultimate`
@@ -10806,7 +10806,7 @@ Count of MAU creating epic boards
Group: `group::product planning`
-Status: `implemented`
+Status: `data_available`
Tiers: `premium`, `ultimate`
@@ -10818,7 +10818,7 @@ Count of WAU creating epic boards
Group: `group::product planning`
-Status: `implemented`
+Status: `data_available`
Tiers: `premium`, `ultimate`
@@ -10830,7 +10830,7 @@ Count of MAU updating epic board names
Group: `group::product planning`
-Status: `implemented`
+Status: `data_available`
Tiers: `premium`, `ultimate`
@@ -10842,7 +10842,7 @@ Count of WAU updating epic board names
Group: `group::product planning`
-Status: `implemented`
+Status: `data_available`
Tiers: `premium`, `ultimate`
@@ -10854,7 +10854,7 @@ Count of MAU viewing epic boards
Group: `group::product planning`
-Status: `implemented`
+Status: `data_available`
Tiers: `premium`, `ultimate`
@@ -10866,7 +10866,7 @@ Count of WAU viewing epic boards
Group: `group::product planning`
-Status: `implemented`
+Status: `data_available`
Tiers: `premium`, `ultimate`
@@ -10950,7 +10950,7 @@ Count of MAU cross referencing epics
Group: `group::product planning`
-Status: `implemented`
+Status: `data_available`
Tiers: `premium`, `ultimate`
@@ -10962,7 +10962,7 @@ Counts of WAU cross referencing epics
Group: `group::product planning`
-Status: `implemented`
+Status: `data_available`
Tiers: `premium`, `ultimate`
@@ -11142,7 +11142,7 @@ Counts of MAU awarding emoji on epic
Group: `group::product planning`
-Status: `implemented`
+Status: `data_available`
Tiers: `premium`, `ultimate`
@@ -11154,7 +11154,7 @@ Counts of WAU awarding emoji on epic
Group: `group::product planning`
-Status: `implemented`
+Status: `data_available`
Tiers: `premium`, `ultimate`
@@ -11214,7 +11214,7 @@ Number of users creating an issue from an epic
Group: `group::product planning`
-Status: `implemented`
+Status: `data_available`
Tiers: `premium`
@@ -11226,7 +11226,7 @@ Number of users creating an issue from an epic
Group: `group::product planning`
-Status: `implemented`
+Status: `data_available`
Tiers: `premium`
@@ -11238,7 +11238,7 @@ Counts of MAU removing emoji on epic
Group: `group::product planning`
-Status: `implemented`
+Status: `data_available`
Tiers: `premium`, `ultimate`
@@ -11250,7 +11250,7 @@ Counts of WAU removing emoji on epic
Group: `group::product planning`
-Status: `implemented`
+Status: `data_available`
Tiers: `premium`, `ultimate`
@@ -11454,7 +11454,7 @@ Counts of MAU updating parent on epic
Group: `group::product planning`
-Status: `implemented`
+Status: `data_available`
Tiers: `premium`, `ultimate`
@@ -11466,7 +11466,7 @@ Counts of WAU updating parent on epic
Group: `group::product planning`
-Status: `implemented`
+Status: `data_available`
Tiers: `premium`, `ultimate`
@@ -11550,7 +11550,7 @@ Counts of MAU checking epic task
Group: `group::product planning`
-Status: `implemented`
+Status: `data_available`
Tiers: `premium`, `ultimate`
@@ -11562,7 +11562,7 @@ Counts of WAU checking epic task
Group: `group::product planning`
-Status: `implemented`
+Status: `data_available`
Tiers: `premium`, `ultimate`
@@ -11574,7 +11574,7 @@ Counts of MAU unchecking epic task
Group: `group::product planning`
-Status: `implemented`
+Status: `data_available`
Tiers: `premium`, `ultimate`
@@ -11586,7 +11586,7 @@ Counts of WAU unchecking epic task
Group: `group::product planning`
-Status: `implemented`
+Status: `data_available`
Tiers: `premium`, `ultimate`
@@ -12990,7 +12990,7 @@ Missing description
Group: ``
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -13002,7 +13002,7 @@ Missing description
Group: ``
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -16304,7 +16304,7 @@ Missing description
Group: ``
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -16340,7 +16340,7 @@ Total count of all custom compliance framework labels
Group: `compliance`
-Status: `implemented`
+Status: `data_available`
Tiers: `premium`, `ultimate`
@@ -18274,7 +18274,7 @@ Missing description
Group: ``
-Status: `implemented`
+Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
@@ -18310,7 +18310,7 @@ Monthly count of all custom compliance framework labels
Group: `compliance`
-Status: `implemented`
+Status: `data_available`
Tiers: `premium`, `ultimate`
diff --git a/doc/development/usage_ping/metrics_dictionary.md b/doc/development/usage_ping/metrics_dictionary.md
index d927d1fb461..6b5fed4bcca 100644
--- a/doc/development/usage_ping/metrics_dictionary.md
+++ b/doc/development/usage_ping/metrics_dictionary.md
@@ -37,6 +37,7 @@ Each metric is defined in a separate YAML file consisting of a number of fields:
| `status` | yes | `string`; [status](#metric-statuses) of the metric, may be set to `data_available`, `implemented`, `not_used`, `deprecated`, `removed`, `broken`. |
| `time_frame` | yes | `string`; may be set to a value like `7d`, `28d`, `all`, `none`. |
| `data_source` | yes | `string`; may be set to a value like `database`, `redis`, `redis_hll`, `prometheus`, `system`. |
+| `data_category` | yes | `string`; [categories](#data-category) of the metric, may be set to `Operational`, `Optional`, `Subscription`, `Standard`. |
| `instrumentation_class` | no | `string`; [the class that implements the metric](metrics_instrumentation.md). |
| `distribution` | yes | `array`; may be set to one of `ce, ee` or `ee`. The [distribution](https://about.gitlab.com/handbook/marketing/strategic-marketing/tiers/#definitions) where the tracked feature is available. |
| `tier` | yes | `array`; may be set to one of `free, premium, ultimate`, `premium, ultimate` or `ultimate`. The [tier]( https://about.gitlab.com/handbook/marketing/strategic-marketing/tiers/) where the tracked feature is available. |
@@ -93,6 +94,15 @@ Metric name suggestions can contain two types of elements:
For a metric name to be valid, it must not include any prompt, and no fixed suggestions
should be changed.
+### Data category
+
+We use the following categories to classify a metric:
+
+- `Operational`: Required data for operational purposes.
+- `Optional`: Data that is optional to collect. This can be [enabled or disabled](../usage_ping/index.md#disable-usage-ping) in the Admin Area.
+- `Subscription`: Data related to licensing.
+- `Standard`: Standard set of identifiers that are included when collecting data.
+
### Metric name suggestion examples
#### Metric with `data_source: database`
diff --git a/doc/user/project/merge_requests/img/status_checks_branches_selector_v14_0.png b/doc/user/project/merge_requests/img/status_checks_branches_selector_v14_0.png
new file mode 100644
index 00000000000..65009faf426
--- /dev/null
+++ b/doc/user/project/merge_requests/img/status_checks_branches_selector_v14_0.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/status_checks_create_form_v14_0.png b/doc/user/project/merge_requests/img/status_checks_create_form_v14_0.png
new file mode 100644
index 00000000000..9e6d6c552e5
--- /dev/null
+++ b/doc/user/project/merge_requests/img/status_checks_create_form_v14_0.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/status_checks_delete_modal_v14_0.png b/doc/user/project/merge_requests/img/status_checks_delete_modal_v14_0.png
new file mode 100644
index 00000000000..a305f5c73f8
--- /dev/null
+++ b/doc/user/project/merge_requests/img/status_checks_delete_modal_v14_0.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/status_checks_list_view_v14_0.png b/doc/user/project/merge_requests/img/status_checks_list_view_v14_0.png
new file mode 100644
index 00000000000..6be64112ac6
--- /dev/null
+++ b/doc/user/project/merge_requests/img/status_checks_list_view_v14_0.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/status_checks_update_form_v14_0.png b/doc/user/project/merge_requests/img/status_checks_update_form_v14_0.png
new file mode 100644
index 00000000000..fcfe16bcd97
--- /dev/null
+++ b/doc/user/project/merge_requests/img/status_checks_update_form_v14_0.png
Binary files differ
diff --git a/doc/user/project/merge_requests/status_checks.md b/doc/user/project/merge_requests/status_checks.md
new file mode 100644
index 00000000000..775820870f3
--- /dev/null
+++ b/doc/user/project/merge_requests/status_checks.md
@@ -0,0 +1,179 @@
+---
+stage: Manage
+group: Compliance
+info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
+type: reference, concepts
+disqus_identifier: 'https://docs.gitlab.com/ee/user/project/merge_requests/status_checks.html'
+---
+
+# External Status Checks **(ULTIMATE)**
+
+> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3869) in GitLab 14.0.
+> - It's [deployed behind a feature flag](../../feature_flags.md), disabled by default.
+> - It's disabled on GitLab.com.
+> - It's not recommended for production use.
+> - To use it in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-status-checks). **(ULTIMATE SELF)**
+
+WARNING:
+This feature might not be available to you. Check the **version history** note above for details.
+
+You can create a status check that sends merge request data to third-party tools.
+When users create, change, or close merge requests, GitLab sends a notification. The users or automated workflows
+can then update the status of merge requests from outside of GitLab.
+
+With this integration, you can integrate with third-party workflow tools, like
+ServiceNow, or the custom tool of your choice. The third-party tool
+respond with an associated status. This status is then displayed as a non-blocking
+widget within the merge request to surface this status to the merge request author or reviewers
+at the merge request level itself.
+
+The lack of a status check response does not block the merging of a merge request.
+
+You can configure merge request status checks for each individual project. These are not shared between projects.
+
+To learn more about use cases, feature discovery, and development timelines,
+see the [external status checks epic](https://gitlab.com/groups/gitlab-org/-/epics/3869).
+
+## View the status checks on a project
+
+Within each project's settings, you can see a list of status checks added to the project:
+
+1. In your project, go to **Settings > General**.
+1. Expand the **Merge requests** section.
+1. Scroll down to the **Status checks** sub-section.
+
+![Status checks list](img/status_checks_list_view_v14_0.png)
+
+This list shows the service name, API URL, and targeted branch.
+It also provides actions to allow you to create, edit, or remove status checks.
+
+## Add or update a status check
+
+### Add a status check
+
+Within the **Status checks** sub-section, select the **Add status check** button.
+The **Add status check** form is then shown.
+
+![Status checks create form](img/status_checks_create_form_v14_0.png)
+
+Filling in the form and selecting the **Add status check** button creates a new status check.
+
+### Update a status check
+
+Within the **Status checks** sub-section, select the **Edit** button
+next to the status check you want to edit.
+The **Update status check** form is then shown.
+
+![Status checks update form](img/status_checks_update_form_v14_0.png)
+
+Changing the values in the form and selecting the **Update status check** button updates the status check.
+
+### Form values
+
+For common form errors see the [troubleshooting](#troubleshooting) section below.
+
+#### Service name
+
+This name can be any alphanumerical value and **must** be set. The name **must** be unique for
+the project.
+The name **has** to be unique for the project.
+
+#### API to check
+
+This field requires a URL and **must** use either the HTTP or HTTPs protocols.
+We **recommend** using HTTPs to protect your merge request data in transit.
+The URL **must** be set and **must** be unique for the project.
+
+#### Target branch
+
+If you want to restrict the status check to a single branch,
+you can use this field to set this limit.
+
+![Status checks branch selector](img/status_checks_branches_selector_v14_0.png)
+
+The branches list is populated from the projects [protected branches](../protected_branches.md).
+
+You can scroll through the list of branches or use the search box
+when there are a lot of branches and the branch you are looking
+for doesn't appear immediately. The search box requires
+**three** alphanumeric characters to be entered for the search to begin.
+
+If you want the status check to be applied to **all** merge requests,
+you can select the **Any branch** option.
+
+## Delete a status check
+
+Within the **Status checks** sub-section, select the **Remove...** button
+next to the status check you want to delete.
+The **Remove status check?** modal is then shown.
+
+![Status checks delete modal](img/status_checks_delete_modal_v14_0.png)
+
+To complete the deletion of the status check you must select the
+**Remove status check** button. This **permanently** deletes
+the status check and it **will not** be recoverable.
+
+## Troubleshooting
+
+### Duplicate value errors
+
+```plaintext
+Name is already taken
+---
+External API is already in use by another status check
+```
+
+On a per project basis, status checks can only use a name or API URL once.
+These errors mean that either the status checks name or API URL have already
+been used in this projects status checks.
+
+You must either choose a different
+value on the current status check or update the value on the existing status check.
+
+### Invalid URL error
+
+```plaintext
+Please provide a valid URL
+```
+
+The API to check field requires the URL provided to use either the HTTP or HTTPs protocols.
+You must update the value of the field to meet this requirement.
+
+### Branch list error during retrieval or search
+
+```plaintext
+Unable to fetch branches list, please close the form and try again
+```
+
+An unexpected response was received from the branches retrieval API.
+As suggested, you should close the form and reopen again or refresh the page. This error should be temporary, although
+if it persists please check the [GitLab status page](https://status.gitlab.com/) to see if there is a wider outage.
+
+## Enable or disable status checks **(ULTIMATE SELF)**
+
+Status checks are under development and not ready for production use. It is
+deployed behind a feature flag that is **disabled by default**.
+[GitLab administrators with access to the GitLab Rails console](../../../administration/feature_flags.md)
+can enable it.
+
+To enable it:
+
+```ruby
+# For the instance
+Feature.enable(:ff_compliance_approval_gates)
+# For a single project
+Feature.enable(:ff_compliance_approval_gates, Project.find(<project id>))
+```
+
+To disable it:
+
+```ruby
+# For the instance
+Feature.disable(:ff_compliance_approval_gates)
+# For a single project
+Feature.disable(:ff_compliance_approval_gates, Project.find(<project id>)
+```
+
+## Related links
+
+- [External status checks API](../../../api/status_checks.md)
diff --git a/doc/user/project/settings/index.md b/doc/user/project/settings/index.md
index cd9d36bf161..3ea34c35443 100644
--- a/doc/user/project/settings/index.md
+++ b/doc/user/project/settings/index.md
@@ -249,6 +249,7 @@ Set up your project's merge request settings:
- Set up the merge request method (merge commit, [fast-forward merge](../merge_requests/fast_forward_merge.md)).
- Add merge request [description templates](../description_templates.md#description-templates).
- Enable [merge request approvals](../merge_requests/approvals/index.md).
+- Enable [status checks](../merge_requests/status_checks.md).
- Enable [merge only if pipeline succeeds](../merge_requests/merge_when_pipeline_succeeds.md).
- Enable [merge only when all threads are resolved](../../discussions/index.md#only-allow-merge-requests-to-be-merged-if-all-threads-are-resolved).
- Enable [require an associated issue from Jira](../../../integration/jira/issues.md#require-associated-jira-issue-for-merge-requests-to-be-merged).
diff --git a/generator_templates/usage_metric_definition/metric_definition.yml b/generator_templates/usage_metric_definition/metric_definition.yml
index 89290a0bd89..53ff84fc4ab 100644
--- a/generator_templates/usage_metric_definition/metric_definition.yml
+++ b/generator_templates/usage_metric_definition/metric_definition.yml
@@ -11,6 +11,7 @@ milestone: "<%= milestone %>"
introduced_by_url:
time_frame: <%= time_frame %>
data_source:
+data_category: Operational
distribution:
<%= distribution %>
tier:
diff --git a/lib/api/api.rb b/lib/api/api.rb
index b551c42d004..2a3033753f7 100644
--- a/lib/api/api.rb
+++ b/lib/api/api.rb
@@ -168,7 +168,6 @@ module API
mount ::API::ErrorTracking
mount ::API::Events
mount ::API::FeatureFlags
- mount ::API::FeatureFlagScopes
mount ::API::FeatureFlagsUserLists
mount ::API::Features
mount ::API::Files
diff --git a/lib/api/feature_flag_scopes.rb b/lib/api/feature_flag_scopes.rb
deleted file mode 100644
index 3f3bf4d9f42..00000000000
--- a/lib/api/feature_flag_scopes.rb
+++ /dev/null
@@ -1,160 +0,0 @@
-# frozen_string_literal: true
-
-module API
- class FeatureFlagScopes < ::API::Base
- include PaginationParams
-
- ENVIRONMENT_SCOPE_ENDPOINT_REQUIREMENTS = FeatureFlags::FEATURE_FLAG_ENDPOINT_REQUIREMENTS
- .merge(environment_scope: API::NO_SLASH_URL_PART_REGEX)
-
- feature_category :feature_flags
-
- before do
- authorize_read_feature_flags!
- end
-
- params do
- requires :id, type: String, desc: 'The ID of a project'
- end
- resource 'projects/:id', requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
- resource :feature_flag_scopes do
- desc 'Get all effective feature flags under the environment' do
- detail 'This feature was introduced in GitLab 12.5'
- success ::API::Entities::FeatureFlag::DetailedLegacyScope
- end
- params do
- requires :environment, type: String, desc: 'The environment name'
- end
- get do
- present scopes_for_environment, with: ::API::Entities::FeatureFlag::DetailedLegacyScope
- end
- end
-
- params do
- requires :name, type: String, desc: 'The name of the feature flag'
- end
- resource 'feature_flags/:name', requirements: FeatureFlags::FEATURE_FLAG_ENDPOINT_REQUIREMENTS do
- resource :scopes do
- desc 'Get all scopes of a feature flag' do
- detail 'This feature was introduced in GitLab 12.5'
- success ::API::Entities::FeatureFlag::LegacyScope
- end
- params do
- use :pagination
- end
- get do
- present paginate(feature_flag.scopes), with: ::API::Entities::FeatureFlag::LegacyScope
- end
-
- desc 'Create a scope of a feature flag' do
- detail 'This feature was introduced in GitLab 12.5'
- success ::API::Entities::FeatureFlag::LegacyScope
- end
- params do
- requires :environment_scope, type: String, desc: 'The environment scope of the scope'
- requires :active, type: Boolean, desc: 'Whether the scope is active'
- requires :strategies, type: JSON, desc: 'The strategies of the scope'
- end
- post do
- authorize_update_feature_flag!
-
- result = ::FeatureFlags::UpdateService
- .new(user_project, current_user, scopes_attributes: [declared_params])
- .execute(feature_flag)
-
- if result[:status] == :success
- present scope, with: ::API::Entities::FeatureFlag::LegacyScope
- else
- render_api_error!(result[:message], result[:http_status])
- end
- end
-
- params do
- requires :environment_scope, type: String, desc: 'URL-encoded environment scope'
- end
- resource ':environment_scope', requirements: ENVIRONMENT_SCOPE_ENDPOINT_REQUIREMENTS do
- desc 'Get a scope of a feature flag' do
- detail 'This feature was introduced in GitLab 12.5'
- success ::API::Entities::FeatureFlag::LegacyScope
- end
- get do
- present scope, with: ::API::Entities::FeatureFlag::LegacyScope
- end
-
- desc 'Update a scope of a feature flag' do
- detail 'This feature was introduced in GitLab 12.5'
- success ::API::Entities::FeatureFlag::LegacyScope
- end
- params do
- optional :active, type: Boolean, desc: 'Whether the scope is active'
- optional :strategies, type: JSON, desc: 'The strategies of the scope'
- end
- put do
- authorize_update_feature_flag!
-
- scope_attributes = declared_params.merge(id: scope.id)
-
- result = ::FeatureFlags::UpdateService
- .new(user_project, current_user, scopes_attributes: [scope_attributes])
- .execute(feature_flag)
-
- if result[:status] == :success
- updated_scope = result[:feature_flag].scopes
- .find { |scope| scope.environment_scope == params[:environment_scope] }
-
- present updated_scope, with: ::API::Entities::FeatureFlag::LegacyScope
- else
- render_api_error!(result[:message], result[:http_status])
- end
- end
-
- desc 'Delete a scope from a feature flag' do
- detail 'This feature was introduced in GitLab 12.5'
- success ::API::Entities::FeatureFlag::LegacyScope
- end
- delete do
- authorize_update_feature_flag!
-
- param = { scopes_attributes: [{ id: scope.id, _destroy: true }] }
-
- result = ::FeatureFlags::UpdateService
- .new(user_project, current_user, param)
- .execute(feature_flag)
-
- if result[:status] == :success
- status :no_content
- else
- render_api_error!(result[:message], result[:http_status])
- end
- end
- end
- end
- end
- end
-
- helpers do
- def authorize_read_feature_flags!
- authorize! :read_feature_flag, user_project
- end
-
- def authorize_update_feature_flag!
- authorize! :update_feature_flag, feature_flag
- end
-
- def feature_flag
- @feature_flag ||= user_project.operations_feature_flags
- .find_by_name!(params[:name])
- end
-
- def scope
- @scope ||= feature_flag.scopes
- .find_by_environment_scope!(CGI.unescape(params[:environment_scope]))
- end
-
- def scopes_for_environment
- Operations::FeatureFlagScope
- .for_unleash_client(user_project, params[:environment])
- end
- end
- end
-end
diff --git a/lib/api/feature_flags.rb b/lib/api/feature_flags.rb
index a08933583fb..fb5858bc10b 100644
--- a/lib/api/feature_flags.rb
+++ b/lib/api/feature_flags.rb
@@ -95,54 +95,6 @@ module API
present_entity(feature_flag)
end
- desc 'Enable a strategy for a feature flag on an environment' do
- detail 'This feature was introduced in GitLab 12.5'
- success ::API::Entities::FeatureFlag
- end
- params do
- requires :environment_scope, type: String, desc: 'The environment scope of the feature flag'
- requires :strategy, type: JSON, desc: 'The strategy to be enabled on the scope'
- end
- post :enable do
- not_found! unless Feature.enabled?(:feature_flag_api, user_project)
- exclude_legacy_flags_check!
- render_api_error!('Version 2 flags not supported', :unprocessable_entity) if new_version_flag_present?
-
- result = ::FeatureFlags::EnableService
- .new(user_project, current_user, params).execute
-
- if result[:status] == :success
- status :ok
- present_entity(result[:feature_flag])
- else
- render_api_error!(result[:message], result[:http_status])
- end
- end
-
- desc 'Disable a strategy for a feature flag on an environment' do
- detail 'This feature is going to be introduced in GitLab 12.5 if `feature_flag_api` feature flag is removed'
- success ::API::Entities::FeatureFlag
- end
- params do
- requires :environment_scope, type: String, desc: 'The environment scope of the feature flag'
- requires :strategy, type: JSON, desc: 'The strategy to be disabled on the scope'
- end
- post :disable do
- not_found! unless Feature.enabled?(:feature_flag_api, user_project)
- exclude_legacy_flags_check!
- render_api_error!('Version 2 flags not supported', :unprocessable_entity) if feature_flag.new_version_flag?
-
- result = ::FeatureFlags::DisableService
- .new(user_project, current_user, params).execute
-
- if result[:status] == :success
- status :ok
- present_entity(result[:feature_flag])
- else
- render_api_error!(result[:message], result[:http_status])
- end
- end
-
desc 'Update a feature flag' do
detail 'This feature was introduced in GitLab 13.2'
success ::API::Entities::FeatureFlag
@@ -255,9 +207,7 @@ module API
end
def exclude_legacy_flags_check!
- if Feature.enabled?(:remove_legacy_flags, project, default_enabled: :yaml) &&
- Feature.disabled?(:remove_legacy_flags_override, project, default_enabled: :yaml) &&
- feature_flag.legacy_flag?
+ if feature_flag.legacy_flag?
not_found!
end
end
diff --git a/lib/api/unleash.rb b/lib/api/unleash.rb
index c622b8a499c..37fe540cde1 100644
--- a/lib/api/unleash.rb
+++ b/lib/api/unleash.rb
@@ -69,21 +69,7 @@ module API
def feature_flags
return [] unless unleash_app_name.present?
- legacy_flags =
- if exclude_legacy_flags?
- []
- else
- Operations::FeatureFlagScope.for_unleash_client(project, unleash_app_name)
- end
-
- new_version_flags = Operations::FeatureFlag.for_unleash_client(project, unleash_app_name)
-
- legacy_flags + new_version_flags
- end
-
- def exclude_legacy_flags?
- Feature.enabled?(:remove_legacy_flags, project, default_enabled: :yaml) &&
- Feature.disabled?(:remove_legacy_flags_override, project, default_enabled: :yaml)
+ Operations::FeatureFlag.for_unleash_client(project, unleash_app_name)
end
end
end
diff --git a/lib/gitlab/ci/config/entry/reports.rb b/lib/gitlab/ci/config/entry/reports.rb
index b34ab67cf04..4db25fb0930 100644
--- a/lib/gitlab/ci/config/entry/reports.rb
+++ b/lib/gitlab/ci/config/entry/reports.rb
@@ -43,7 +43,7 @@ module Gitlab
validates :cobertura, array_of_strings_or_string: true
validates :terraform, array_of_strings_or_string: true
validates :accessibility, array_of_strings_or_string: true
- validates :cluster_applications, array_of_strings_or_string: true
+ validates :cluster_applications, array_of_strings_or_string: true # DEPRECATED: https://gitlab.com/gitlab-org/gitlab/-/issues/333441
validates :requirements, array_of_strings_or_string: true
end
end
diff --git a/lib/gitlab/ci/templates/Managed-Cluster-Applications.gitlab-ci.yml b/lib/gitlab/ci/templates/Managed-Cluster-Applications.gitlab-ci.yml
index be8d56ccf93..ca63e942130 100644
--- a/lib/gitlab/ci/templates/Managed-Cluster-Applications.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Managed-Cluster-Applications.gitlab-ci.yml
@@ -27,8 +27,6 @@ apply:
variables:
- $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
artifacts:
- reports:
- cluster_applications: gl-cluster-applications.json
when: on_failure
paths:
- tiller.log
diff --git a/lib/gitlab/kubernetes/helm/parsers/list_v2.rb b/lib/gitlab/kubernetes/helm/parsers/list_v2.rb
deleted file mode 100644
index c5c5d198a6c..00000000000
--- a/lib/gitlab/kubernetes/helm/parsers/list_v2.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Kubernetes
- module Helm
- module Parsers
- # Parses Helm v2 list (JSON) output
- class ListV2
- ParserError = Class.new(StandardError)
-
- attr_reader :contents, :json
-
- def initialize(contents)
- @contents = contents
- @json = Gitlab::Json.parse(contents)
- rescue JSON::ParserError => e
- raise ParserError, e.message
- end
-
- def releases
- @releases = helm_releases
- end
-
- private
-
- def helm_releases
- helm_releases = json['Releases'] || []
-
- raise ParserError, 'Invalid format for Releases' unless helm_releases.all? { |item| item.is_a?(Hash) }
-
- helm_releases
- end
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/project_search_results.rb b/lib/gitlab/project_search_results.rb
index 6719dc8362b..e52023c4612 100644
--- a/lib/gitlab/project_search_results.rb
+++ b/lib/gitlab/project_search_results.rb
@@ -43,9 +43,20 @@ module Gitlab
end
end
+ # rubocop:disable CodeReuse/ActiveRecord
def users
- super.where(id: @project.team.members) # rubocop:disable CodeReuse/ActiveRecord
+ results = super
+
+ if @project.is_a?(Array)
+ team_members_for_projects = User.joins(:project_authorizations).where(project_authorizations: { project_id: @project })
+ results = results.where(id: team_members_for_projects)
+ else
+ results = results.where(id: @project.team.members)
+ end
+
+ results
end
+ # rubocop:enable CodeReuse/ActiveRecord
def limited_blobs_count
@limited_blobs_count ||= blobs(limit: count_limit).count
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index db9ce5233b7..bd30ecd1aa6 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -4521,9 +4521,6 @@ msgstr ""
msgid "At least one approval from a code owner is required to change files matching the respective CODEOWNER rules."
msgstr ""
-msgid "At least one logging option is required to be enabled"
-msgstr ""
-
msgid "At least one of group_id or project_id must be specified"
msgstr ""
@@ -7075,9 +7072,6 @@ msgstr ""
msgid "ClusterIntegration|Cluster name is required."
msgstr ""
-msgid "ClusterIntegration|Cluster_applications artifact too big. Maximum allowable size: %{human_size}"
-msgstr ""
-
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters. %{linkStart}More information%{linkEnd}"
msgstr ""
@@ -7282,9 +7276,6 @@ msgstr ""
msgid "ClusterIntegration|HTTP Error"
msgstr ""
-msgid "ClusterIntegration|Helm release failed to install"
-msgstr ""
-
msgid "ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}."
msgstr ""
@@ -7444,12 +7435,6 @@ msgstr ""
msgid "ClusterIntegration|No VPCs found"
msgstr ""
-msgid "ClusterIntegration|No deployment cluster found for this job"
-msgstr ""
-
-msgid "ClusterIntegration|No deployment found for this job"
-msgstr ""
-
msgid "ClusterIntegration|No instance type found"
msgstr ""
diff --git a/package.json b/package.json
index d81030cb666..ba6616fc280 100644
--- a/package.json
+++ b/package.json
@@ -56,7 +56,7 @@
"@gitlab/favicon-overlay": "2.0.0",
"@gitlab/svgs": "1.199.0",
"@gitlab/tributejs": "1.0.0",
- "@gitlab/ui": "29.34.0",
+ "@gitlab/ui": "29.34.1",
"@gitlab/visual-review-tools": "1.6.1",
"@rails/actioncable": "6.1.3-2",
"@rails/ujs": "6.1.3-2",
diff --git a/spec/controllers/projects/feature_flags_controller_spec.rb b/spec/controllers/projects/feature_flags_controller_spec.rb
index 752e8b652e0..f809dd31b3b 100644
--- a/spec/controllers/projects/feature_flags_controller_spec.rb
+++ b/spec/controllers/projects/feature_flags_controller_spec.rb
@@ -154,60 +154,6 @@ RSpec.describe Projects::FeatureFlagsController do
end
end
- context 'when feature flags have additional scopes' do
- let!(:feature_flag_active_scope) do
- create(:operations_feature_flag_scope,
- feature_flag: feature_flag_active,
- environment_scope: 'production',
- active: false)
- end
-
- let!(:feature_flag_inactive_scope) do
- create(:operations_feature_flag_scope,
- feature_flag: feature_flag_inactive,
- environment_scope: 'staging',
- active: false)
- end
-
- it 'returns a correct summary' do
- subject
-
- expect(json_response['count']['all']).to eq(2)
- expect(json_response['count']['enabled']).to eq(1)
- expect(json_response['count']['disabled']).to eq(1)
- end
-
- it 'recognizes feature flag 1 as active' do
- subject
-
- expect(json_response['feature_flags'].first['active']).to be_truthy
- end
-
- it 'recognizes feature flag 2 as inactive' do
- subject
-
- expect(json_response['feature_flags'].second['active']).to be_falsy
- end
-
- it 'has ordered scopes' do
- subject
-
- expect(json_response['feature_flags'][0]['scopes'][0]['id'])
- .to be < json_response['feature_flags'][0]['scopes'][1]['id']
- expect(json_response['feature_flags'][1]['scopes'][0]['id'])
- .to be < json_response['feature_flags'][1]['scopes'][1]['id']
- end
-
- it 'does not have N+1 problem' do
- recorded = ActiveRecord::QueryRecorder.new { subject }
-
- related_count = recorded.log
- .count { |query| query.include?('operations_feature_flag') }
-
- expect(related_count).to be_within(5).of(2)
- end
- end
-
context 'with version 1 and 2 feature flags' do
let!(:new_version_feature_flag) do
create(:operations_feature_flag, :new_version_flag, project: project, name: 'feature_flag_c')
@@ -235,7 +181,7 @@ RSpec.describe Projects::FeatureFlagsController do
subject { get(:show, params: params, format: :json) }
let!(:feature_flag) do
- create(:operations_feature_flag, project: project)
+ create(:operations_feature_flag, :legacy_flag, project: project)
end
let(:params) do
@@ -375,7 +321,7 @@ RSpec.describe Projects::FeatureFlagsController do
subject { get(:edit, params: params) }
context 'with legacy flags' do
- let!(:feature_flag) { create(:operations_feature_flag, project: project) }
+ let!(:feature_flag) { create(:operations_feature_flag, :legacy_flag, project: project) }
let(:params) do
{
@@ -385,29 +331,13 @@ RSpec.describe Projects::FeatureFlagsController do
}
end
- context 'removed' do
- before do
- stub_feature_flags(remove_legacy_flags: true, remove_legacy_flags_override: false)
- end
-
- it 'returns not found' do
- is_expected.to have_gitlab_http_status(:not_found)
- end
- end
-
- context 'removed' do
- before do
- stub_feature_flags(remove_legacy_flags: false)
- end
-
- it 'returns ok' do
- is_expected.to have_gitlab_http_status(:ok)
- end
+ it 'returns not found' do
+ is_expected.to have_gitlab_http_status(:not_found)
end
end
context 'with new version flags' do
- let!(:feature_flag) { create(:operations_feature_flag, :new_version_flag, project: project) }
+ let!(:feature_flag) { create(:operations_feature_flag, project: project) }
let(:params) do
{
@@ -814,7 +744,7 @@ RSpec.describe Projects::FeatureFlagsController do
describe 'DELETE destroy.json' do
subject { delete(:destroy, params: params, format: :json) }
- let!(:feature_flag) { create(:operations_feature_flag, project: project) }
+ let!(:feature_flag) { create(:operations_feature_flag, :legacy_flag, project: project) }
let(:params) do
{
diff --git a/spec/factories/ci/job_artifacts.rb b/spec/factories/ci/job_artifacts.rb
index 17cd495e217..642437b1119 100644
--- a/spec/factories/ci/job_artifacts.rb
+++ b/spec/factories/ci/job_artifacts.rb
@@ -317,21 +317,6 @@ FactoryBot.define do
end
end
- trait :cluster_applications do
- file_type { :cluster_applications }
- file_format { :gzip }
-
- transient do
- file do
- fixture_file_upload(Rails.root.join('spec/fixtures/helm/helm_list_v2_prometheus_missing.json.gz'), 'application/x-gzip')
- end
- end
-
- after(:build) do |artifact, evaluator|
- artifact.file = evaluator.file
- end
- end
-
trait :correct_checksum do
after(:build) do |artifact, evaluator|
artifact.file_sha256 = Digest::SHA256.file(artifact.file.path).hexdigest
diff --git a/spec/factories/clusters/applications/helm.rb b/spec/factories/clusters/applications/helm.rb
index 73103956ee8..29197768ec0 100644
--- a/spec/factories/clusters/applications/helm.rb
+++ b/spec/factories/clusters/applications/helm.rb
@@ -132,12 +132,6 @@ FactoryBot.define do
cluster factory: %i(cluster with_installed_helm provided_by_gcp project)
end
- factory :clusters_applications_fluentd, class: 'Clusters::Applications::Fluentd' do
- host { 'example.com' }
- cilium_log_enabled { true }
- cluster factory: %i(cluster with_installed_helm provided_by_gcp)
- end
-
factory :clusters_applications_cilium, class: 'Clusters::Applications::Cilium' do
cluster factory: %i(cluster with_installed_helm provided_by_gcp)
end
diff --git a/spec/factories/clusters/clusters.rb b/spec/factories/clusters/clusters.rb
index 3d0435cfe1d..dfe1b587951 100644
--- a/spec/factories/clusters/clusters.rb
+++ b/spec/factories/clusters/clusters.rb
@@ -101,7 +101,6 @@ FactoryBot.define do
application_jupyter factory: %i(clusters_applications_jupyter installed)
application_knative factory: %i(clusters_applications_knative installed)
application_elastic_stack factory: %i(clusters_applications_elastic_stack installed)
- application_fluentd factory: %i(clusters_applications_fluentd installed)
application_cilium factory: %i(clusters_applications_cilium installed)
end
diff --git a/spec/factories/operations/feature_flag_scopes.rb b/spec/factories/operations/feature_flag_scopes.rb
index a98c397b8b5..4ca9b53f320 100644
--- a/spec/factories/operations/feature_flag_scopes.rb
+++ b/spec/factories/operations/feature_flag_scopes.rb
@@ -2,7 +2,7 @@
FactoryBot.define do
factory :operations_feature_flag_scope, class: 'Operations::FeatureFlagScope' do
- association :feature_flag, factory: :operations_feature_flag
+ association :feature_flag, factory: [:operations_feature_flag, :legacy_flag]
active { true }
strategies { [{ name: "default", parameters: {} }] }
sequence(:environment_scope) { |n| "review/patch-#{n}" }
diff --git a/spec/factories/operations/feature_flags.rb b/spec/factories/operations/feature_flags.rb
index 7e43d38a04f..32e5ec9fb26 100644
--- a/spec/factories/operations/feature_flags.rb
+++ b/spec/factories/operations/feature_flags.rb
@@ -5,6 +5,7 @@ FactoryBot.define do
sequence(:name) { |n| "feature_flag_#{n}" }
project
active { true }
+ version { :new_version_flag }
trait :legacy_flag do
version { Operations::FeatureFlag.versions['legacy_flag'] }
diff --git a/spec/features/projects/feature_flags/user_sees_feature_flag_list_spec.rb b/spec/features/projects/feature_flags/user_sees_feature_flag_list_spec.rb
index 50fc7bb0753..d922bc1f4a0 100644
--- a/spec/features/projects/feature_flags/user_sees_feature_flag_list_spec.rb
+++ b/spec/features/projects/feature_flags/user_sees_feature_flag_list_spec.rb
@@ -18,65 +18,21 @@ RSpec.describe 'User sees feature flag list', :js do
context 'with legacy feature flags' do
before do
- create_flag(project, 'ci_live_trace', false).tap do |feature_flag|
+ create_flag(project, 'ci_live_trace', false, version: :legacy_flag).tap do |feature_flag|
create_scope(feature_flag, 'review/*', true)
end
- create_flag(project, 'drop_legacy_artifacts', false)
- create_flag(project, 'mr_train', true).tap do |feature_flag|
+ create_flag(project, 'drop_legacy_artifacts', false, version: :legacy_flag)
+ create_flag(project, 'mr_train', true, version: :legacy_flag).tap do |feature_flag|
create_scope(feature_flag, 'production', false)
end
end
- it 'user sees the first flag' do
- visit(project_feature_flags_path(project))
-
- within_feature_flag_row(1) do
- expect(page.find('.js-feature-flag-id')).to have_content('^1')
- expect(page.find('.feature-flag-name')).to have_content('ci_live_trace')
- expect_status_toggle_button_not_to_be_checked
-
- within_feature_flag_scopes do
- expect(page.find('[data-qa-selector="feature-flag-scope-muted-badge"]:nth-child(1)')).to have_content('*')
- expect(page.find('[data-qa-selector="feature-flag-scope-info-badge"]:nth-child(2)')).to have_content('review/*')
- end
- end
- end
-
- it 'user sees the second flag' do
- visit(project_feature_flags_path(project))
-
- within_feature_flag_row(2) do
- expect(page.find('.js-feature-flag-id')).to have_content('^2')
- expect(page.find('.feature-flag-name')).to have_content('drop_legacy_artifacts')
- expect_status_toggle_button_not_to_be_checked
-
- within_feature_flag_scopes do
- expect(page.find('[data-qa-selector="feature-flag-scope-muted-badge"]:nth-child(1)')).to have_content('*')
- end
- end
- end
-
- it 'user sees the third flag' do
- visit(project_feature_flags_path(project))
-
- within_feature_flag_row(3) do
- expect(page.find('.js-feature-flag-id')).to have_content('^3')
- expect(page.find('.feature-flag-name')).to have_content('mr_train')
- expect_status_toggle_button_to_be_checked
-
- within_feature_flag_scopes do
- expect(page.find('[data-qa-selector="feature-flag-scope-info-badge"]:nth-child(1)')).to have_content('*')
- expect(page.find('[data-qa-selector="feature-flag-scope-muted-badge"]:nth-child(2)')).to have_content('production')
- end
- end
- end
-
- it 'user sees the status toggle disabled' do
+ it 'shows empty page' do
visit(project_feature_flags_path(project))
- within_feature_flag_row(1) do
- expect_status_toggle_button_to_be_disabled
- end
+ expect(page).to have_text 'Get started with feature flags'
+ expect(page).to have_selector('.btn-confirm', text: 'New feature flag')
+ expect(page).to have_selector('[data-qa-selector="configure_feature_flags_button"]', text: 'Configure')
end
end
diff --git a/spec/features/projects/feature_flags/user_updates_feature_flag_spec.rb b/spec/features/projects/feature_flags/user_updates_feature_flag_spec.rb
index a435e565ff1..9c03a26abc8 100644
--- a/spec/features/projects/feature_flags/user_updates_feature_flag_spec.rb
+++ b/spec/features/projects/feature_flags/user_updates_feature_flag_spec.rb
@@ -73,16 +73,16 @@ RSpec.describe 'User updates feature flag', :js do
context 'with a legacy feature flag' do
let!(:feature_flag) do
create_flag(project, 'ci_live_trace', true,
- description: 'For live trace feature')
+ description: 'For live trace feature',
+ version: :legacy_flag)
end
let!(:scope) { create_scope(feature_flag, 'review/*', true) }
- it 'the user cannot edit the flag' do
+ it 'shows not found error' do
visit(edit_project_feature_flag_path(project, feature_flag))
- expect(page).to have_text 'This feature flag is read-only, and it will be removed in 14.0.'
- expect(page).to have_css('button.js-ff-submit.disabled')
+ expect(page).to have_text 'Page Not Found'
end
end
end
diff --git a/spec/finders/feature_flags_finder_spec.rb b/spec/finders/feature_flags_finder_spec.rb
index 4da5e954157..4faa6a62a1f 100644
--- a/spec/finders/feature_flags_finder_spec.rb
+++ b/spec/finders/feature_flags_finder_spec.rb
@@ -24,10 +24,6 @@ RSpec.describe FeatureFlagsFinder do
let!(:feature_flag_2) { create(:operations_feature_flag, name: 'flag-b', project: project) }
let(:args) { {} }
- before do
- stub_feature_flags(remove_legacy_flags: false)
- end
-
it 'returns feature flags ordered by name' do
is_expected.to eq([feature_flag_1, feature_flag_2])
end
@@ -77,21 +73,11 @@ RSpec.describe FeatureFlagsFinder do
end
end
- context 'when new version flags are enabled' do
- let!(:feature_flag_3) { create(:operations_feature_flag, :new_version_flag, name: 'flag-c', project: project) }
-
- it 'returns new and legacy flags' do
- is_expected.to eq([feature_flag_1, feature_flag_2, feature_flag_3])
- end
+ context 'with a legacy flag' do
+ let!(:feature_flag_3) { create(:operations_feature_flag, :legacy_flag, name: 'flag-c', project: project) }
- context 'when legacy flags are disabled' do
- before do
- stub_feature_flags(remove_legacy_flags_override: false, remove_legacy_flags: true)
- end
-
- it 'returns only new flags' do
- is_expected.to eq([feature_flag_3])
- end
+ it 'returns new flags' do
+ is_expected.to eq([feature_flag_1, feature_flag_2])
end
end
end
diff --git a/spec/fixtures/api/schemas/cluster_status.json b/spec/fixtures/api/schemas/cluster_status.json
index c919cd54a28..ce62655648b 100644
--- a/spec/fixtures/api/schemas/cluster_status.json
+++ b/spec/fixtures/api/schemas/cluster_status.json
@@ -42,7 +42,6 @@
"host": {"type": ["string", "null"]},
"port": {"type": ["integer", "514"]},
"protocol": {"type": ["integer", "0"]},
- "cilium_log_enabled": {"type": ["boolean", "true"]},
"update_available": { "type": ["boolean", "null"] },
"can_uninstall": { "type": "boolean" },
"available_domains": {
diff --git a/spec/fixtures/helm/helm_list_v2_cilium_deployed.json.gz b/spec/fixtures/helm/helm_list_v2_cilium_deployed.json.gz
deleted file mode 100644
index a343356c95c..00000000000
--- a/spec/fixtures/helm/helm_list_v2_cilium_deployed.json.gz
+++ /dev/null
Binary files differ
diff --git a/spec/fixtures/helm/helm_list_v2_cilium_failed.json.gz b/spec/fixtures/helm/helm_list_v2_cilium_failed.json.gz
deleted file mode 100644
index f7faff2ca19..00000000000
--- a/spec/fixtures/helm/helm_list_v2_cilium_failed.json.gz
+++ /dev/null
Binary files differ
diff --git a/spec/fixtures/helm/helm_list_v2_cilium_missing.json.gz b/spec/fixtures/helm/helm_list_v2_cilium_missing.json.gz
deleted file mode 100644
index 20cac36287b..00000000000
--- a/spec/fixtures/helm/helm_list_v2_cilium_missing.json.gz
+++ /dev/null
Binary files differ
diff --git a/spec/fixtures/helm/helm_list_v2_empty_blob.json.gz b/spec/fixtures/helm/helm_list_v2_empty_blob.json.gz
deleted file mode 100644
index 5647f052c3b..00000000000
--- a/spec/fixtures/helm/helm_list_v2_empty_blob.json.gz
+++ /dev/null
Binary files differ
diff --git a/spec/fixtures/helm/helm_list_v2_prometheus_deployed.json.gz b/spec/fixtures/helm/helm_list_v2_prometheus_deployed.json.gz
deleted file mode 100644
index bcbbba8dc00..00000000000
--- a/spec/fixtures/helm/helm_list_v2_prometheus_deployed.json.gz
+++ /dev/null
Binary files differ
diff --git a/spec/fixtures/helm/helm_list_v2_prometheus_failed.json.gz b/spec/fixtures/helm/helm_list_v2_prometheus_failed.json.gz
deleted file mode 100644
index 0b39b42bdfa..00000000000
--- a/spec/fixtures/helm/helm_list_v2_prometheus_failed.json.gz
+++ /dev/null
Binary files differ
diff --git a/spec/fixtures/helm/helm_list_v2_prometheus_missing.json.gz b/spec/fixtures/helm/helm_list_v2_prometheus_missing.json.gz
deleted file mode 100644
index 20cac36287b..00000000000
--- a/spec/fixtures/helm/helm_list_v2_prometheus_missing.json.gz
+++ /dev/null
Binary files differ
diff --git a/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric.yml b/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric.yml
index 90d395e1eda..f694e617320 100644
--- a/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric.yml
+++ b/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric.yml
@@ -12,6 +12,7 @@ milestone: "13.9"
introduced_by_url:
time_frame: 7d
data_source:
+data_category: Operational
distribution:
- ce
# Add here corresponding tiers
diff --git a/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_ee.yml b/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_ee.yml
index c51b5bf6e01..5cebfbcbad9 100644
--- a/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_ee.yml
+++ b/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_ee.yml
@@ -12,6 +12,7 @@ milestone: "13.9"
introduced_by_url:
time_frame: 7d
data_source:
+data_category: Operational
distribution:
- ee
tier:
diff --git a/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_name_suggestions.yml b/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_name_suggestions.yml
index c1ed9783308..d448e7bf3f6 100644
--- a/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_name_suggestions.yml
+++ b/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_name_suggestions.yml
@@ -13,6 +13,7 @@ milestone: "13.9"
introduced_by_url:
time_frame: 7d
data_source:
+data_category: Operational
distribution:
- ce
- ee
diff --git a/spec/frontend/packages/shared/components/__snapshots__/package_list_row_spec.js.snap b/spec/frontend/packages/shared/components/__snapshots__/package_list_row_spec.js.snap
index f4e617ecafe..b576f1b2553 100644
--- a/spec/frontend/packages/shared/components/__snapshots__/package_list_row_spec.js.snap
+++ b/spec/frontend/packages/shared/components/__snapshots__/package_list_row_spec.js.snap
@@ -11,7 +11,7 @@ exports[`packages_list_row renders 1`] = `
<!---->
<div
- class="gl-display-flex gl-xs-flex-direction-column gl-justify-content-space-between gl-align-items-stretch gl-flex-fill-1"
+ class="gl-display-flex gl-xs-flex-direction-column gl-justify-content-space-between gl-align-items-stretch gl-flex-grow-1"
>
<div
class="gl-display-flex gl-flex-direction-column gl-xs-mb-3 gl-min-w-0 gl-flex-grow-1"
@@ -42,7 +42,7 @@ exports[`packages_list_row renders 1`] = `
</div>
<div
- class="gl-display-flex gl-align-items-center gl-text-gray-500 gl-min-h-6 gl-min-w-0 gl-flex-fill-1"
+ class="gl-display-flex gl-align-items-center gl-text-gray-500 gl-min-h-6 gl-min-w-0 gl-flex-grow-1"
>
<div
class="gl-display-flex"
diff --git a/spec/frontend/runner/runner_list/filtered_search_utils_spec.js b/spec/frontend/runner/runner_list/runner_search_utils_spec.js
index abbe05452d1..a1f33e9c880 100644
--- a/spec/frontend/runner/runner_list/filtered_search_utils_spec.js
+++ b/spec/frontend/runner/runner_list/runner_search_utils_spec.js
@@ -3,7 +3,7 @@ import {
fromUrlQueryToSearch,
fromSearchToUrl,
fromSearchToVariables,
-} from '~/runner/runner_list/filtered_search_utils';
+} from '~/runner/runner_list/runner_search_utils';
describe('search_params.js', () => {
const examples = [
@@ -24,6 +24,40 @@ describe('search_params.js', () => {
graphqlVariables: { status: 'ACTIVE', sort: 'CREATED_DESC', first: RUNNER_PAGE_SIZE },
},
{
+ name: 'a single term text search',
+ urlQuery: '?search=something',
+ search: {
+ filters: [
+ {
+ type: 'filtered-search-term',
+ value: { data: 'something' },
+ },
+ ],
+ pagination: { page: 1 },
+ sort: 'CREATED_DESC',
+ },
+ graphqlVariables: { search: 'something', sort: 'CREATED_DESC', first: RUNNER_PAGE_SIZE },
+ },
+ {
+ name: 'a two terms text search',
+ urlQuery: '?search=something+else',
+ search: {
+ filters: [
+ {
+ type: 'filtered-search-term',
+ value: { data: 'something' },
+ },
+ {
+ type: 'filtered-search-term',
+ value: { data: 'else' },
+ },
+ ],
+ pagination: { page: 1 },
+ sort: 'CREATED_DESC',
+ },
+ graphqlVariables: { search: 'something else', sort: 'CREATED_DESC', first: RUNNER_PAGE_SIZE },
+ },
+ {
name: 'single instance type',
urlQuery: '?runner_type[]=INSTANCE_TYPE',
search: {
@@ -110,6 +144,13 @@ describe('search_params.js', () => {
});
});
+ it('When search params appear as array, they are concatenated', () => {
+ expect(fromUrlQueryToSearch('?search[]=my&search[]=text').filters).toEqual([
+ { type: 'filtered-search-term', value: { data: 'my' } },
+ { type: 'filtered-search-term', value: { data: 'text' } },
+ ]);
+ });
+
it('When a page cannot be parsed as a number, it defaults to `1`', () => {
expect(fromUrlQueryToSearch('?page=NONSENSE&after=AFTER_CURSOR').pagination).toEqual({
page: 1,
@@ -136,12 +177,15 @@ describe('search_params.js', () => {
});
});
- it('When a filtered search parameter is already present, it gets removed', () => {
- const initialUrl = `http://test.host/?status[]=ACTIVE`;
+ it.each([
+ 'http://test.host/?status[]=ACTIVE',
+ 'http://test.host/?runner_type[]=INSTANCE_TYPE',
+ 'http://test.host/?search=my_text',
+ ])('When a filter is removed, it is removed from the URL', (initalUrl) => {
const search = { filters: [], sort: 'CREATED_DESC' };
const expectedUrl = `http://test.host/`;
- expect(fromSearchToUrl(search, initialUrl)).toEqual(expectedUrl);
+ expect(fromSearchToUrl(search, initalUrl)).toEqual(expectedUrl);
});
it('When unrelated search parameter is present, it does not get removed', () => {
@@ -159,5 +203,37 @@ describe('search_params.js', () => {
expect(fromSearchToVariables(search)).toEqual(graphqlVariables);
});
});
+
+ it('When a search param is empty, it gets removed', () => {
+ expect(
+ fromSearchToVariables({
+ filters: [
+ {
+ type: 'filtered-search-term',
+ value: { data: '' },
+ },
+ ],
+ }),
+ ).toMatchObject({
+ search: '',
+ });
+
+ expect(
+ fromSearchToVariables({
+ filters: [
+ {
+ type: 'filtered-search-term',
+ value: { data: 'something' },
+ },
+ {
+ type: 'filtered-search-term',
+ value: { data: '' },
+ },
+ ],
+ }),
+ ).toMatchObject({
+ search: 'something',
+ });
+ });
});
});
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_utils_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_utils_spec.js
index b2ed79cd75a..93cddff8421 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_utils_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_utils_spec.js
@@ -1,6 +1,9 @@
import { useLocalStorageSpy } from 'helpers/local_storage_helper';
import AccessorUtilities from '~/lib/utils/accessor';
+
+import { FILTERED_SEARCH_TERM } from '~/vue_shared/components/filtered_search_bar/constants';
+
import {
stripQuotes,
uniqueTokens,
@@ -210,6 +213,19 @@ describe('filterToQueryObject', () => {
const res = filterToQueryObject({ [token]: value });
expect(res).toEqual(result);
});
+
+ it.each([
+ [FILTERED_SEARCH_TERM, [{ value: '' }], { search: '' }],
+ [FILTERED_SEARCH_TERM, [{ value: 'bar' }], { search: 'bar' }],
+ [FILTERED_SEARCH_TERM, [{ value: 'bar' }, { value: '' }], { search: 'bar' }],
+ [FILTERED_SEARCH_TERM, [{ value: 'bar' }, { value: 'baz' }], { search: 'bar baz' }],
+ ])(
+ 'when filteredSearchTermKey=search gathers filter values %s=%j into query object=%j',
+ (token, value, result) => {
+ const res = filterToQueryObject({ [token]: value }, { filteredSearchTermKey: 'search' });
+ expect(res).toEqual(result);
+ },
+ );
});
describe('urlQueryToFilter', () => {
@@ -255,10 +271,61 @@ describe('urlQueryToFilter', () => {
},
],
['not[foo][]=bar', { foo: [{ value: 'bar', operator: '!=' }] }],
- ])('gathers filter values %s into query object=%j', (query, result) => {
- const res = urlQueryToFilter(query);
- expect(res).toEqual(result);
- });
+ ['nop=1&not[nop]=2', {}, { filterNamesAllowList: ['foo'] }],
+ [
+ 'foo[]=bar&not[foo][]=baz&nop=xxx&not[nop]=yyy',
+ {
+ foo: [
+ { value: 'bar', operator: '=' },
+ { value: 'baz', operator: '!=' },
+ ],
+ },
+ { filterNamesAllowList: ['foo'] },
+ ],
+ [
+ 'search=term&foo=bar',
+ {
+ [FILTERED_SEARCH_TERM]: [{ value: 'term' }],
+ foo: { value: 'bar', operator: '=' },
+ },
+ { filteredSearchTermKey: 'search' },
+ ],
+ [
+ 'search=my terms',
+ {
+ [FILTERED_SEARCH_TERM]: [{ value: 'my' }, { value: 'terms' }],
+ },
+ { filteredSearchTermKey: 'search' },
+ ],
+ [
+ 'search[]=my&search[]=terms',
+ {
+ [FILTERED_SEARCH_TERM]: [{ value: 'my' }, { value: 'terms' }],
+ },
+ { filteredSearchTermKey: 'search' },
+ ],
+ [
+ 'search=my+terms',
+ {
+ [FILTERED_SEARCH_TERM]: [{ value: 'my' }, { value: 'terms' }],
+ },
+ { filteredSearchTermKey: 'search', legacySpacesDecode: false },
+ ],
+ [
+ 'search=my terms&foo=bar&nop=xxx',
+ {
+ [FILTERED_SEARCH_TERM]: [{ value: 'my' }, { value: 'terms' }],
+ foo: { value: 'bar', operator: '=' },
+ },
+ { filteredSearchTermKey: 'search', filterNamesAllowList: ['foo'] },
+ ],
+ ])(
+ 'gathers filter values %s into query object=%j when options %j',
+ (query, result, options = undefined) => {
+ const res = urlQueryToFilter(query, options);
+ expect(res).toEqual(result);
+ },
+ );
});
describe('getRecentlyUsedTokenValues', () => {
diff --git a/spec/graphql/resolvers/concerns/caching_array_resolver_spec.rb b/spec/graphql/resolvers/concerns/caching_array_resolver_spec.rb
index e9e7fff6e6e..8d15d7eda1b 100644
--- a/spec/graphql/resolvers/concerns/caching_array_resolver_spec.rb
+++ b/spec/graphql/resolvers/concerns/caching_array_resolver_spec.rb
@@ -4,7 +4,6 @@ require 'spec_helper'
RSpec.describe ::CachingArrayResolver do
include GraphqlHelpers
- include Gitlab::Graphql::Laziness
let_it_be(:admins) { create_list(:user, 4, admin: true) }
let(:query_context) { { current_user: admins.first } }
diff --git a/spec/graphql/resolvers/package_details_resolver_spec.rb b/spec/graphql/resolvers/package_details_resolver_spec.rb
index 1bdc069b3bb..d6acb31d4e3 100644
--- a/spec/graphql/resolvers/package_details_resolver_spec.rb
+++ b/spec/graphql/resolvers/package_details_resolver_spec.rb
@@ -4,7 +4,6 @@ require 'spec_helper'
RSpec.describe Resolvers::PackageDetailsResolver do
include GraphqlHelpers
- include ::Gitlab::Graphql::Laziness
let_it_be_with_reload(:project) { create(:project) }
let_it_be(:user) { project.owner }
diff --git a/spec/lib/gitlab/kubernetes/helm/parsers/list_v2_spec.rb b/spec/lib/gitlab/kubernetes/helm/parsers/list_v2_spec.rb
deleted file mode 100644
index 435c296d5f1..00000000000
--- a/spec/lib/gitlab/kubernetes/helm/parsers/list_v2_spec.rb
+++ /dev/null
@@ -1,100 +0,0 @@
-# frozen_string_literal: true
-
-require 'fast_spec_helper'
-
-RSpec.describe Gitlab::Kubernetes::Helm::Parsers::ListV2 do
- let(:valid_file_contents) do
- <<~EOF
- {
- "Next": "",
- "Releases": [
- {
- "Name": "certmanager",
- "Revision": 2,
- "Updated": "Sun Mar 29 06:55:42 2020",
- "Status": "DEPLOYED",
- "Chart": "cert-manager-v0.10.1",
- "AppVersion": "v0.10.1",
- "Namespace": "gitlab-managed-apps"
- },
- {
- "Name": "certmanager-crds",
- "Revision": 2,
- "Updated": "Sun Mar 29 06:55:32 2020",
- "Status": "DEPLOYED",
- "Chart": "cert-manager-crds-v0.2.0",
- "AppVersion": "release-0.10",
- "Namespace": "gitlab-managed-apps"
- },
- {
- "Name": "certmanager-issuer",
- "Revision": 1,
- "Updated": "Tue Feb 18 10:04:04 2020",
- "Status": "FAILED",
- "Chart": "cert-manager-issuer-v0.1.0",
- "AppVersion": "",
- "Namespace": "gitlab-managed-apps"
- },
- {
- "Name": "runner",
- "Revision": 2,
- "Updated": "Sun Mar 29 07:01:01 2020",
- "Status": "DEPLOYED",
- "Chart": "gitlab-runner-0.14.0",
- "AppVersion": "12.8.0",
- "Namespace": "gitlab-managed-apps"
- }
- ]
- }
- EOF
- end
-
- describe '#initialize' do
- it 'initializes without error' do
- expect do
- described_class.new(valid_file_contents)
- end.not_to raise_error
- end
-
- it 'raises an error on invalid JSON' do
- expect do
- described_class.new('')
- end.to raise_error(described_class::ParserError)
- end
- end
-
- describe '#releases' do
- subject(:list_v2) { described_class.new(valid_file_contents) }
-
- it 'returns list of releases' do
- expect(list_v2.releases).to match([
- a_hash_including('Name' => 'certmanager', 'Status' => 'DEPLOYED'),
- a_hash_including('Name' => 'certmanager-crds', 'Status' => 'DEPLOYED'),
- a_hash_including('Name' => 'certmanager-issuer', 'Status' => 'FAILED'),
- a_hash_including('Name' => 'runner', 'Status' => 'DEPLOYED')
- ])
- end
-
- context 'empty Releases' do
- let(:valid_file_contents) { '{}' }
-
- it 'returns an empty array' do
- expect(list_v2.releases).to eq([])
- end
- end
-
- context 'invalid Releases' do
- let(:invalid_file_contents) do
- '{ "Releases" : ["a", "b"] }'
- end
-
- subject(:list_v2) { described_class.new(invalid_file_contents) }
-
- it 'raises an error' do
- expect do
- list_v2.releases
- end.to raise_error(described_class::ParserError, 'Invalid format for Releases')
- end
- end
- end
-end
diff --git a/spec/lib/gitlab/project_search_results_spec.rb b/spec/lib/gitlab/project_search_results_spec.rb
index a76ad1f6f4c..2f28b8dfce0 100644
--- a/spec/lib/gitlab/project_search_results_spec.rb
+++ b/spec/lib/gitlab/project_search_results_spec.rb
@@ -549,30 +549,39 @@ RSpec.describe Gitlab::ProjectSearchResults do
describe 'user search' do
let(:query) { 'gob' }
- let(:group) { create(:group) }
- let(:project) { create(:project, namespace: group) }
+
+ let_it_be(:user_1) { create(:user, username: 'gob_bluth') }
+ let_it_be(:user_2) { create(:user, username: 'michael_bluth') }
+ let_it_be(:user_3) { create(:user, username: 'gob_2018') }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project) { create(:project, namespace: group) }
subject(:objects) { results.objects('users') }
it 'returns the user belonging to the project matching the search query' do
- user1 = create(:user, username: 'gob_bluth')
- create(:project_member, :developer, user: user1, project: project)
+ create(:project_member, :developer, user: user_1, project: project)
+ create(:project_member, :developer, user: user_2, project: project)
- user2 = create(:user, username: 'michael_bluth')
- create(:project_member, :developer, user: user2, project: project)
+ expect(objects).to contain_exactly(user_1)
+ end
- create(:user, username: 'gob_2018')
+ it 'returns the user belonging to the group matching the search query' do
+ create(:group_member, :developer, user: user_1, group: group)
- expect(objects).to contain_exactly(user1)
+ expect(objects).to contain_exactly(user_1)
end
- it 'returns the user belonging to the group matching the search query' do
- user1 = create(:user, username: 'gob_bluth')
- create(:group_member, :developer, user: user1, group: group)
+ context 'when multiple projects provided' do
+ let_it_be(:project_2) { create(:project, namespace: group) }
+
+ subject(:results) { described_class.new(user, query, project: [project, project_2], repository_ref: repository_ref, filters: filters) }
- create(:user, username: 'gob_2018')
+ it 'returns users belonging to projects matching the search query' do
+ create(:project_member, :developer, user: user_1, project: project)
+ create(:project_member, :developer, user: user_3, project: project_2)
- expect(objects).to contain_exactly(user1)
+ expect(objects).to contain_exactly(user_1, user_3)
+ end
end
end
end
diff --git a/spec/models/clusters/applications/fluentd_spec.rb b/spec/models/clusters/applications/fluentd_spec.rb
deleted file mode 100644
index a4df44225f3..00000000000
--- a/spec/models/clusters/applications/fluentd_spec.rb
+++ /dev/null
@@ -1,71 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Clusters::Applications::Fluentd do
- let(:cilium_log_enabled) { true }
- let(:fluentd) { create(:clusters_applications_fluentd, cilium_log_enabled: cilium_log_enabled) }
-
- include_examples 'cluster application core specs', :clusters_applications_fluentd
- include_examples 'cluster application status specs', :clusters_applications_fluentd
- include_examples 'cluster application version specs', :clusters_applications_fluentd
- include_examples 'cluster application initial status specs'
-
- describe '#can_uninstall?' do
- subject { fluentd.can_uninstall? }
-
- it { is_expected.to be true }
- end
-
- describe '#install_command' do
- subject { fluentd.install_command }
-
- it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::V3::InstallCommand) }
-
- it 'is initialized with fluentd arguments' do
- expect(subject.name).to eq('fluentd')
- expect(subject.chart).to eq('fluentd/fluentd')
- expect(subject.version).to eq('2.4.0')
- expect(subject).to be_rbac
- end
-
- context 'application failed to install previously' do
- let(:fluentd) { create(:clusters_applications_fluentd, :errored, version: '0.0.1') }
-
- it 'is initialized with the locked version' do
- expect(subject.version).to eq('2.4.0')
- end
- end
- end
-
- describe '#files' do
- let(:application) { fluentd }
- let(:values) { subject[:'values.yaml'] }
-
- subject { application.files }
-
- it 'includes fluentd specific keys in the values.yaml file' do
- expect(values).to include('output.conf', 'general.conf')
- end
- end
-
- describe '#values' do
- let(:cilium_log_path) { "/var/log/containers/*#{described_class::CILIUM_CONTAINER_NAME}*.log" }
-
- subject { fluentd.values }
-
- context 'with cilium_log_enabled set to false' do
- let(:cilium_log_enabled) { false }
-
- it "raises ActiveRecord::RecordInvalid" do
- expect {subject}.to raise_error(ActiveRecord::RecordInvalid)
- end
- end
-
- context 'with cilium_log_enabled set to true' do
- let(:cilium_log_enabled) { true }
-
- it { is_expected.to include(cilium_log_path) }
- end
- end
-end
diff --git a/spec/models/operations/feature_flag_scope_spec.rb b/spec/models/operations/feature_flag_scope_spec.rb
index 29d338d8b29..dc83789fade 100644
--- a/spec/models/operations/feature_flag_scope_spec.rb
+++ b/spec/models/operations/feature_flag_scope_spec.rb
@@ -29,7 +29,7 @@ RSpec.describe Operations::FeatureFlagScope do
end
context 'when environment scope of a default scope is updated' do
- let!(:feature_flag) { create(:operations_feature_flag) }
+ let!(:feature_flag) { create(:operations_feature_flag, :legacy_flag) }
let!(:scope_default) { feature_flag.default_scope }
it 'keeps default scope intact' do
@@ -41,7 +41,7 @@ RSpec.describe Operations::FeatureFlagScope do
end
context 'when a default scope is destroyed' do
- let!(:feature_flag) { create(:operations_feature_flag) }
+ let!(:feature_flag) { create(:operations_feature_flag, :legacy_flag) }
let!(:scope_default) { feature_flag.default_scope }
it 'prevents from destroying the default scope' do
diff --git a/spec/models/operations/feature_flag_spec.rb b/spec/models/operations/feature_flag_spec.rb
index d5b3c7a8582..55682e12642 100644
--- a/spec/models/operations/feature_flag_spec.rb
+++ b/spec/models/operations/feature_flag_spec.rb
@@ -181,7 +181,7 @@ RSpec.describe Operations::FeatureFlag do
end
context 'when the feature flag is active and all scopes are inactive' do
- let!(:feature_flag) { create(:operations_feature_flag, active: true) }
+ let!(:feature_flag) { create(:operations_feature_flag, :legacy_flag, active: true) }
it 'returns the flag' do
feature_flag.default_scope.update!(active: false)
@@ -199,7 +199,7 @@ RSpec.describe Operations::FeatureFlag do
end
context 'when the feature flag is inactive and all scopes are active' do
- let!(:feature_flag) { create(:operations_feature_flag, active: false) }
+ let!(:feature_flag) { create(:operations_feature_flag, :legacy_flag, active: false) }
it 'does not return the flag' do
feature_flag.default_scope.update!(active: true)
@@ -221,7 +221,7 @@ RSpec.describe Operations::FeatureFlag do
end
context 'when the feature flag is active and all scopes are inactive' do
- let!(:feature_flag) { create(:operations_feature_flag, active: true) }
+ let!(:feature_flag) { create(:operations_feature_flag, :legacy_flag, active: true) }
it 'does not return the flag' do
feature_flag.default_scope.update!(active: false)
@@ -239,7 +239,7 @@ RSpec.describe Operations::FeatureFlag do
end
context 'when the feature flag is inactive and all scopes are active' do
- let!(:feature_flag) { create(:operations_feature_flag, active: false) }
+ let!(:feature_flag) { create(:operations_feature_flag, :legacy_flag, active: false) }
it 'returns the flag' do
feature_flag.default_scope.update!(active: true)
diff --git a/spec/requests/api/feature_flag_scopes_spec.rb b/spec/requests/api/feature_flag_scopes_spec.rb
deleted file mode 100644
index da5b2cbb7ae..00000000000
--- a/spec/requests/api/feature_flag_scopes_spec.rb
+++ /dev/null
@@ -1,319 +0,0 @@
-# frozen_string_literal: true
-require 'spec_helper'
-
-RSpec.describe API::FeatureFlagScopes do
- include FeatureFlagHelpers
-
- let(:project) { create(:project, :repository) }
- let(:developer) { create(:user) }
- let(:reporter) { create(:user) }
- let(:user) { developer }
-
- before do
- project.add_developer(developer)
- project.add_reporter(reporter)
- end
-
- shared_examples_for 'check user permission' do
- context 'when user is reporter' do
- let(:user) { reporter }
-
- it 'forbids the request' do
- subject
-
- expect(response).to have_gitlab_http_status(:forbidden)
- end
- end
- end
-
- shared_examples_for 'not found' do
- it 'returns Not Found' do
- subject
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
-
- describe 'GET /projects/:id/feature_flag_scopes' do
- subject do
- get api("/projects/#{project.id}/feature_flag_scopes", user),
- params: params
- end
-
- let(:feature_flag_1) { create_flag(project, 'flag_1', true) }
- let(:feature_flag_2) { create_flag(project, 'flag_2', true) }
-
- before do
- create_scope(feature_flag_1, 'staging', false)
- create_scope(feature_flag_1, 'production', true)
- create_scope(feature_flag_2, 'review/*', false)
- end
-
- context 'when environment is production' do
- let(:params) { { environment: 'production' } }
-
- it_behaves_like 'check user permission'
-
- it 'returns all effective feature flags under the environment' do
- subject
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(response).to match_response_schema('public_api/v4/feature_flag_detailed_scopes')
- expect(json_response.second).to include({ 'name' => 'flag_1', 'active' => true })
- expect(json_response.first).to include({ 'name' => 'flag_2', 'active' => true })
- end
- end
-
- context 'when environment is staging' do
- let(:params) { { environment: 'staging' } }
-
- it 'returns all effective feature flags under the environment' do
- subject
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response.second).to include({ 'name' => 'flag_1', 'active' => false })
- expect(json_response.first).to include({ 'name' => 'flag_2', 'active' => true })
- end
- end
-
- context 'when environment is review/feature X' do
- let(:params) { { environment: 'review/feature X' } }
-
- it 'returns all effective feature flags under the environment' do
- subject
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response.second).to include({ 'name' => 'flag_1', 'active' => true })
- expect(json_response.first).to include({ 'name' => 'flag_2', 'active' => false })
- end
- end
- end
-
- describe 'GET /projects/:id/feature_flags/:name/scopes' do
- subject do
- get api("/projects/#{project.id}/feature_flags/#{feature_flag.name}/scopes", user)
- end
-
- context 'when there are two scopes' do
- let(:feature_flag) { create_flag(project, 'test') }
- let!(:additional_scope) { create_scope(feature_flag, 'production', false) }
-
- it_behaves_like 'check user permission'
-
- it 'returns scopes of the feature flag' do
- subject
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(response).to match_response_schema('public_api/v4/feature_flag_scopes')
- expect(json_response.count).to eq(2)
- expect(json_response.first['environment_scope']).to eq(feature_flag.scopes[0].environment_scope)
- expect(json_response.second['environment_scope']).to eq(feature_flag.scopes[1].environment_scope)
- end
- end
-
- context 'when there are no feature flags' do
- let(:feature_flag) { double(:feature_flag, name: 'test') }
-
- it_behaves_like 'not found'
- end
- end
-
- describe 'POST /projects/:id/feature_flags/:name/scopes' do
- subject do
- post api("/projects/#{project.id}/feature_flags/#{feature_flag.name}/scopes", user),
- params: params
- end
-
- let(:params) do
- {
- environment_scope: 'staging',
- active: true,
- strategies: [{ name: 'userWithId', parameters: { 'userIds': 'a,b,c' } }].to_json
- }
- end
-
- context 'when there is a corresponding feature flag' do
- let!(:feature_flag) { create(:operations_feature_flag, project: project) }
-
- it_behaves_like 'check user permission'
-
- it 'creates a new scope' do
- subject
-
- expect(response).to have_gitlab_http_status(:created)
- expect(response).to match_response_schema('public_api/v4/feature_flag_scope')
- expect(json_response['environment_scope']).to eq(params[:environment_scope])
- expect(json_response['active']).to eq(params[:active])
- expect(json_response['strategies']).to eq(Gitlab::Json.parse(params[:strategies]))
- end
-
- context 'when the scope already exists' do
- before do
- create_scope(feature_flag, params[:environment_scope])
- end
-
- it 'returns error' do
- subject
-
- expect(response).to have_gitlab_http_status(:bad_request)
- expect(json_response['message']).to include('Scopes environment scope (staging) has already been taken')
- end
- end
- end
-
- context 'when feature flag is not found' do
- let(:feature_flag) { double(:feature_flag, name: 'test') }
-
- it_behaves_like 'not found'
- end
- end
-
- describe 'GET /projects/:id/feature_flags/:name/scopes/:environment_scope' do
- subject do
- get api("/projects/#{project.id}/feature_flags/#{feature_flag.name}/scopes/#{environment_scope}",
- user)
- end
-
- let(:environment_scope) { scope.environment_scope }
-
- shared_examples_for 'successful response' do
- it 'returns a scope' do
- subject
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(response).to match_response_schema('public_api/v4/feature_flag_scope')
- expect(json_response['id']).to eq(scope.id)
- expect(json_response['active']).to eq(scope.active)
- expect(json_response['environment_scope']).to eq(scope.environment_scope)
- end
- end
-
- context 'when there is a feature flag' do
- let!(:feature_flag) { create(:operations_feature_flag, project: project) }
- let(:scope) { feature_flag.default_scope }
-
- it_behaves_like 'check user permission'
- it_behaves_like 'successful response'
-
- context 'when environment scope includes slash' do
- let!(:scope) { create_scope(feature_flag, 'review/*', false) }
-
- it_behaves_like 'not found'
-
- context 'when URL-encoding the environment scope parameter' do
- let(:environment_scope) { CGI.escape(scope.environment_scope) }
-
- it_behaves_like 'successful response'
- end
- end
- end
-
- context 'when there are no feature flags' do
- let(:feature_flag) { double(:feature_flag, name: 'test') }
- let(:scope) { double(:feature_flag_scope, environment_scope: 'prd') }
-
- it_behaves_like 'not found'
- end
- end
-
- describe 'PUT /projects/:id/feature_flags/:name/scopes/:environment_scope' do
- subject do
- put api("/projects/#{project.id}/feature_flags/#{feature_flag.name}/scopes/#{environment_scope}",
- user), params: params
- end
-
- let(:environment_scope) { scope.environment_scope }
-
- let(:params) do
- {
- active: true,
- strategies: [{ name: 'userWithId', parameters: { 'userIds': 'a,b,c' } }].to_json
- }
- end
-
- context 'when there is a corresponding feature flag' do
- let!(:feature_flag) { create(:operations_feature_flag, project: project) }
- let(:scope) { create_scope(feature_flag, 'staging', false, [{ name: "default", parameters: {} }]) }
-
- it_behaves_like 'check user permission'
-
- it 'returns the updated scope' do
- subject
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(response).to match_response_schema('public_api/v4/feature_flag_scope')
- expect(json_response['id']).to eq(scope.id)
- expect(json_response['active']).to eq(params[:active])
- expect(json_response['strategies']).to eq(Gitlab::Json.parse(params[:strategies]))
- end
-
- context 'when there are no corresponding feature flag scopes' do
- let(:scope) { double(:feature_flag_scope, environment_scope: 'prd') }
-
- it_behaves_like 'not found'
- end
- end
-
- context 'when there are no corresponding feature flags' do
- let(:feature_flag) { double(:feature_flag, name: 'test') }
- let(:scope) { double(:feature_flag_scope, environment_scope: 'prd') }
-
- it_behaves_like 'not found'
- end
- end
-
- describe 'DELETE /projects/:id/feature_flags/:name/scopes/:environment_scope' do
- subject do
- delete api("/projects/#{project.id}/feature_flags/#{feature_flag.name}/scopes/#{environment_scope}",
- user)
- end
-
- let(:environment_scope) { scope.environment_scope }
-
- shared_examples_for 'successful response' do
- it 'destroys the scope' do
- expect { subject }
- .to change { Operations::FeatureFlagScope.exists?(environment_scope: scope.environment_scope) }
- .from(true).to(false)
-
- expect(response).to have_gitlab_http_status(:no_content)
- end
- end
-
- context 'when there is a feature flag' do
- let!(:feature_flag) { create(:operations_feature_flag, project: project) }
-
- context 'when there is a targeted scope' do
- let!(:scope) { create_scope(feature_flag, 'production', false) }
-
- it_behaves_like 'check user permission'
- it_behaves_like 'successful response'
-
- context 'when environment scope includes slash' do
- let!(:scope) { create_scope(feature_flag, 'review/*', false) }
-
- it_behaves_like 'not found'
-
- context 'when URL-encoding the environment scope parameter' do
- let(:environment_scope) { CGI.escape(scope.environment_scope) }
-
- it_behaves_like 'successful response'
- end
- end
- end
-
- context 'when there are no targeted scopes' do
- let!(:scope) { double(:feature_flag_scope, environment_scope: 'production') }
-
- it_behaves_like 'not found'
- end
- end
-
- context 'when there are no feature flags' do
- let(:feature_flag) { double(:feature_flag, name: 'test') }
- let(:scope) { double(:feature_flag_scope, environment_scope: 'prd') }
-
- it_behaves_like 'not found'
- end
- end
-end
diff --git a/spec/requests/api/feature_flags_spec.rb b/spec/requests/api/feature_flags_spec.rb
index 923ebefe01f..2cd52c0a5e5 100644
--- a/spec/requests/api/feature_flags_spec.rb
+++ b/spec/requests/api/feature_flags_spec.rb
@@ -62,7 +62,7 @@ RSpec.describe API::FeatureFlags do
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('public_api/v4/feature_flags')
- expect(json_response.map { |f| f['version'] }).to eq(%w[legacy_flag legacy_flag])
+ expect(json_response.map { |f| f['version'] }).to eq(%w[new_version_flag new_version_flag])
end
it 'does not have N+1 problem' do
@@ -145,19 +145,7 @@ RSpec.describe API::FeatureFlags do
expect(response).to match_response_schema('public_api/v4/feature_flag')
expect(json_response['name']).to eq(feature_flag.name)
expect(json_response['description']).to eq(feature_flag.description)
- expect(json_response['version']).to eq('legacy_flag')
- end
-
- context 'without legacy flags' do
- before do
- stub_feature_flags(remove_legacy_flags: true, remove_legacy_flags_override: false)
- end
-
- it 'returns not found' do
- subject
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
+ expect(json_response['version']).to eq('new_version_flag')
end
it_behaves_like 'check user permission'
@@ -465,246 +453,6 @@ RSpec.describe API::FeatureFlags do
end
end
- describe 'POST /projects/:id/feature_flags/:name/enable' do
- subject do
- post api("/projects/#{project.id}/feature_flags/#{params[:name]}/enable", user),
- params: params
- end
-
- let(:params) do
- {
- name: 'awesome-feature',
- environment_scope: 'production',
- strategy: { name: 'userWithId', parameters: { userIds: 'Project:1' } }.to_json
- }
- end
-
- context 'when feature flag does not exist yet' do
- it 'creates a new feature flag with the specified scope and strategy' do
- subject
-
- feature_flag = project.operations_feature_flags.last
- scope = feature_flag.scopes.find_by_environment_scope(params[:environment_scope])
- expect(response).to have_gitlab_http_status(:ok)
- expect(response).to match_response_schema('public_api/v4/feature_flag')
- expect(feature_flag.name).to eq(params[:name])
- expect(scope.strategies).to eq([Gitlab::Json.parse(params[:strategy])])
- expect(feature_flag.version).to eq('legacy_flag')
- end
-
- it 'returns the flag version and strategies in the json response' do
- subject
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(response).to match_response_schema('public_api/v4/feature_flag')
- expect(json_response.slice('version', 'strategies')).to eq({
- 'version' => 'legacy_flag',
- 'strategies' => []
- })
- end
-
- it_behaves_like 'check user permission'
-
- context 'without legacy flags' do
- before do
- stub_feature_flags(remove_legacy_flags: true, remove_legacy_flags_override: false)
- end
-
- it 'returns not found' do
- subject
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
- end
-
- context 'when feature flag exists already' do
- let!(:feature_flag) { create_flag(project, params[:name]) }
-
- context 'when feature flag scope does not exist yet' do
- it 'creates a new scope with the specified strategy' do
- subject
-
- scope = feature_flag.scopes.find_by_environment_scope(params[:environment_scope])
- expect(response).to have_gitlab_http_status(:ok)
- expect(scope.strategies).to eq([Gitlab::Json.parse(params[:strategy])])
- end
-
- it_behaves_like 'check user permission'
- end
-
- context 'when feature flag scope exists already' do
- let(:defined_strategy) { { name: 'userWithId', parameters: { userIds: 'Project:2' } } }
-
- before do
- create_scope(feature_flag, params[:environment_scope], true, [defined_strategy])
- end
-
- it 'adds an additional strategy to the scope' do
- subject
-
- scope = feature_flag.scopes.find_by_environment_scope(params[:environment_scope])
- expect(response).to have_gitlab_http_status(:ok)
- expect(scope.strategies).to eq([defined_strategy.deep_stringify_keys, Gitlab::Json.parse(params[:strategy])])
- end
-
- context 'when the specified strategy exists already' do
- let(:defined_strategy) { Gitlab::Json.parse(params[:strategy]) }
-
- it 'does not add a duplicate strategy' do
- subject
-
- scope = feature_flag.scopes.find_by_environment_scope(params[:environment_scope])
- strategy_count = scope.strategies.count { |strategy| strategy['name'] == 'userWithId' }
- expect(response).to have_gitlab_http_status(:ok)
- expect(strategy_count).to eq(1)
- end
- end
- end
-
- context 'without legacy flags' do
- before do
- stub_feature_flags(remove_legacy_flags: true, remove_legacy_flags_override: false)
- end
-
- it 'returns not found' do
- subject
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
- end
-
- context 'with a version 2 flag' do
- let!(:feature_flag) { create(:operations_feature_flag, :new_version_flag, project: project, name: params[:name]) }
-
- it 'does not change the flag and returns an unprocessable_entity response' do
- subject
-
- expect(response).to have_gitlab_http_status(:unprocessable_entity)
- expect(json_response).to eq({ 'message' => 'Version 2 flags not supported' })
- feature_flag.reload
- expect(feature_flag.scopes).to eq([])
- expect(feature_flag.strategies).to eq([])
- end
- end
- end
-
- describe 'POST /projects/:id/feature_flags/:name/disable' do
- subject do
- post api("/projects/#{project.id}/feature_flags/#{params[:name]}/disable", user),
- params: params
- end
-
- let(:params) do
- {
- name: 'awesome-feature',
- environment_scope: 'production',
- strategy: { name: 'userWithId', parameters: { userIds: 'Project:1' } }.to_json
- }
- end
-
- context 'when feature flag does not exist yet' do
- it_behaves_like 'not found'
- end
-
- context 'when feature flag exists already' do
- let!(:feature_flag) { create_flag(project, params[:name]) }
-
- context 'when feature flag scope does not exist yet' do
- it_behaves_like 'not found'
- end
-
- context 'when feature flag scope exists already and has the specified strategy' do
- let(:defined_strategies) do
- [
- { name: 'userWithId', parameters: { userIds: 'Project:1' } },
- { name: 'userWithId', parameters: { userIds: 'Project:2' } }
- ]
- end
-
- before do
- create_scope(feature_flag, params[:environment_scope], true, defined_strategies)
- end
-
- it 'removes the strategy from the scope' do
- subject
-
- scope = feature_flag.scopes.find_by_environment_scope(params[:environment_scope])
- expect(response).to have_gitlab_http_status(:ok)
- expect(response).to match_response_schema('public_api/v4/feature_flag')
- expect(scope.strategies)
- .to eq([{ name: 'userWithId', parameters: { userIds: 'Project:2' } }.deep_stringify_keys])
- end
-
- it 'returns the flag version and strategies in the json response' do
- subject
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(response).to match_response_schema('public_api/v4/feature_flag')
- expect(json_response.slice('version', 'strategies')).to eq({
- 'version' => 'legacy_flag',
- 'strategies' => []
- })
- end
-
- context 'without legacy flags' do
- before do
- stub_feature_flags(remove_legacy_flags: true, remove_legacy_flags_override: false)
- end
-
- it 'returns not found' do
- subject
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
-
- it_behaves_like 'check user permission'
-
- context 'when strategies become empty array after the removal' do
- let(:defined_strategies) do
- [{ name: 'userWithId', parameters: { userIds: 'Project:1' } }]
- end
-
- it 'destroys the scope' do
- subject
-
- scope = feature_flag.scopes.find_by_environment_scope(params[:environment_scope])
- expect(response).to have_gitlab_http_status(:ok)
- expect(scope).to be_nil
- end
-
- it_behaves_like 'check user permission'
- end
- end
-
- context 'when scope exists already but cannot find the corresponding strategy' do
- let(:defined_strategy) { { name: 'userWithId', parameters: { userIds: 'Project:2' } } }
-
- before do
- create_scope(feature_flag, params[:environment_scope], true, [defined_strategy])
- end
-
- it_behaves_like 'not found'
- end
- end
-
- context 'with a version 2 feature flag' do
- let!(:feature_flag) { create(:operations_feature_flag, :new_version_flag, project: project, name: params[:name]) }
-
- it 'does not change the flag and returns an unprocessable_entity response' do
- subject
-
- expect(response).to have_gitlab_http_status(:unprocessable_entity)
- expect(json_response).to eq({ 'message' => 'Version 2 flags not supported' })
- feature_flag.reload
- expect(feature_flag.scopes).to eq([])
- expect(feature_flag.strategies).to eq([])
- end
- end
- end
-
describe 'PUT /projects/:id/feature_flags/:name' do
context 'with a legacy feature flag' do
let!(:feature_flag) do
@@ -712,13 +460,13 @@ RSpec.describe API::FeatureFlags do
name: 'feature1', description: 'old description')
end
- it 'returns a 422' do
+ it 'returns a 404' do
params = { description: 'new description' }
put api("/projects/#{project.id}/feature_flags/feature1", user), params: params
- expect(response).to have_gitlab_http_status(:unprocessable_entity)
- expect(json_response).to eq({ 'message' => 'PUT operations are not supported for legacy feature flags' })
+ expect(response).to have_gitlab_http_status(:not_found)
+ expect(json_response).to eq({ 'message' => '404 Not Found' })
expect(feature_flag.reload.description).to eq('old description')
end
end
@@ -1024,20 +772,6 @@ RSpec.describe API::FeatureFlags do
expect(feature_flag.reload.strategies.first.scopes.count).to eq(0)
end
end
-
- context 'without legacy flags' do
- before do
- stub_feature_flags(remove_legacy_flags: true, remove_legacy_flags_override: false)
- end
-
- it 'returns not found' do
- params = { description: 'new description' }
-
- put api("/projects/#{project.id}/feature_flags/other_flag_name", user), params: params
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
end
describe 'DELETE /projects/:id/feature_flags/:name' do
@@ -1046,7 +780,7 @@ RSpec.describe API::FeatureFlags do
params: params
end
- let!(:feature_flag) { create(:operations_feature_flag, project: project) }
+ let!(:feature_flag) { create(:operations_feature_flag, :legacy_flag, project: project) }
let(:params) { {} }
it 'destroys the feature flag' do
diff --git a/spec/requests/api/unleash_spec.rb b/spec/requests/api/unleash_spec.rb
index d3d193ba052..9989f8d28bd 100644
--- a/spec/requests/api/unleash_spec.rb
+++ b/spec/requests/api/unleash_spec.rb
@@ -176,34 +176,9 @@ RSpec.describe API::Unleash do
it_behaves_like 'authenticated request'
context 'with version 1 (legacy) feature flags' do
- let(:feature_flag) { create(:operations_feature_flag, project: project, name: 'feature1', active: true, version: 1) }
+ let(:feature_flag) { create(:operations_feature_flag, :legacy_flag, project: project, name: 'feature1', active: true, version: 1) }
- it_behaves_like 'support multiple environments'
-
- context 'with a list of feature flags' do
- let(:headers) { { "UNLEASH-INSTANCEID" => client.token, "UNLEASH-APPNAME" => "production" } }
- let!(:enabled_feature_flag) { create(:operations_feature_flag, project: project, name: 'feature1', active: true, version: 1) }
- let!(:disabled_feature_flag) { create(:operations_feature_flag, project: project, name: 'feature2', active: false, version: 1) }
-
- it 'responds with a list of features' do
- subject
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['version']).to eq(1)
- expect(json_response['features']).not_to be_empty
- expect(json_response['features'].map { |f| f['name'] }.sort).to eq(%w[feature1 feature2])
- expect(json_response['features'].sort_by {|f| f['name'] }.map { |f| f['enabled'] }).to eq([true, false])
- end
-
- it 'matches json schema' do
- subject
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(response).to match_response_schema('unleash/unleash')
- end
- end
-
- it 'returns a feature flag strategy' do
+ it 'does not return a legacy feature flag' do
create(:operations_feature_flag_scope,
feature_flag: feature_flag,
environment_scope: 'sandbox',
@@ -215,81 +190,7 @@ RSpec.describe API::Unleash do
get api(features_url), headers: headers
expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['features'].first['enabled']).to eq(true)
- strategies = json_response['features'].first['strategies']
- expect(strategies).to eq([{
- "name" => "gradualRolloutUserId",
- "parameters" => {
- "percentage" => "50",
- "groupId" => "default"
- }
- }])
- end
-
- it 'returns a default strategy for a scope' do
- create(:operations_feature_flag_scope, feature_flag: feature_flag, environment_scope: 'sandbox', active: true)
- headers = { "UNLEASH-INSTANCEID" => client.token, "UNLEASH-APPNAME" => "sandbox" }
-
- get api(features_url), headers: headers
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['features'].first['enabled']).to eq(true)
- strategies = json_response['features'].first['strategies']
- expect(strategies).to eq([{ "name" => "default", "parameters" => {} }])
- end
-
- it 'returns multiple strategies for a feature flag' do
- create(:operations_feature_flag_scope,
- feature_flag: feature_flag,
- environment_scope: 'staging',
- active: true,
- strategies: [{ name: "userWithId", parameters: { userIds: "max,fred" } },
- { name: "gradualRolloutUserId",
- parameters: { groupId: "default", percentage: "50" } }])
- headers = { "UNLEASH-INSTANCEID" => client.token, "UNLEASH-APPNAME" => "staging" }
-
- get api(features_url), headers: headers
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['features'].first['enabled']).to eq(true)
- strategies = json_response['features'].first['strategies'].sort_by { |s| s['name'] }
- expect(strategies).to eq([{
- "name" => "gradualRolloutUserId",
- "parameters" => {
- "percentage" => "50",
- "groupId" => "default"
- }
- }, {
- "name" => "userWithId",
- "parameters" => {
- "userIds" => "max,fred"
- }
- }])
- end
-
- it 'returns a disabled feature when the flag is disabled' do
- flag = create(:operations_feature_flag, project: project, name: 'test_feature', active: false, version: 1)
- create(:operations_feature_flag_scope, feature_flag: flag, environment_scope: 'production', active: true)
- headers = { "UNLEASH-INSTANCEID" => client.token, "UNLEASH-APPNAME" => "production" }
-
- get api(features_url), headers: headers
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['features'].first['enabled']).to eq(false)
- end
-
- context "with an inactive scope" do
- let!(:scope) { create(:operations_feature_flag_scope, feature_flag: feature_flag, environment_scope: 'production', active: false, strategies: [{ name: "default", parameters: {} }]) }
- let(:headers) { { "UNLEASH-INSTANCEID" => client.token, "UNLEASH-APPNAME" => "production" } }
-
- it 'returns a disabled feature' do
- get api(features_url), headers: headers
-
- expect(response).to have_gitlab_http_status(:ok)
- feature_json = json_response['features'].first
- expect(feature_json['enabled']).to eq(false)
- expect(feature_json['strategies']).to eq([{ 'name' => 'default', 'parameters' => {} }])
- end
+ expect(json_response['features']).to be_empty
end
end
@@ -534,89 +435,6 @@ RSpec.describe API::Unleash do
}])
end
end
-
- context 'when mixing version 1 and version 2 feature flags' do
- it 'returns both types of flags when both match' do
- feature_flag_a = create(:operations_feature_flag, project: project,
- name: 'feature_a', active: true, version: 2)
- strategy = create(:operations_strategy, feature_flag: feature_flag_a,
- name: 'userWithId', parameters: { userIds: 'user8' })
- create(:operations_scope, strategy: strategy, environment_scope: 'staging')
- feature_flag_b = create(:operations_feature_flag, project: project,
- name: 'feature_b', active: true, version: 1)
- create(:operations_feature_flag_scope, feature_flag: feature_flag_b,
- active: true, strategies: [{ name: 'default', parameters: {} }], environment_scope: 'staging')
-
- get api(features_url), headers: { 'UNLEASH-INSTANCEID' => client.token, 'UNLEASH-APPNAME' => 'staging' }
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['features'].sort_by {|f| f['name']}).to eq([{
- 'name' => 'feature_a',
- 'enabled' => true,
- 'strategies' => [{
- 'name' => 'userWithId',
- 'parameters' => { 'userIds' => 'user8' }
- }]
- }, {
- 'name' => 'feature_b',
- 'enabled' => true,
- 'strategies' => [{
- 'name' => 'default',
- 'parameters' => {}
- }]
- }])
- end
-
- it 'returns legacy flags when only legacy flags match' do
- feature_flag_a = create(:operations_feature_flag, project: project,
- name: 'feature_a', active: true, version: 2)
- strategy = create(:operations_strategy, feature_flag: feature_flag_a,
- name: 'userWithId', parameters: { userIds: 'user8' })
- create(:operations_scope, strategy: strategy, environment_scope: 'production')
- feature_flag_b = create(:operations_feature_flag, project: project,
- name: 'feature_b', active: true, version: 1)
- create(:operations_feature_flag_scope, feature_flag: feature_flag_b,
- active: true, strategies: [{ name: 'default', parameters: {} }], environment_scope: 'staging')
-
- get api(features_url), headers: { 'UNLEASH-INSTANCEID' => client.token, 'UNLEASH-APPNAME' => 'staging' }
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['features']).to eq([{
- 'name' => 'feature_b',
- 'enabled' => true,
- 'strategies' => [{
- 'name' => 'default',
- 'parameters' => {}
- }]
- }])
- end
-
- it 'returns new flags when legacy flags are disabled' do
- stub_feature_flags(remove_legacy_flags_override: false, remove_legacy_flags: true)
-
- feature_flag_a = create(:operations_feature_flag, :new_version_flag, project: project,
- name: 'feature_a', active: true)
- strategy = create(:operations_strategy, feature_flag: feature_flag_a,
- name: 'userWithId', parameters: { userIds: 'user8' })
- create(:operations_scope, strategy: strategy, environment_scope: 'staging')
- feature_flag_b = create(:operations_feature_flag, :legacy_flag, project: project,
- name: 'feature_b', active: true)
- create(:operations_feature_flag_scope, feature_flag: feature_flag_b,
- active: true, strategies: [{ name: 'default', parameters: {} }], environment_scope: 'staging')
-
- get api(features_url), headers: { 'UNLEASH-INSTANCEID' => client.token, 'UNLEASH-APPNAME' => 'staging' }
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['features'].sort_by {|f| f['name']}).to eq([{
- 'name' => 'feature_a',
- 'enabled' => true,
- 'strategies' => [{
- 'name' => 'userWithId',
- 'parameters' => { 'userIds' => 'user8' }
- }]
- }])
- end
- end
end
end
diff --git a/spec/serializers/cluster_application_entity_spec.rb b/spec/serializers/cluster_application_entity_spec.rb
index 3941aad540a..1e71e45948c 100644
--- a/spec/serializers/cluster_application_entity_spec.rb
+++ b/spec/serializers/cluster_application_entity_spec.rb
@@ -77,16 +77,5 @@ RSpec.describe ClusterApplicationEntity do
expect(subject[:pages_domain]).to eq(id: pages_domain.id, domain: pages_domain.domain)
end
end
-
- context 'for fluentd application' do
- let(:application) { build(:clusters_applications_fluentd, :installed) }
-
- it 'includes host, port, protocol and log fields' do
- expect(subject[:port]).to eq(514)
- expect(subject[:host]).to eq("example.com")
- expect(subject[:protocol]).to eq("tcp")
- expect(subject[:cilium_log_enabled]).to be true
- end
- end
end
end
diff --git a/spec/services/ci/job_artifacts/create_service_spec.rb b/spec/services/ci/job_artifacts/create_service_spec.rb
index 97c65dc005e..e6d9f208096 100644
--- a/spec/services/ci/job_artifacts/create_service_spec.rb
+++ b/spec/services/ci/job_artifacts/create_service_spec.rb
@@ -203,53 +203,6 @@ RSpec.describe Ci::JobArtifacts::CreateService do
end
end
- context 'when artifact type is cluster_applications' do
- let(:artifacts_file) do
- file_to_upload('spec/fixtures/helm/helm_list_v2_prometheus_missing.json.gz', sha256: artifacts_sha256)
- end
-
- let(:params) do
- {
- 'artifact_type' => 'cluster_applications',
- 'artifact_format' => 'gzip'
- }.with_indifferent_access
- end
-
- it 'calls cluster applications parse service' do
- expect_next_instance_of(Clusters::ParseClusterApplicationsArtifactService) do |service|
- expect(service).to receive(:execute).once.and_call_original
- end
-
- subject
- end
-
- context 'when there is a deployment cluster' do
- let(:user) { project.owner }
-
- before do
- job.update!(user: user)
- end
-
- it 'calls cluster applications parse service with job and job user', :aggregate_failures do
- expect(Clusters::ParseClusterApplicationsArtifactService).to receive(:new).with(job, user).and_call_original
-
- subject
- end
- end
-
- context 'when ci_synchronous_artifact_parsing feature flag is disabled' do
- before do
- stub_feature_flags(ci_synchronous_artifact_parsing: false)
- end
-
- it 'does not call parse service' do
- expect(Clusters::ParseClusterApplicationsArtifactService).not_to receive(:new)
-
- expect(subject[:status]).to eq(:success)
- end
- end
- end
-
shared_examples 'rescues object storage error' do |klass, message, expected_message|
it "handles #{klass}" do
allow_next_instance_of(JobArtifactUploader) do |uploader|
diff --git a/spec/services/clusters/parse_cluster_applications_artifact_service_spec.rb b/spec/services/clusters/parse_cluster_applications_artifact_service_spec.rb
deleted file mode 100644
index 1f6ad218927..00000000000
--- a/spec/services/clusters/parse_cluster_applications_artifact_service_spec.rb
+++ /dev/null
@@ -1,126 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Clusters::ParseClusterApplicationsArtifactService do
- let_it_be(:project) { create(:project) }
- let_it_be(:user) { create(:user) }
-
- before do
- project.add_maintainer(user)
- end
-
- describe 'RELEASE_NAMES' do
- it 'is included in Cluster application names', :aggregate_failures do
- described_class::RELEASE_NAMES.each do |release_name|
- expect(Clusters::Cluster::APPLICATIONS).to include(release_name)
- end
- end
- end
-
- describe '.new' do
- let(:job) { build(:ci_build) }
-
- it 'sets the project and current user', :aggregate_failures do
- service = described_class.new(job, user)
-
- expect(service.project).to eq(job.project)
- expect(service.current_user).to eq(user)
- end
- end
-
- describe '#execute' do
- let_it_be(:cluster, reload: true) { create(:cluster, projects: [project]) }
- let_it_be(:deployment, reload: true) { create(:deployment, cluster: cluster) }
-
- let(:job) { deployment.deployable }
- let(:artifact) { create(:ci_job_artifact, :cluster_applications, job: job) }
-
- it 'calls Gitlab::Kubernetes::Helm::Parsers::ListV2' do
- expect(Gitlab::Kubernetes::Helm::Parsers::ListV2).to receive(:new).and_call_original
-
- result = described_class.new(job, user).execute(artifact)
-
- expect(result[:status]).to eq(:success)
- end
-
- context 'artifact is not of cluster_applications type' do
- let(:artifact) { create(:ci_job_artifact, :archive) }
- let(:job) { artifact.job }
-
- it 'raise ArgumentError' do
- expect do
- described_class.new(job, user).execute(artifact)
- end.to raise_error(ArgumentError, 'Artifact is not cluster_applications file type')
- end
- end
-
- context 'artifact exceeds acceptable size' do
- it 'returns an error' do
- stub_const("#{described_class}::MAX_ACCEPTABLE_ARTIFACT_SIZE", 1.byte)
-
- result = described_class.new(job, user).execute(artifact)
-
- expect(result[:status]).to eq(:error)
- expect(result[:message]).to eq('Cluster_applications artifact too big. Maximum allowable size: 1 Byte')
- end
- end
-
- context 'job has no deployment' do
- let(:job) { build(:ci_build) }
-
- it 'returns an error' do
- result = described_class.new(job, user).execute(artifact)
-
- expect(result[:status]).to eq(:error)
- expect(result[:message]).to eq('No deployment found for this job')
- end
- end
-
- context 'job has no deployment cluster' do
- let(:deployment) { create(:deployment) }
- let(:job) { deployment.deployable }
-
- it 'returns an error' do
- result = described_class.new(job, user).execute(artifact)
-
- expect(result[:status]).to eq(:error)
- expect(result[:message]).to eq('No deployment cluster found for this job')
- end
- end
-
- context 'blob is empty' do
- let(:file) { fixture_file_upload(Rails.root.join("spec/fixtures/helm/helm_list_v2_empty_blob.json.gz")) }
- let(:artifact) { create(:ci_job_artifact, :cluster_applications, job: job, file: file) }
-
- it 'returns success' do
- result = described_class.new(job, user).execute(artifact)
-
- expect(result[:status]).to eq(:success)
- end
- end
-
- context 'job has deployment cluster' do
- context 'current user does not have access to deployment cluster' do
- let(:other_user) { create(:user) }
-
- it 'returns an error' do
- result = described_class.new(job, other_user).execute(artifact)
-
- expect(result[:status]).to eq(:error)
- expect(result[:message]).to eq('No deployment cluster found for this job')
- end
- end
-
- it 'does not affect unpermitted cluster applications' do
- expect(Clusters::ParseClusterApplicationsArtifactService::RELEASE_NAMES).to contain_exactly('cilium')
- end
-
- Clusters::ParseClusterApplicationsArtifactService::RELEASE_NAMES.each do |release_name|
- context release_name do
- include_examples 'parse cluster applications artifact', release_name
- end
- end
- end
- end
-end
diff --git a/spec/services/feature_flags/disable_service_spec.rb b/spec/services/feature_flags/disable_service_spec.rb
deleted file mode 100644
index 4b2137be35c..00000000000
--- a/spec/services/feature_flags/disable_service_spec.rb
+++ /dev/null
@@ -1,92 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe FeatureFlags::DisableService do
- include FeatureFlagHelpers
-
- let_it_be(:project) { create(:project) }
- let_it_be(:user) { create(:user) }
-
- let(:params) { {} }
- let(:service) { described_class.new(project, user, params) }
-
- before_all do
- project.add_developer(user)
- end
-
- describe '#execute' do
- subject { service.execute }
-
- context 'with params to disable default strategy on prd scope' do
- let(:params) do
- {
- name: 'awesome',
- environment_scope: 'prd',
- strategy: { name: 'userWithId', parameters: { 'userIds': 'User:1' } }.deep_stringify_keys
- }
- end
-
- context 'when there is a persisted feature flag' do
- let!(:feature_flag) { create_flag(project, params[:name]) }
-
- context 'when there is a persisted scope' do
- let!(:scope) do
- create_scope(feature_flag, params[:environment_scope], true, strategies)
- end
-
- context 'when there is a persisted strategy' do
- let(:strategies) do
- [
- { name: 'userWithId', parameters: { 'userIds': 'User:1' } }.deep_stringify_keys,
- { name: 'userWithId', parameters: { 'userIds': 'User:2' } }.deep_stringify_keys
- ]
- end
-
- it 'deletes the specified strategy' do
- subject
-
- scope.reload
- expect(scope.strategies.count).to eq(1)
- expect(scope.strategies).not_to include(params[:strategy])
- end
-
- context 'when strategies will be empty' do
- let(:strategies) { [params[:strategy]] }
-
- it 'deletes the persisted scope' do
- subject
-
- expect(feature_flag.scopes.exists?(environment_scope: params[:environment_scope]))
- .to eq(false)
- end
- end
- end
-
- context 'when there is no persisted strategy' do
- let(:strategies) { [{ name: 'default', parameters: {} }] }
-
- it 'returns error' do
- expect(subject[:status]).to eq(:error)
- expect(subject[:message]).to include('Strategy not found')
- end
- end
- end
-
- context 'when there is no persisted scope' do
- it 'returns error' do
- expect(subject[:status]).to eq(:error)
- expect(subject[:message]).to include('Feature Flag Scope not found')
- end
- end
- end
-
- context 'when there is no persisted feature flag' do
- it 'returns error' do
- expect(subject[:status]).to eq(:error)
- expect(subject[:message]).to include('Feature Flag not found')
- end
- end
- end
- end
-end
diff --git a/spec/services/feature_flags/enable_service_spec.rb b/spec/services/feature_flags/enable_service_spec.rb
deleted file mode 100644
index c0008b1933f..00000000000
--- a/spec/services/feature_flags/enable_service_spec.rb
+++ /dev/null
@@ -1,154 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe FeatureFlags::EnableService do
- include FeatureFlagHelpers
-
- let_it_be(:project) { create(:project) }
- let_it_be(:user) { create(:user) }
-
- let(:params) { {} }
- let(:service) { described_class.new(project, user, params) }
-
- before_all do
- project.add_developer(user)
- end
-
- describe '#execute' do
- subject { service.execute }
-
- context 'with params to enable default strategy on prd scope' do
- let(:params) do
- {
- name: 'awesome',
- environment_scope: 'prd',
- strategy: { name: 'default', parameters: {} }.stringify_keys
- }
- end
-
- context 'when there is no persisted feature flag' do
- it 'creates a new feature flag with scope' do
- feature_flag = subject[:feature_flag]
- scope = feature_flag.scopes.find_by_environment_scope(params[:environment_scope])
- expect(subject[:status]).to eq(:success)
- expect(feature_flag.name).to eq(params[:name])
- expect(feature_flag.default_scope).not_to be_active
- expect(scope).to be_active
- expect(scope.strategies).to include(params[:strategy])
- end
-
- context 'when params include default scope' do
- let(:params) do
- {
- name: 'awesome',
- environment_scope: '*',
- strategy: { name: 'userWithId', parameters: { 'userIds': 'abc' } }.deep_stringify_keys
- }
- end
-
- it 'create a new feature flag with an active default scope with the specified strategy' do
- feature_flag = subject[:feature_flag]
- expect(subject[:status]).to eq(:success)
- expect(feature_flag.default_scope).to be_active
- expect(feature_flag.default_scope.strategies).to include(params[:strategy])
- end
- end
- end
-
- context 'when there is a persisted feature flag' do
- let!(:feature_flag) { create_flag(project, params[:name]) }
-
- context 'when there is no persisted scope' do
- it 'creates a new scope for the persisted feature flag' do
- feature_flag = subject[:feature_flag]
- scope = feature_flag.scopes.find_by_environment_scope(params[:environment_scope])
- expect(subject[:status]).to eq(:success)
- expect(feature_flag.name).to eq(params[:name])
- expect(scope).to be_active
- expect(scope.strategies).to include(params[:strategy])
- end
- end
-
- context 'when there is a persisted scope' do
- let!(:feature_flag_scope) do
- create_scope(feature_flag, params[:environment_scope], active, strategies)
- end
-
- let(:active) { true }
-
- context 'when the persisted scope does not have the specified strategy yet' do
- let(:strategies) { [{ name: 'userWithId', parameters: { 'userIds': 'abc' } }] }
-
- it 'adds the specified strategy to the scope' do
- subject
-
- feature_flag_scope.reload
- expect(feature_flag_scope.strategies).to include(params[:strategy])
- end
-
- context 'when the persisted scope is inactive' do
- let(:active) { false }
-
- it 'reactivates the scope' do
- expect { subject }
- .to change { feature_flag_scope.reload.active }.from(false).to(true)
- end
- end
- end
-
- context 'when the persisted scope has the specified strategy already' do
- let(:strategies) { [params[:strategy]] }
-
- it 'does not add a duplicated strategy to the scope' do
- expect { subject }
- .not_to change { feature_flag_scope.reload.strategies.count }
- end
- end
- end
- end
- end
-
- context 'when strategy is not specified in params' do
- let(:params) do
- {
- name: 'awesome',
- environment_scope: 'prd'
- }
- end
-
- it 'returns error' do
- expect(subject[:status]).to eq(:error)
- expect(subject[:message]).to include('Scopes strategies must be an array of strategy hashes')
- end
- end
-
- context 'when environment scope is not specified in params' do
- let(:params) do
- {
- name: 'awesome',
- strategy: { name: 'default', parameters: {} }.stringify_keys
- }
- end
-
- it 'returns error' do
- expect(subject[:status]).to eq(:error)
- expect(subject[:message]).to include("Scopes environment scope can't be blank")
- end
- end
-
- context 'when name is not specified in params' do
- let(:params) do
- {
- environment_scope: 'prd',
- strategy: { name: 'default', parameters: {} }.stringify_keys
- }
- end
-
- it 'returns error' do
- expect(subject[:status]).to eq(:error)
- expect(subject[:message]).to include("Name can't be blank")
- end
- end
- end
-end
diff --git a/spec/services/feature_flags/update_service_spec.rb b/spec/services/feature_flags/update_service_spec.rb
index 1a127a0d472..d838549891a 100644
--- a/spec/services/feature_flags/update_service_spec.rb
+++ b/spec/services/feature_flags/update_service_spec.rb
@@ -121,150 +121,5 @@ RSpec.describe FeatureFlags::UpdateService do
subject
end
end
-
- context 'when scope active state is changed' do
- let(:params) do
- {
- scopes_attributes: [{ id: feature_flag.scopes.first.id, active: false }]
- }
- end
-
- it 'creates audit event about changing active state' do
- expect { subject }.to change { AuditEvent.count }.by(1)
- expect(audit_event_message).to(
- include("Updated rule <strong>*</strong> active state "\
- "from <strong>true</strong> to <strong>false</strong>.")
- )
- end
- end
-
- context 'when scope is renamed' do
- let(:changed_scope) { feature_flag.scopes.create!(environment_scope: 'review', active: true) }
- let(:params) do
- {
- scopes_attributes: [{ id: changed_scope.id, environment_scope: 'staging' }]
- }
- end
-
- it 'creates audit event with changed name' do
- expect { subject }.to change { AuditEvent.count }.by(1)
- expect(audit_event_message).to(
- include("Updated rule <strong>staging</strong> environment scope "\
- "from <strong>review</strong> to <strong>staging</strong>.")
- )
- end
-
- context 'when scope can not be updated' do
- let(:params) do
- {
- scopes_attributes: [{ id: changed_scope.id, environment_scope: '' }]
- }
- end
-
- it 'returns error status' do
- expect(subject[:status]).to eq(:error)
- end
-
- it 'returns error messages' do
- expect(subject[:message]).to include("Scopes environment scope can't be blank")
- end
-
- it 'does not create audit event' do
- expect { subject }.not_to change { AuditEvent.count }
- end
- end
- end
-
- context 'when scope is deleted' do
- let(:deleted_scope) { feature_flag.scopes.create!(environment_scope: 'review', active: true) }
- let(:params) do
- {
- scopes_attributes: [{ id: deleted_scope.id, '_destroy': true }]
- }
- end
-
- it 'creates audit event with deleted scope' do
- expect { subject }.to change { AuditEvent.count }.by(1)
- expect(audit_event_message).to include("Deleted rule <strong>review</strong>.")
- end
-
- context 'when scope can not be deleted' do
- before do
- allow(deleted_scope).to receive(:destroy).and_return(false)
- end
-
- it 'does not create audit event' do
- expect do
- subject
- end.to not_change { AuditEvent.count }.and raise_error(ActiveRecord::RecordNotDestroyed)
- end
- end
- end
-
- context 'when new scope is being added' do
- let(:new_environment_scope) { 'review' }
- let(:params) do
- {
- scopes_attributes: [{ environment_scope: new_environment_scope, active: true }]
- }
- end
-
- it 'creates audit event with new scope' do
- expected = 'Created rule <strong>review</strong> and set it as <strong>active</strong> '\
- 'with strategies <strong>[{"name"=>"default", "parameters"=>{}}]</strong>.'
-
- subject
-
- expect(audit_event_message).to include(expected)
- end
-
- context 'when scope can not be created' do
- let(:new_environment_scope) { '' }
-
- it 'returns error status' do
- expect(subject[:status]).to eq(:error)
- end
-
- it 'returns error messages' do
- expect(subject[:message]).to include("Scopes environment scope can't be blank")
- end
-
- it 'does not create audit event' do
- expect { subject }.not_to change { AuditEvent.count }
- end
- end
- end
-
- context 'when the strategy is changed' do
- let(:scope) do
- create(:operations_feature_flag_scope,
- feature_flag: feature_flag,
- environment_scope: 'sandbox',
- strategies: [{ name: "default", parameters: {} }])
- end
-
- let(:params) do
- {
- scopes_attributes: [{
- id: scope.id,
- environment_scope: 'sandbox',
- strategies: [{
- name: 'gradualRolloutUserId',
- parameters: {
- groupId: 'mygroup',
- percentage: "40"
- }
- }]
- }]
- }
- end
-
- it 'creates an audit event' do
- expected = %r{Updated rule <strong>sandbox</strong> strategies from <strong>.*</strong> to <strong>.*</strong>.}
-
- expect { subject }.to change { AuditEvent.count }.by(1)
- expect(audit_event_message).to match(expected)
- end
- end
end
end
diff --git a/spec/support/helpers/feature_flag_helpers.rb b/spec/support/helpers/feature_flag_helpers.rb
index aef15d81712..af7a674f3bc 100644
--- a/spec/support/helpers/feature_flag_helpers.rb
+++ b/spec/support/helpers/feature_flag_helpers.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module FeatureFlagHelpers
- def create_flag(project, name, active = true, description: nil, version: Operations::FeatureFlag.versions['legacy_flag'])
+ def create_flag(project, name, active = true, description: nil, version: Operations::FeatureFlag.versions['new_version_flag'])
create(:operations_feature_flag, name: name, active: active, version: version,
description: description, project: project)
end
diff --git a/spec/support/helpers/graphql_helpers.rb b/spec/support/helpers/graphql_helpers.rb
index 5dc6945ec5e..4857fa63114 100644
--- a/spec/support/helpers/graphql_helpers.rb
+++ b/spec/support/helpers/graphql_helpers.rb
@@ -1,6 +1,10 @@
# frozen_string_literal: true
module GraphqlHelpers
+ def self.included(base)
+ base.include(::Gitlab::Graphql::Laziness)
+ end
+
MutationDefinition = Struct.new(:query, :variables)
NoData = Class.new(StandardError)
diff --git a/spec/support/shared_examples/services/clusters/parse_cluster_applications_artifact_shared_examples.rb b/spec/support/shared_examples/services/clusters/parse_cluster_applications_artifact_shared_examples.rb
deleted file mode 100644
index 466300017d9..00000000000
--- a/spec/support/shared_examples/services/clusters/parse_cluster_applications_artifact_shared_examples.rb
+++ /dev/null
@@ -1,89 +0,0 @@
-# frozen_string_literal: true
-
-RSpec.shared_examples 'parse cluster applications artifact' do |release_name|
- let(:application_class) { Clusters::Cluster::APPLICATIONS[release_name] }
- let(:cluster_application) { cluster.public_send("application_#{release_name}") }
- let(:file) { fixture_file_upload(Rails.root.join(fixture)) }
- let(:artifact) { create(:ci_job_artifact, :cluster_applications, job: job, file: file) }
-
- context 'release is missing' do
- let(:fixture) { "spec/fixtures/helm/helm_list_v2_#{release_name}_missing.json.gz" }
-
- context 'application does not exist' do
- it 'does not create or destroy an application' do
- expect do
- described_class.new(job, user).execute(artifact)
- end.not_to change(application_class, :count)
- end
- end
-
- context 'application exists' do
- before do
- create("clusters_applications_#{release_name}".to_sym, :installed, cluster: cluster)
- end
-
- it 'marks the application as uninstalled' do
- described_class.new(job, user).execute(artifact)
-
- cluster_application.reload
- expect(cluster_application).to be_uninstalled
- end
- end
- end
-
- context 'release is deployed' do
- let(:fixture) { "spec/fixtures/helm/helm_list_v2_#{release_name}_deployed.json.gz" }
-
- context 'application does not exist' do
- it 'creates an application and marks it as installed' do
- expect do
- described_class.new(job, user).execute(artifact)
- end.to change(application_class, :count)
-
- expect(cluster_application).to be_persisted
- expect(cluster_application).to be_externally_installed
- end
- end
-
- context 'application exists' do
- before do
- create("clusters_applications_#{release_name}".to_sym, :errored, cluster: cluster)
- end
-
- it 'marks the application as installed' do
- described_class.new(job, user).execute(artifact)
-
- expect(cluster_application).to be_externally_installed
- end
- end
- end
-
- context 'release is failed' do
- let(:fixture) { "spec/fixtures/helm/helm_list_v2_#{release_name}_failed.json.gz" }
-
- context 'application does not exist' do
- it 'creates an application and marks it as errored' do
- expect do
- described_class.new(job, user).execute(artifact)
- end.to change(application_class, :count)
-
- expect(cluster_application).to be_persisted
- expect(cluster_application).to be_errored
- expect(cluster_application.status_reason).to eq('Helm release failed to install')
- end
- end
-
- context 'application exists' do
- before do
- create("clusters_applications_#{release_name}".to_sym, :installed, cluster: cluster)
- end
-
- it 'marks the application as errored' do
- described_class.new(job, user).execute(artifact)
-
- expect(cluster_application).to be_errored
- expect(cluster_application.status_reason).to eq('Helm release failed to install')
- end
- end
- end
-end
diff --git a/spec/tooling/danger/project_helper_spec.rb b/spec/tooling/danger/project_helper_spec.rb
index 3275b41ba6e..7474709d255 100644
--- a/spec/tooling/danger/project_helper_spec.rb
+++ b/spec/tooling/danger/project_helper_spec.rb
@@ -112,10 +112,10 @@ RSpec.describe Tooling::Danger::ProjectHelper do
'FOO_VERSION' | [:backend]
'Dangerfile' | [:engineering_productivity]
- 'danger/commit_messages/Dangerfile' | [:engineering_productivity]
- 'ee/danger/commit_messages/Dangerfile' | [:engineering_productivity]
- 'danger/commit_messages/' | [:engineering_productivity]
- 'ee/danger/commit_messages/' | [:engineering_productivity]
+ 'danger/bundle_size/Dangerfile' | [:engineering_productivity]
+ 'ee/danger/bundle_size/Dangerfile' | [:engineering_productivity]
+ 'danger/bundle_size/' | [:engineering_productivity]
+ 'ee/danger/bundle_size/' | [:engineering_productivity]
'.gitlab-ci.yml' | [:engineering_productivity]
'.gitlab/ci/cng.gitlab-ci.yml' | [:engineering_productivity]
'.gitlab/ci/ee-specific-checks.gitlab-ci.yml' | [:engineering_productivity]
@@ -218,7 +218,7 @@ RSpec.describe Tooling::Danger::ProjectHelper do
describe '.local_warning_message' do
it 'returns an informational message with rules that can run' do
- expect(described_class.local_warning_message).to eq('==> Only the following Danger rules can be run locally: changelog, commit_messages, database, datateam, documentation, duplicate_yarn_dependencies, eslint, karma, pajamas, pipeline, prettier, product_intelligence, utility_css')
+ expect(described_class.local_warning_message).to eq('==> Only the following Danger rules can be run locally: changelog, database, datateam, documentation, duplicate_yarn_dependencies, eslint, karma, pajamas, pipeline, prettier, product_intelligence, utility_css')
end
end
diff --git a/tooling/danger/project_helper.rb b/tooling/danger/project_helper.rb
index c0aa27b7a0c..a29dc5e5bed 100644
--- a/tooling/danger/project_helper.rb
+++ b/tooling/danger/project_helper.rb
@@ -5,7 +5,6 @@ module Tooling
module ProjectHelper
LOCAL_RULES ||= %w[
changelog
- commit_messages
database
datateam
documentation
diff --git a/vendor/fluentd/values.yaml b/vendor/fluentd/values.yaml
deleted file mode 100644
index a5072ef14ae..00000000000
--- a/vendor/fluentd/values.yaml
+++ /dev/null
@@ -1,18 +0,0 @@
-plugins:
- enabled: true
- pluginsList: ["fluent-plugin-remote_syslog"]
-
-extraVolumes:
- - name: varlog
- hostPath:
- path: /var/log
- - name: varlibdockercontainers
- hostPath:
- path: /var/lib/docker/containers
-
-extraVolumeMounts:
- - name: varlog
- mountPath: /var/log
- - name: varlibdockercontainers
- mountPath: /var/lib/docker/containers
- readOnly: true
diff --git a/yarn.lock b/yarn.lock
index e5b5c8cc88b..980b8fa5990 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -908,10 +908,10 @@
resolved "https://registry.yarnpkg.com/@gitlab/tributejs/-/tributejs-1.0.0.tgz#672befa222aeffc83e7d799b0500a7a4418e59b8"
integrity sha512-nmKw1+hB6MHvlmPz63yPwVs1qQkycHwsKgxpEbzmky16Y6mL4EJMk3w1b8QlOAF/AIAzjCERPhe/R4MJiohbZw==
-"@gitlab/ui@29.34.0":
- version "29.34.0"
- resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-29.34.0.tgz#c8e9d7411f98537d3153d99b6c614583d4d1285d"
- integrity sha512-ukEHnvd+4f9M+K4b5EArVygUDbS+kUcsP94f6I7Rvd95TR/LlJXwf6vtFdgdBNbk8W98AzW9GwdlT4hmgWfRdw==
+"@gitlab/ui@29.34.1":
+ version "29.34.1"
+ resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-29.34.1.tgz#1dfd6864c0c7b325745f28ec708d1f187df3acd8"
+ integrity sha512-uNS3KNAzDFELq5SkfN7Yg9F8Pc98kcPVaXVhZGvw8JcjyVdLF4AORUbzFBsAtJXOwkWPH8yfBQY7+RVC9wkjGg==
dependencies:
"@babel/standalone" "^7.0.0"
"@gitlab/vue-toasted" "^1.3.0"