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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-04-26 00:09:46 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-04-26 00:09:46 +0300
commit44fb0702f3d2161d286df9b409f4309ed41207df (patch)
tree413f71c07a4ef9d13f17fee357832693e6cb3c48
parentc7531da771f30a54e2220f8f62efeba4b0b1a674 (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--GITLAB_METRICS_EXPORTER_VERSION1
-rw-r--r--app/assets/javascripts/packages_and_registries/dependency_proxy/app.vue6
-rw-r--r--app/assets/javascripts/packages_and_registries/dependency_proxy/components/manifest_row.vue24
-rw-r--r--app/assets/javascripts/packages_and_registries/dependency_proxy/constants.js1
-rw-r--r--app/assets/javascripts/packages_and_registries/dependency_proxy/graphql/queries/get_dependency_proxy_details.query.graphql1
-rw-r--r--app/assets/javascripts/vue_shared/components/registry/list_item.vue1
-rw-r--r--app/controllers/jira_connect/events_controller.rb2
-rw-r--r--app/views/projects/default_branch/_show.html.haml14
-rw-r--r--data/whats_new/202204210001_14_10.yml2
-rw-r--r--db/docs/alert_management_alert_assignees.yml2
-rw-r--r--db/docs/alert_management_alert_user_mentions.yml2
-rw-r--r--db/docs/alert_management_alerts.yml2
-rw-r--r--db/docs/analytics_cycle_analytics_group_value_streams.yml2
-rw-r--r--db/docs/authentication_events.yml2
-rw-r--r--db/docs/background_migration_jobs.yml2
-rw-r--r--db/docs/board_user_preferences.yml2
-rw-r--r--db/docs/boards_epic_user_preferences.yml2
-rw-r--r--db/docs/ci_build_pending_states.yml2
-rw-r--r--db/docs/ci_build_report_results.yml2
-rw-r--r--db/docs/ci_daily_build_group_report_results.yml2
-rw-r--r--db/docs/ci_freeze_periods.yml2
-rw-r--r--db/docs/ci_instance_variables.yml2
-rw-r--r--db/docs/ci_pipeline_artifacts.yml2
-rw-r--r--db/docs/ci_pipeline_messages.yml2
-rw-r--r--db/docs/ci_platform_metrics.yml2
-rw-r--r--db/docs/cluster_agent_tokens.yml2
-rw-r--r--db/docs/cluster_agents.yml2
-rw-r--r--db/docs/clusters_applications_cilium.yml4
-rw-r--r--db/docs/custom_emoji.yml2
-rw-r--r--db/docs/dast_scanner_profiles.yml2
-rw-r--r--db/docs/dast_site_profiles.yml2
-rw-r--r--db/docs/dast_site_tokens.yml2
-rw-r--r--db/docs/dast_site_validations.yml2
-rw-r--r--db/docs/dast_sites.yml2
-rw-r--r--db/docs/diff_note_positions.yml2
-rw-r--r--db/docs/elastic_reindexing_tasks.yml2
-rw-r--r--db/docs/experiment_users.yml2
-rw-r--r--db/docs/experiments.yml4
-rw-r--r--db/docs/group_deploy_keys.yml2
-rw-r--r--db/docs/group_deploy_keys_groups.yml2
-rw-r--r--db/docs/group_wiki_repositories.yml2
-rw-r--r--db/docs/issuable_severities.yml2
-rw-r--r--db/docs/merge_request_diff_details.yml2
-rw-r--r--db/docs/merge_request_reviewers.yml2
-rw-r--r--db/docs/metrics_dashboard_annotations.yml2
-rw-r--r--db/docs/metrics_users_starred_dashboards.yml2
-rw-r--r--db/docs/namespace_limits.yml2
-rw-r--r--db/docs/namespace_settings.yml2
-rw-r--r--db/docs/operations_feature_flags_issues.yml2
-rw-r--r--db/docs/operations_strategies_user_lists.yml2
-rw-r--r--db/docs/operations_user_lists.yml2
-rw-r--r--db/docs/packages_composer_metadata.yml2
-rw-r--r--db/docs/packages_nuget_dependency_link_metadata.yml2
-rw-r--r--db/docs/packages_nuget_metadata.yml2
-rw-r--r--db/docs/packages_pypi_metadata.yml2
-rw-r--r--db/docs/pages_deployments.yml2
-rw-r--r--db/docs/project_access_tokens.yml2
-rw-r--r--db/docs/project_compliance_framework_settings.yml2
-rw-r--r--db/docs/project_repository_storage_moves.yml2
-rw-r--r--db/docs/raw_usage_data.yml2
-rw-r--r--db/docs/resource_iteration_events.yml2
-rw-r--r--db/docs/resource_state_events.yml2
-rw-r--r--db/docs/security_findings.yml2
-rw-r--r--db/docs/snippet_statistics.yml2
-rw-r--r--db/docs/sprints.yml2
-rw-r--r--db/docs/status_page_published_incidents.yml2
-rw-r--r--db/docs/terraform_state_versions.yml2
-rw-r--r--db/docs/terraform_states.yml2
-rw-r--r--db/docs/vulnerability_historical_statistics.yml2
-rw-r--r--db/docs/vulnerability_statistics.yml2
-rw-r--r--db/docs/vulnerability_user_mentions.yml2
-rw-r--r--db/docs/webauthn_registrations.yml2
-rw-r--r--doc/api/projects.md2
-rw-r--r--doc/user/project/repository/gpg_signed_commits/index.md2
-rw-r--r--doc/user/project/repository/push_rules.md112
-rw-r--r--lib/atlassian/jira_connect/asymmetric_jwt.rb68
-rw-r--r--lib/atlassian/jira_connect/jwt/asymmetric.rb80
-rw-r--r--lib/tasks/gitlab/metrics_exporter.rake26
-rw-r--r--locale/gitlab.pot3
-rw-r--r--metrics_server/metrics_server.rb50
-rw-r--r--sidekiq_cluster/cli.rb3
-rw-r--r--spec/commands/metrics_server/metrics_server_spec.rb89
-rw-r--r--spec/commands/sidekiq_cluster/cli_spec.rb20
-rw-r--r--spec/controllers/jira_connect/events_controller_spec.rb4
-rw-r--r--spec/frontend/packages_and_registries/dependency_proxy/components/manifest_row_spec.js66
-rw-r--r--spec/frontend/packages_and_registries/dependency_proxy/mock_data.js14
-rw-r--r--spec/frontend/vue_shared/components/registry/list_item_spec.js14
-rw-r--r--spec/lib/atlassian/jira_connect/jwt/asymmetric_spec.rb (renamed from spec/lib/atlassian/jira_connect/asymmetric_jwt_spec.rb)14
-rw-r--r--spec/lib/tasks/gitlab/metrics_exporter_task_spec.rb81
-rw-r--r--spec/metrics_server/metrics_server_spec.rb114
90 files changed, 617 insertions, 327 deletions
diff --git a/GITLAB_METRICS_EXPORTER_VERSION b/GITLAB_METRICS_EXPORTER_VERSION
new file mode 100644
index 00000000000..ba2906d0666
--- /dev/null
+++ b/GITLAB_METRICS_EXPORTER_VERSION
@@ -0,0 +1 @@
+main
diff --git a/app/assets/javascripts/packages_and_registries/dependency_proxy/app.vue b/app/assets/javascripts/packages_and_registries/dependency_proxy/app.vue
index 67c2ca02d20..5689e0c04f3 100644
--- a/app/assets/javascripts/packages_and_registries/dependency_proxy/app.vue
+++ b/app/assets/javascripts/packages_and_registries/dependency_proxy/app.vue
@@ -102,10 +102,10 @@ export default {
return { fullPath: this.groupPath, first: GRAPHQL_PAGE_SIZE };
},
pageInfo() {
- return this.group.dependencyProxyManifests.pageInfo;
+ return this.group.dependencyProxyManifests?.pageInfo;
},
manifests() {
- return this.group.dependencyProxyManifests.nodes;
+ return this.group.dependencyProxyManifests?.nodes;
},
modalTitleWithCount() {
return sprintf(
@@ -132,7 +132,7 @@ export default {
);
},
showDeleteDropdown() {
- return this.group.dependencyProxyBlobCount > 0;
+ return this.group.dependencyProxyManifests?.nodes.length > 0;
},
},
methods: {
diff --git a/app/assets/javascripts/packages_and_registries/dependency_proxy/components/manifest_row.vue b/app/assets/javascripts/packages_and_registries/dependency_proxy/components/manifest_row.vue
index 78880b6e3f4..1bbd0c32dc4 100644
--- a/app/assets/javascripts/packages_and_registries/dependency_proxy/components/manifest_row.vue
+++ b/app/assets/javascripts/packages_and_registries/dependency_proxy/components/manifest_row.vue
@@ -1,5 +1,6 @@
<script>
-import { GlSprintf } from '@gitlab/ui';
+import { GlIcon, GlSprintf } from '@gitlab/ui';
+import { MANIFEST_PENDING_DESTRUCTION_STATUS } from '~/packages_and_registries/dependency_proxy/constants';
import ListItem from '~/vue_shared/components/registry/list_item.vue';
import TimeagoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import { s__ } from '~/locale';
@@ -7,6 +8,7 @@ import { s__ } from '~/locale';
export default {
name: 'ManifestRow',
components: {
+ GlIcon,
GlSprintf,
ListItem,
TimeagoTooltip,
@@ -24,17 +26,31 @@ export default {
version() {
return this.manifest?.imageName.split(':')[1];
},
+ isErrorStatus() {
+ return this.manifest?.status === MANIFEST_PENDING_DESTRUCTION_STATUS;
+ },
+ disabledRowStyle() {
+ return this.isErrorStatus ? 'gl-font-weight-normal gl-text-gray-500' : '';
+ },
},
i18n: {
cachedAgoMessage: s__('DependencyProxy|Cached %{time}'),
+ scheduledForDeletion: s__('DependencyProxy|Scheduled for deletion'),
},
};
</script>
<template>
- <list-item>
- <template #left-primary> {{ name }} </template>
- <template #left-secondary> {{ version }} </template>
+ <list-item :disabled="isErrorStatus">
+ <template #left-primary>
+ <span :class="disabledRowStyle">{{ name }}</span>
+ </template>
+ <template #left-secondary>
+ {{ version }}
+ <span v-if="isErrorStatus" class="gl-ml-4" data-testid="status"
+ ><gl-icon name="clock" /> {{ $options.i18n.scheduledForDeletion }}</span
+ >
+ </template>
<template #right-primary> &nbsp; </template>
<template #right-secondary>
<timeago-tooltip :time="manifest.createdAt" data-testid="cached-message">
diff --git a/app/assets/javascripts/packages_and_registries/dependency_proxy/constants.js b/app/assets/javascripts/packages_and_registries/dependency_proxy/constants.js
index 3c6ede6fdce..fdad69204ba 100644
--- a/app/assets/javascripts/packages_and_registries/dependency_proxy/constants.js
+++ b/app/assets/javascripts/packages_and_registries/dependency_proxy/constants.js
@@ -1 +1,2 @@
export const GRAPHQL_PAGE_SIZE = 20;
+export const MANIFEST_PENDING_DESTRUCTION_STATUS = 'PENDING_DESTRUCTION';
diff --git a/app/assets/javascripts/packages_and_registries/dependency_proxy/graphql/queries/get_dependency_proxy_details.query.graphql b/app/assets/javascripts/packages_and_registries/dependency_proxy/graphql/queries/get_dependency_proxy_details.query.graphql
index 5c43b10a5e3..c1597625964 100644
--- a/app/assets/javascripts/packages_and_registries/dependency_proxy/graphql/queries/get_dependency_proxy_details.query.graphql
+++ b/app/assets/javascripts/packages_and_registries/dependency_proxy/graphql/queries/get_dependency_proxy_details.query.graphql
@@ -20,6 +20,7 @@ query getDependencyProxyDetails(
id
createdAt
imageName
+ status
}
pageInfo {
...PageInfo
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 6bb321713d5..a8b250f2041 100644
--- a/app/assets/javascripts/vue_shared/components/registry/list_item.vue
+++ b/app/assets/javascripts/vue_shared/components/registry/list_item.vue
@@ -32,7 +32,6 @@ export default {
return {
'gl-border-t-transparent': !this.first && !this.selected,
'gl-border-t-gray-100': this.first && !this.selected,
- 'gl-opacity-5': this.disabled,
'gl-border-b-gray-100': !this.selected,
'gl-bg-blue-50 gl-border-blue-200': this.selected,
};
diff --git a/app/controllers/jira_connect/events_controller.rb b/app/controllers/jira_connect/events_controller.rb
index 3c78f63e069..394fdc9b2f6 100644
--- a/app/controllers/jira_connect/events_controller.rb
+++ b/app/controllers/jira_connect/events_controller.rb
@@ -47,7 +47,7 @@ class JiraConnect::EventsController < JiraConnect::ApplicationController
end
def verify_asymmetric_atlassian_jwt!
- asymmetric_jwt = Atlassian::JiraConnect::AsymmetricJwt.new(auth_token, jwt_verification_claims)
+ asymmetric_jwt = Atlassian::JiraConnect::Jwt::Asymmetric.new(auth_token, jwt_verification_claims)
return head :unauthorized unless asymmetric_jwt.valid?
diff --git a/app/views/projects/default_branch/_show.html.haml b/app/views/projects/default_branch/_show.html.haml
index f9d3af7aa36..2d3d36a9157 100644
--- a/app/views/projects/default_branch/_show.html.haml
+++ b/app/views/projects/default_branch/_show.html.haml
@@ -9,7 +9,7 @@
= _('Set the default branch for this project. All merge requests and commits are made against this branch unless you specify a different one.')
.settings-content
- = form_for @project, remote: true, html: { multipart: true, anchor: 'default-branch-settings' }, authenticity_token: true do |f|
+ = gitlab_ui_form_for @project, remote: true, html: { multipart: true, anchor: 'default-branch-settings' }, authenticity_token: true do |f|
%fieldset
- if @project.empty_repo?
.text-secondary
@@ -20,12 +20,10 @@
= f.select(:default_branch, @project.repository.branch_names, {}, {class: 'select2 select-wide', data: { qa_selector: 'default_branch_dropdown' }})
.form-group
- .form-check
- = f.check_box :autoclose_referenced_issues, class: 'form-check-input'
- = f.label :autoclose_referenced_issues, class: 'form-check-label' do
- %strong= _("Auto-close referenced issues on default branch")
- .form-text.text-muted
- = _("When merge requests and commits in the default branch close, any issues they reference also close.")
- = link_to sprite_icon('question-o'), help_page_path('user/project/issues/managing_issues.md', anchor: 'closing-issues-automatically'), target: '_blank', rel: 'noopener noreferrer'
+ - help_text = _("When merge requests and commits in the default branch close, any issues they reference also close.")
+ - help_icon = link_to sprite_icon('question-o'), help_page_path('user/project/issues/managing_issues.md', anchor: 'closing-issues-automatically'), target: '_blank', rel: 'noopener noreferrer'
+ = f.gitlab_ui_checkbox_component :autoclose_referenced_issues,
+ _("Auto-close referenced issues on default branch"),
+ help_text: (help_text + "&nbsp;" + help_icon).html_safe
= f.submit _('Save changes'), class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' }
diff --git a/data/whats_new/202204210001_14_10.yml b/data/whats_new/202204210001_14_10.yml
index a95e209a422..162738661a2 100644
--- a/data/whats_new/202204210001_14_10.yml
+++ b/data/whats_new/202204210001_14_10.yml
@@ -41,6 +41,6 @@
gitlab-com: true
packages: [Free, Premium, Ultimate]
url: 'https://docs.gitlab.com/ee/ci/runners/runners_scope.html#group-runners'
- image_url: 'https://about.gitlab.com/images/14_10/group-runners-view-new-3.pn'
+ image_url: 'https://about.gitlab.com/images/14_10/group-runners-view-new-3.png'
published_at: 2022-04-22
release: 14.10
diff --git a/db/docs/alert_management_alert_assignees.yml b/db/docs/alert_management_alert_assignees.yml
index 23b81240c11..6b91d6db72c 100644
--- a/db/docs/alert_management_alert_assignees.yml
+++ b/db/docs/alert_management_alert_assignees.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- incident_management
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/32609
milestone: '13.1'
diff --git a/db/docs/alert_management_alert_user_mentions.yml b/db/docs/alert_management_alert_user_mentions.yml
index c834c2a8b12..eda29a17cda 100644
--- a/db/docs/alert_management_alert_user_mentions.yml
+++ b/db/docs/alert_management_alert_user_mentions.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- incident_management
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33217
milestone: '13.1'
diff --git a/db/docs/alert_management_alerts.yml b/db/docs/alert_management_alerts.yml
index 1d5cbf0df23..347653fbb0b 100644
--- a/db/docs/alert_management_alerts.yml
+++ b/db/docs/alert_management_alerts.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- incident_management
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/29864
milestone: '13.0'
diff --git a/db/docs/analytics_cycle_analytics_group_value_streams.yml b/db/docs/analytics_cycle_analytics_group_value_streams.yml
index fdf620c382f..d41ed8168d0 100644
--- a/db/docs/analytics_cycle_analytics_group_value_streams.yml
+++ b/db/docs/analytics_cycle_analytics_group_value_streams.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- value_stream_management
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/36658
milestone: '13.2'
diff --git a/db/docs/authentication_events.yml b/db/docs/authentication_events.yml
index fb76b359854..7eec9124e81 100644
--- a/db/docs/authentication_events.yml
+++ b/db/docs/authentication_events.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- authentication_and_authorization
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/39652
milestone: '13.4'
diff --git a/db/docs/background_migration_jobs.yml b/db/docs/background_migration_jobs.yml
index 09022a7b2be..b0fd5b58d50 100644
--- a/db/docs/background_migration_jobs.yml
+++ b/db/docs/background_migration_jobs.yml
@@ -7,5 +7,5 @@ feature_categories:
description: >-
The background_migration_jobs table stores information about the jobs processed during the execution of a background migration.
See https://docs.gitlab.com/ee/development/database/background_migrations.html for more details.
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35913
milestone: '13.2'
diff --git a/db/docs/board_user_preferences.yml b/db/docs/board_user_preferences.yml
index 209374e9d66..40a5b1c3cb0 100644
--- a/db/docs/board_user_preferences.yml
+++ b/db/docs/board_user_preferences.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- team_planning
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33892
milestone: '13.1'
diff --git a/db/docs/boards_epic_user_preferences.yml b/db/docs/boards_epic_user_preferences.yml
index 3fa841c2703..2cfbaf765ae 100644
--- a/db/docs/boards_epic_user_preferences.yml
+++ b/db/docs/boards_epic_user_preferences.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- team_planning
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/40360
milestone: '13.4'
diff --git a/db/docs/ci_build_pending_states.yml b/db/docs/ci_build_pending_states.yml
index 7f6ce6de4a2..aa9e07d64b5 100644
--- a/db/docs/ci_build_pending_states.yml
+++ b/db/docs/ci_build_pending_states.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- continuous_integration
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/41585
milestone: '13.4'
diff --git a/db/docs/ci_build_report_results.yml b/db/docs/ci_build_report_results.yml
index 101f1b0ce83..42d152221f3 100644
--- a/db/docs/ci_build_report_results.yml
+++ b/db/docs/ci_build_report_results.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- code_testing
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/32991
milestone: '13.1'
diff --git a/db/docs/ci_daily_build_group_report_results.yml b/db/docs/ci_daily_build_group_report_results.yml
index 4b481176b38..8f23ac42bd0 100644
--- a/db/docs/ci_daily_build_group_report_results.yml
+++ b/db/docs/ci_daily_build_group_report_results.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- code_testing
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30387
milestone: '13.0'
diff --git a/db/docs/ci_freeze_periods.yml b/db/docs/ci_freeze_periods.yml
index ed28e4189e9..877e18acd9d 100644
--- a/db/docs/ci_freeze_periods.yml
+++ b/db/docs/ci_freeze_periods.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- continuous_integration
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/29162
milestone: '13.0'
diff --git a/db/docs/ci_instance_variables.yml b/db/docs/ci_instance_variables.yml
index a73a38d2a02..aaac23556d6 100644
--- a/db/docs/ci_instance_variables.yml
+++ b/db/docs/ci_instance_variables.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- pipeline_authoring
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30156
milestone: '13.0'
diff --git a/db/docs/ci_pipeline_artifacts.yml b/db/docs/ci_pipeline_artifacts.yml
index 31aaa42bf0f..753a57c74e2 100644
--- a/db/docs/ci_pipeline_artifacts.yml
+++ b/db/docs/ci_pipeline_artifacts.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- build_artifacts
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37969
milestone: '13.3'
diff --git a/db/docs/ci_pipeline_messages.yml b/db/docs/ci_pipeline_messages.yml
index 9a66ad366b1..ad759f5f7e6 100644
--- a/db/docs/ci_pipeline_messages.yml
+++ b/db/docs/ci_pipeline_messages.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- continuous_integration
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33762
milestone: '13.2'
diff --git a/db/docs/ci_platform_metrics.yml b/db/docs/ci_platform_metrics.yml
index 4d64ed63894..26039b8a7c8 100644
--- a/db/docs/ci_platform_metrics.yml
+++ b/db/docs/ci_platform_metrics.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- continuous_integration
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/40036
milestone: '13.4'
diff --git a/db/docs/cluster_agent_tokens.yml b/db/docs/cluster_agent_tokens.yml
index 9f8827ffe66..0d6265789f1 100644
--- a/db/docs/cluster_agent_tokens.yml
+++ b/db/docs/cluster_agent_tokens.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- kubernetes_management
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33228
milestone: '13.3'
diff --git a/db/docs/cluster_agents.yml b/db/docs/cluster_agents.yml
index adeda8df3e5..6593542dad6 100644
--- a/db/docs/cluster_agents.yml
+++ b/db/docs/cluster_agents.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- kubernetes_management
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33228
milestone: '13.3'
diff --git a/db/docs/clusters_applications_cilium.yml b/db/docs/clusters_applications_cilium.yml
index f91ed18fdbc..97428bcc665 100644
--- a/db/docs/clusters_applications_cilium.yml
+++ b/db/docs/clusters_applications_cilium.yml
@@ -3,7 +3,7 @@ table_name: clusters_applications_cilium
classes:
- Clusters::Applications::Cilium
feature_categories:
-- kubernetes_management
+- container_network_security
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/34601
milestone: '13.2'
diff --git a/db/docs/custom_emoji.yml b/db/docs/custom_emoji.yml
index 1a290153544..e392bd8cf5b 100644
--- a/db/docs/custom_emoji.yml
+++ b/db/docs/custom_emoji.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- team_planning
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/24229
milestone: '13.2'
diff --git a/db/docs/dast_scanner_profiles.yml b/db/docs/dast_scanner_profiles.yml
index 813029bde9a..f71e969e3c9 100644
--- a/db/docs/dast_scanner_profiles.yml
+++ b/db/docs/dast_scanner_profiles.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- dynamic_application_security_testing
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37404
milestone: '13.3'
diff --git a/db/docs/dast_site_profiles.yml b/db/docs/dast_site_profiles.yml
index e2ce0676d8d..b68f5cd2368 100644
--- a/db/docs/dast_site_profiles.yml
+++ b/db/docs/dast_site_profiles.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- dynamic_application_security_testing
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/36659
milestone: '13.2'
diff --git a/db/docs/dast_site_tokens.yml b/db/docs/dast_site_tokens.yml
index ce8af8e6fd1..9891c9742a4 100644
--- a/db/docs/dast_site_tokens.yml
+++ b/db/docs/dast_site_tokens.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- dynamic_application_security_testing
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/41639
milestone: '13.4'
diff --git a/db/docs/dast_site_validations.yml b/db/docs/dast_site_validations.yml
index 9d4a73d1d52..9e14ba276e4 100644
--- a/db/docs/dast_site_validations.yml
+++ b/db/docs/dast_site_validations.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- dynamic_application_security_testing
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/41639
milestone: '13.4'
diff --git a/db/docs/dast_sites.yml b/db/docs/dast_sites.yml
index 6513a66eb8a..8b739997022 100644
--- a/db/docs/dast_sites.yml
+++ b/db/docs/dast_sites.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- dynamic_application_security_testing
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/36659
milestone: '13.2'
diff --git a/db/docs/diff_note_positions.yml b/db/docs/diff_note_positions.yml
index 274c34ed72e..8e8a64861ab 100644
--- a/db/docs/diff_note_positions.yml
+++ b/db/docs/diff_note_positions.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- source_code_management
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28113
milestone: '13.0'
diff --git a/db/docs/elastic_reindexing_tasks.yml b/db/docs/elastic_reindexing_tasks.yml
index 640d57ea4df..049dae71d4c 100644
--- a/db/docs/elastic_reindexing_tasks.yml
+++ b/db/docs/elastic_reindexing_tasks.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- global_search
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/34069
milestone: '13.2'
diff --git a/db/docs/experiment_users.yml b/db/docs/experiment_users.yml
index a136f212a1f..38e6c57a283 100644
--- a/db/docs/experiment_users.yml
+++ b/db/docs/experiment_users.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- experimentation_conversion
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38397
milestone: '13.3'
diff --git a/db/docs/experiments.yml b/db/docs/experiments.yml
index 496c0a7644c..ef2ccfa8d89 100644
--- a/db/docs/experiments.yml
+++ b/db/docs/experiments.yml
@@ -3,7 +3,7 @@ table_name: experiments
classes:
- Experiment
feature_categories:
-- experimentation_expansion
+- experimentation_conversion
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38397
milestone: '13.3'
diff --git a/db/docs/group_deploy_keys.yml b/db/docs/group_deploy_keys.yml
index 1b456703e37..c96b6fd0470 100644
--- a/db/docs/group_deploy_keys.yml
+++ b/db/docs/group_deploy_keys.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- secrets_management
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30886
milestone: '13.1'
diff --git a/db/docs/group_deploy_keys_groups.yml b/db/docs/group_deploy_keys_groups.yml
index e50849a6967..c8c36cc16b4 100644
--- a/db/docs/group_deploy_keys_groups.yml
+++ b/db/docs/group_deploy_keys_groups.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- advanced_deployments
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/32901
milestone: '13.2'
diff --git a/db/docs/group_wiki_repositories.yml b/db/docs/group_wiki_repositories.yml
index 6a5a1976ca3..80f48f2117f 100644
--- a/db/docs/group_wiki_repositories.yml
+++ b/db/docs/group_wiki_repositories.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- wiki
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31121
milestone: '13.0'
diff --git a/db/docs/issuable_severities.yml b/db/docs/issuable_severities.yml
index 9a86931e4c3..56fcc9b3200 100644
--- a/db/docs/issuable_severities.yml
+++ b/db/docs/issuable_severities.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- team_planning
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/40272
milestone: '13.4'
diff --git a/db/docs/merge_request_diff_details.yml b/db/docs/merge_request_diff_details.yml
index 4d48beb4de6..21a3984c160 100644
--- a/db/docs/merge_request_diff_details.yml
+++ b/db/docs/merge_request_diff_details.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- code_review
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/34248
milestone: '13.4'
diff --git a/db/docs/merge_request_reviewers.yml b/db/docs/merge_request_reviewers.yml
index a039a2bba84..ed17649852f 100644
--- a/db/docs/merge_request_reviewers.yml
+++ b/db/docs/merge_request_reviewers.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- code_review
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/40358
milestone: '13.4'
diff --git a/db/docs/metrics_dashboard_annotations.yml b/db/docs/metrics_dashboard_annotations.yml
index e5f03bf4525..a874ef0dfdc 100644
--- a/db/docs/metrics_dashboard_annotations.yml
+++ b/db/docs/metrics_dashboard_annotations.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- metrics
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27583
milestone: '13.0'
diff --git a/db/docs/metrics_users_starred_dashboards.yml b/db/docs/metrics_users_starred_dashboards.yml
index 2d86519455c..903b563d071 100644
--- a/db/docs/metrics_users_starred_dashboards.yml
+++ b/db/docs/metrics_users_starred_dashboards.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- metrics
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/29912
milestone: '13.0'
diff --git a/db/docs/namespace_limits.yml b/db/docs/namespace_limits.yml
index 4b528dcd447..64f3f6cae3b 100644
--- a/db/docs/namespace_limits.yml
+++ b/db/docs/namespace_limits.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- subgroups
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/34746
milestone: '13.2'
diff --git a/db/docs/namespace_settings.yml b/db/docs/namespace_settings.yml
index a452d2473c5..c34003d48f1 100644
--- a/db/docs/namespace_settings.yml
+++ b/db/docs/namespace_settings.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- subgroups
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/36321
milestone: '13.2'
diff --git a/db/docs/operations_feature_flags_issues.yml b/db/docs/operations_feature_flags_issues.yml
index 9b440b5cb41..660c8161a08 100644
--- a/db/docs/operations_feature_flags_issues.yml
+++ b/db/docs/operations_feature_flags_issues.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- feature_flags
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/32876
milestone: '13.1'
diff --git a/db/docs/operations_strategies_user_lists.yml b/db/docs/operations_strategies_user_lists.yml
index 7e283021e43..d56950b877c 100644
--- a/db/docs/operations_strategies_user_lists.yml
+++ b/db/docs/operations_strategies_user_lists.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- feature_flags
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30243
milestone: '13.0'
diff --git a/db/docs/operations_user_lists.yml b/db/docs/operations_user_lists.yml
index 4f1473bd09d..68af1fae839 100644
--- a/db/docs/operations_user_lists.yml
+++ b/db/docs/operations_user_lists.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- feature_flags
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28822
milestone: '13.0'
diff --git a/db/docs/packages_composer_metadata.yml b/db/docs/packages_composer_metadata.yml
index a50143c8b82..c0273d95606 100644
--- a/db/docs/packages_composer_metadata.yml
+++ b/db/docs/packages_composer_metadata.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- package_registry
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30448
milestone: '13.1'
diff --git a/db/docs/packages_nuget_dependency_link_metadata.yml b/db/docs/packages_nuget_dependency_link_metadata.yml
index 12234295a67..43bed206011 100644
--- a/db/docs/packages_nuget_dependency_link_metadata.yml
+++ b/db/docs/packages_nuget_dependency_link_metadata.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- package_registry
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30618
milestone: '13.0'
diff --git a/db/docs/packages_nuget_metadata.yml b/db/docs/packages_nuget_metadata.yml
index 5c4e1203a85..f5dad38d5d7 100644
--- a/db/docs/packages_nuget_metadata.yml
+++ b/db/docs/packages_nuget_metadata.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- package_registry
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30994
milestone: '13.0'
diff --git a/db/docs/packages_pypi_metadata.yml b/db/docs/packages_pypi_metadata.yml
index 4f39a392f65..f3d7c17055a 100644
--- a/db/docs/packages_pypi_metadata.yml
+++ b/db/docs/packages_pypi_metadata.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- package_registry
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27632
milestone: '13.0'
diff --git a/db/docs/pages_deployments.yml b/db/docs/pages_deployments.yml
index 3c96d27c179..2939913b94e 100644
--- a/db/docs/pages_deployments.yml
+++ b/db/docs/pages_deployments.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- pages
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/41785
milestone: '13.4'
diff --git a/db/docs/project_access_tokens.yml b/db/docs/project_access_tokens.yml
index 59b1ad32857..8c53c854b64 100644
--- a/db/docs/project_access_tokens.yml
+++ b/db/docs/project_access_tokens.yml
@@ -4,5 +4,5 @@ classes: []
feature_categories:
- authentication_and_authorization
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33272
milestone: '13.1'
diff --git a/db/docs/project_compliance_framework_settings.yml b/db/docs/project_compliance_framework_settings.yml
index 3d409ca5dd6..bc5555926c1 100644
--- a/db/docs/project_compliance_framework_settings.yml
+++ b/db/docs/project_compliance_framework_settings.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- compliance_management
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28182
milestone: '13.0'
diff --git a/db/docs/project_repository_storage_moves.yml b/db/docs/project_repository_storage_moves.yml
index fe3886a7690..12fa9d33f07 100644
--- a/db/docs/project_repository_storage_moves.yml
+++ b/db/docs/project_repository_storage_moves.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- source_code_management
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/29095
milestone: '13.0'
diff --git a/db/docs/raw_usage_data.yml b/db/docs/raw_usage_data.yml
index 36dfbd7742a..c7e194d6417 100644
--- a/db/docs/raw_usage_data.yml
+++ b/db/docs/raw_usage_data.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- metrics
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38457
milestone: '13.3'
diff --git a/db/docs/resource_iteration_events.yml b/db/docs/resource_iteration_events.yml
index 96be1471854..0d5c90e50f9 100644
--- a/db/docs/resource_iteration_events.yml
+++ b/db/docs/resource_iteration_events.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- planning_analytics
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37617
milestone: '13.3'
diff --git a/db/docs/resource_state_events.yml b/db/docs/resource_state_events.yml
index c5bd88c7927..dd036acf8d2 100644
--- a/db/docs/resource_state_events.yml
+++ b/db/docs/resource_state_events.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- team_planning
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28926
milestone: '13.0'
diff --git a/db/docs/security_findings.yml b/db/docs/security_findings.yml
index 57a5d18c288..e7c30e4f791 100644
--- a/db/docs/security_findings.yml
+++ b/db/docs/security_findings.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- vulnerability_management
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/40368
milestone: '13.4'
diff --git a/db/docs/snippet_statistics.yml b/db/docs/snippet_statistics.yml
index 4e9de04a918..d6c77e5c235 100644
--- a/db/docs/snippet_statistics.yml
+++ b/db/docs/snippet_statistics.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- snippets
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35026
milestone: '13.2'
diff --git a/db/docs/sprints.yml b/db/docs/sprints.yml
index f330c47484f..0ee8503b41b 100644
--- a/db/docs/sprints.yml
+++ b/db/docs/sprints.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- team_planning
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30125
milestone: '13.0'
diff --git a/db/docs/status_page_published_incidents.yml b/db/docs/status_page_published_incidents.yml
index 79d46ba2ad4..562e8eb2f80 100644
--- a/db/docs/status_page_published_incidents.yml
+++ b/db/docs/status_page_published_incidents.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- incident_management
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/29994
milestone: '13.0'
diff --git a/db/docs/terraform_state_versions.yml b/db/docs/terraform_state_versions.yml
index 8c1110caa95..a812d2a209e 100644
--- a/db/docs/terraform_state_versions.yml
+++ b/db/docs/terraform_state_versions.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- infrastructure_as_code
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35211
milestone: '13.4'
diff --git a/db/docs/terraform_states.yml b/db/docs/terraform_states.yml
index 90be304d898..78a277cafd6 100644
--- a/db/docs/terraform_states.yml
+++ b/db/docs/terraform_states.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- infrastructure_as_code
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/26619
milestone: '13.0'
diff --git a/db/docs/vulnerability_historical_statistics.yml b/db/docs/vulnerability_historical_statistics.yml
index 47fec93a242..38cd2029438 100644
--- a/db/docs/vulnerability_historical_statistics.yml
+++ b/db/docs/vulnerability_historical_statistics.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- vulnerability_management
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/36955
milestone: '13.3'
diff --git a/db/docs/vulnerability_statistics.yml b/db/docs/vulnerability_statistics.yml
index e32fdc907ff..6b82d1cb257 100644
--- a/db/docs/vulnerability_statistics.yml
+++ b/db/docs/vulnerability_statistics.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- vulnerability_management
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/34289
milestone: '13.2'
diff --git a/db/docs/vulnerability_user_mentions.yml b/db/docs/vulnerability_user_mentions.yml
index 594f7fa78f8..94484cfbf06 100644
--- a/db/docs/vulnerability_user_mentions.yml
+++ b/db/docs/vulnerability_user_mentions.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- vulnerability_management
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27515
milestone: '13.0'
diff --git a/db/docs/webauthn_registrations.yml b/db/docs/webauthn_registrations.yml
index 21659b88cb6..13c4c28e24b 100644
--- a/db/docs/webauthn_registrations.yml
+++ b/db/docs/webauthn_registrations.yml
@@ -5,5 +5,5 @@ classes:
feature_categories:
- authentication_and_authorization
description: TODO
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35797
milestone: '13.2'
diff --git a/doc/api/projects.md b/doc/api/projects.md
index 0d39fdd3aa7..34fb80beb1d 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -2537,7 +2537,7 @@ POST /projects/:id/housekeeping
### Get project push rules
-Get the [push rules](../user/project/repository/push_rules.md#enabling-push-rules) of a
+Get the [push rules](../user/project/repository/push_rules.md) of a
project.
```plaintext
diff --git a/doc/user/project/repository/gpg_signed_commits/index.md b/doc/user/project/repository/gpg_signed_commits/index.md
index 00998c9a227..b2a6c8848ce 100644
--- a/doc/user/project/repository/gpg_signed_commits/index.md
+++ b/doc/user/project/repository/gpg_signed_commits/index.md
@@ -11,7 +11,7 @@ GPG ([GNU Privacy Guard](https://gnupg.org/)) key. When you add a cryptographic
signature to your commit, you provide extra assurance that a commit
originated from you, rather than an impersonator. If GitLab can verify a commit
author's identity with a public GPG key, the commit is marked **Verified** in the
-GitLab UI. You can then configure [push rules](../push_rules.md#enabling-push-rules)
+GitLab UI. You can then configure [push rules](../push_rules.md)
for your project to reject individual commits not signed with GPG, or reject all
commits from unverified users.
diff --git a/doc/user/project/repository/push_rules.md b/doc/user/project/repository/push_rules.md
index 6918490c404..bacf55f9535 100644
--- a/doc/user/project/repository/push_rules.md
+++ b/doc/user/project/repository/push_rules.md
@@ -28,7 +28,9 @@ The following options are available:
by the same user as the user who pushed it, or where the committer's email address
is not [confirmed](../../../security/user_email_confirmation.md).
- **Reject unsigned commits** - Reject commit when it is not signed through GPG.
- Read [signing commits with GPG](gpg_signed_commits/index.md).
+ Read [signing commits with GPG](gpg_signed_commits/index.md). This push rule
+ can block some legitimate commits [created in the Web IDE](#reject-unsigned-commits-push-rule-disables-web-ide),
+ and allow [unsigned commits created in the GitLab UI](#unsigned-commits-created-in-the-gitlab-ui).
- **Removal of tags with** `git push` - Forbid users to remove Git tags with `git push`.
Tags can be deleted through the web UI.
- **Check whether the commit author is a GitLab user** - Restrict commits to existing
@@ -45,7 +47,8 @@ These push rules require you to create a regular expression for the rule to eval
this regular expression can be pushed. To allow any commit message, leave empty.
Uses multiline mode, which can be disabled using `(?-m)`.
- **Restrict by branch name** - Only branch names that match this regular expression
- can be pushed. To allow any branch name, leave empty.
+ can be pushed. To allow any branch name, leave empty. For more information, read
+ [Restrict branch names](#restrict-branch-names).
- **Restrict by commit author's email** - Only the commit author's email address that matches this
regular expression can be pushed. Checks both the commit author and committer.
To allow any email address, leave empty.
@@ -64,7 +67,7 @@ in push rules, and you can test them at the [regex101 regex tester](https://rege
It's possible to create custom push rules rather than the push rules available in
**Admin Area > Push Rules** by using more advanced server hooks.
-See [server hooks](../../../administration/server_hooks.md) for more information.
+Refer to [server hooks](../../../administration/server_hooks.md) for more information.
## Use cases
@@ -86,7 +89,11 @@ is accepted.
### Restrict branch names
-If your company has a strict policy for branch names, you may want the branches to start
+> Default restricted branch names were introduced in GitLab 12.10.
+
+By default, GitLab restricts certain formats of branch names for security purposes.
+40-character hexadecimal names, similar to Git commit hashes, are prohibited.
+If your company has a stricter policy for branch names, you may want the branches to start
with a certain name. This approach enables different
GitLab CI/CD jobs (such as `feature`, `hotfix`, `docker`, `android`) that rely on the
branch name.
@@ -96,11 +103,11 @@ various branches, and CI pipelines might not work as expected. By restricting th
branch names globally in Push Rules, such mistakes are prevented.
All branch names that don't match your push rule are rejected.
-Note that the name of your default branch is always allowed, regardless of the branch naming
+NOTE:
+The name of your default branch is always allowed, regardless of the branch naming
regular expression (regex) specified. GitLab is configured this way
because merges typically have the default branch as their target.
-If you have other target branches, include them in your regex. (See [Enabling push rules](#enabling-push-rules)).
-
+If you have other target branches, include them in your regex. (See [Enabling push rules](#enable-global-push-rules)).
The default branch also defaults to being a [protected branch](../protected_branches.md),
which already limits users from pushing directly.
@@ -111,14 +118,7 @@ Some example regular expressions you can use in push rules:
- `^[a-z0-9\\-]{4,15}$` Branches must be between `4` and `15` characters long,
accepting only lowercase letters, numbers and dashes.
-#### Default restricted branch names
-
-> Introduced in GitLab 12.10.
-
-By default, GitLab restricts certain formats of branch names for security purposes.
-40-character hexadecimal names, similar to Git commit hashes, are prohibited.
-
-## Enabling push rules
+## Enable global push rules
You can create push rules for all new projects to inherit, but they can be overridden
at the project level or the [group level](../../group/index.md#group-push-rules).
@@ -127,8 +127,14 @@ To create global push rules:
1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Push Rules**.
+1. Expand **Push rules**.
+1. Set the rule you want.
+1. Select **Save push rules**.
-To override global push rules in a project's settings:
+## Override global push rules per project
+
+The push rule of an individual project overrides the global push rule.
+To override global push rules for a specific project:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Settings > Repository**.
@@ -136,28 +142,6 @@ To override global push rules in a project's settings:
1. Set the rule you want.
1. Select **Save push rules**.
-### Caveat to "Reject unsigned commits" push rule
-
-This push rule ignores commits that are authenticated and created by GitLab
-(either through the UI or API). When the **Reject unsigned commits** push rule is
-enabled, unsigned commits may still show up in the commit history if a commit was
-created **in** GitLab itself. As expected, commits created outside GitLab and
-pushed to the repository are rejected. For more information about how GitLab
-plans to fix this issue, read [issue #19185](https://gitlab.com/gitlab-org/gitlab/-/issues/19185).
-
-#### "Reject unsigned commits" push rule disables Web IDE
-
-In 13.10, if a project has the "Reject unsigned commits" push rule, the user is not allowed to
-commit through GitLab Web IDE.
-
-To allow committing through the Web IDE on a project with this push rule, a GitLab administrator
-must disable the feature flag `reject_unsigned_commits_by_gitlab`. This can be done through a
-[rails console](../../../administration/operations/rails_console.md) and running:
-
-```ruby
-Feature.disable(:reject_unsigned_commits_by_gitlab)
-```
-
## Prevent pushing secrets to the repository
> Moved to GitLab Premium in 13.9.
@@ -231,28 +215,6 @@ Files blocked by this rule are listed below. For a complete list of criteria, se
- `*.history`
- `*_history`
-### Prevent pushing secrets to all projects
-
-To set a global push rule to prevent pushing secrets to all projects:
-
-1. On the top bar, select **Menu > Admin**.
-1. On the left sidebar, select **Push Rules**.
-1. Expand **Push rules**.
-1. Select **Prevent pushing secret files**.
-1. Select **Save push rules**.
-
-### Prevent pushing secrets to a project
-
-The push rule of a project overrides the global push rule.
-
-To prevent pushing secrets to a project:
-
-1. On the top bar, select **Menu > Projects** and find your project.
-1. On the left sidebar, select **Settings > Repository**.
-1. Expand **Push rules**.
-1. Select **Prevent pushing secret files**.
-1. Select **Save push rules**.
-
## Prohibited file names
> Moved to GitLab Premium in 13.9.
@@ -295,14 +257,26 @@ end of the grouped collection of match conditions where it is appended to all ma
(\.exe|^config\.yml|^directory-name\/config\.yml|(^|\/)install\.exe)$
```
-<!-- ## Troubleshooting
+## Troubleshooting
-Include any troubleshooting steps that you can foresee. If you know beforehand what issues
-one might have when setting this up, or when something is changed, or on upgrading, it's
-important to describe those, too. Think of things that may go wrong and include them here.
-This is important to minimize requests for support, and to avoid doc comments with
-questions that you know someone might ask.
+### Reject unsigned commits push rule disables Web IDE
-Each scenario can be a third-level heading, e.g. `### Getting error message X`.
-If you have none to add when creating a doc, leave this section in place
-but commented out to help encourage others to add to it in the future. -->
+In 13.10, if a project has the **Reject unsigned commits** push rule, the user is not allowed to
+commit through GitLab Web IDE.
+
+To allow committing through the Web IDE on a project with this push rule, a GitLab administrator
+must disable the feature flag `reject_unsigned_commits_by_gitlab`. This can be done through a
+[rails console](../../../administration/operations/rails_console.md) and running:
+
+```ruby
+Feature.disable(:reject_unsigned_commits_by_gitlab)
+```
+
+### Unsigned commits created in the GitLab UI
+
+This push rule ignores commits that are authenticated and created by GitLab
+(either through the UI or API). When the **Reject unsigned commits** push rule is
+enabled, unsigned commits may still show up in the commit history if a commit was
+created **in** GitLab itself. As expected, commits created outside GitLab and
+pushed to the repository are rejected. For more information about this issue,
+read [issue #19185](https://gitlab.com/gitlab-org/gitlab/-/issues/19185).
diff --git a/lib/atlassian/jira_connect/asymmetric_jwt.rb b/lib/atlassian/jira_connect/asymmetric_jwt.rb
deleted file mode 100644
index a5668701965..00000000000
--- a/lib/atlassian/jira_connect/asymmetric_jwt.rb
+++ /dev/null
@@ -1,68 +0,0 @@
-# frozen_string_literal: true
-
-module Atlassian
- module JiraConnect
- # See documentation about Atlassian asymmetric JWT verification:
- # https://developer.atlassian.com/cloud/jira/platform/understanding-jwt-for-connect-apps/#verifying-a-asymmetric-jwt-token-for-install-callbacks
-
- class AsymmetricJwt
- include Gitlab::Utils::StrongMemoize
-
- KeyFetchError = Class.new(StandardError)
-
- ALGORITHM = 'RS256'
- PUBLIC_KEY_CDN_URL = 'https://connect-install-keys.atlassian.com/'
- UUID4_REGEX = /\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/.freeze
-
- def initialize(token, verification_claims)
- @token = token
- @verification_claims = verification_claims
- end
-
- def valid?
- claims.present? && claims['qsh'] == verification_qsh
- end
-
- def iss_claim
- return unless claims
-
- claims['iss']
- end
-
- private
-
- def claims
- strong_memoize(:claims) do
- _, jwt_headers = decode_token
- public_key = retrieve_public_key(jwt_headers['kid'])
- decoded_claims, _ = decode_token(public_key, true, **relevant_claims, verify_aud: true, verify_iss: true, algorithm: ALGORITHM)
-
- decoded_claims
- rescue JWT::DecodeError, OpenSSL::PKey::PKeyError, KeyFetchError
- end
- end
-
- def decode_token(key = nil, verify = false, **claims)
- Atlassian::Jwt.decode(@token, key, verify, **claims)
- end
-
- def retrieve_public_key(key_id)
- raise KeyFetchError unless UUID4_REGEX.match?(key_id)
-
- public_key = Gitlab::HTTP.try_get(PUBLIC_KEY_CDN_URL + key_id).try(:body)
-
- raise KeyFetchError if public_key.blank?
-
- OpenSSL::PKey.read(public_key)
- end
-
- def relevant_claims
- @verification_claims.slice(:aud, :iss)
- end
-
- def verification_qsh
- @verification_claims[:qsh]
- end
- end
- end
-end
diff --git a/lib/atlassian/jira_connect/jwt/asymmetric.rb b/lib/atlassian/jira_connect/jwt/asymmetric.rb
new file mode 100644
index 00000000000..0611a17c005
--- /dev/null
+++ b/lib/atlassian/jira_connect/jwt/asymmetric.rb
@@ -0,0 +1,80 @@
+# frozen_string_literal: true
+
+module Atlassian
+ module JiraConnect
+ module Jwt
+ # See documentation about Atlassian asymmetric JWT verification:
+ # https://developer.atlassian.com/cloud/jira/platform/understanding-jwt-for-connect-apps/#verifying-a-asymmetric-jwt-token-for-install-callbacks
+
+ class Asymmetric
+ include Gitlab::Utils::StrongMemoize
+
+ KeyFetchError = Class.new(StandardError)
+
+ ALGORITHM = 'RS256'
+ PUBLIC_KEY_CDN_URL = 'https://connect-install-keys.atlassian.com/'
+ UUID4_REGEX = /\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/.freeze
+
+ def initialize(token, verification_claims)
+ @token = token
+ @verification_claims = verification_claims
+ end
+
+ def valid?
+ claims.present? && claims['qsh'] == verification_qsh
+ end
+
+ def iss_claim
+ return unless claims
+
+ claims['iss']
+ end
+
+ private
+
+ def claims
+ strong_memoize(:claims) do
+ _, jwt_headers = decode_token
+ public_key = retrieve_public_key(jwt_headers['kid'])
+
+ decoded_claims(public_key)
+ rescue JWT::DecodeError, OpenSSL::PKey::PKeyError, KeyFetchError
+ end
+ end
+
+ def decoded_claims(public_key)
+ decode_token(
+ public_key,
+ true,
+ **relevant_claims,
+ verify_aud: true,
+ verify_iss: true,
+ algorithm: ALGORITHM
+ ).first
+ end
+
+ def decode_token(key = nil, verify = false, **claims)
+ Atlassian::Jwt.decode(@token, key, verify, **claims)
+ end
+
+ def retrieve_public_key(key_id)
+ raise KeyFetchError unless UUID4_REGEX.match?(key_id)
+
+ public_key = Gitlab::HTTP.try_get(PUBLIC_KEY_CDN_URL + key_id).try(:body)
+
+ raise KeyFetchError if public_key.blank?
+
+ OpenSSL::PKey.read(public_key)
+ end
+
+ def relevant_claims
+ @verification_claims.slice(:aud, :iss)
+ end
+
+ def verification_qsh
+ @verification_claims[:qsh]
+ end
+ end
+ end
+ end
+end
diff --git a/lib/tasks/gitlab/metrics_exporter.rake b/lib/tasks/gitlab/metrics_exporter.rake
new file mode 100644
index 00000000000..d9dd80b8eeb
--- /dev/null
+++ b/lib/tasks/gitlab/metrics_exporter.rake
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+require_relative Rails.root.join('metrics_server', 'dependencies')
+require_relative Rails.root.join('metrics_server', 'metrics_server')
+
+namespace :gitlab do
+ namespace :metrics_exporter do
+ REPO = 'https://gitlab.com/gitlab-org/gitlab-metrics-exporter.git'
+
+ desc "GitLab | Metrics Exporter | Install or upgrade gitlab-metrics-exporter"
+ task :install, [:dir] => :gitlab_environment do |t, args|
+ unless args.dir.present?
+ abort %(Please specify the directory where you want to install the exporter
+Usage: rake "gitlab:metrics_exporter:install[/installation/dir]")
+ end
+
+ version = ENV['GITLAB_METRICS_EXPORTER_VERSION'] || MetricsServer.version
+ make = Gitlab::Utils.which('gmake') || Gitlab::Utils.which('make')
+
+ abort "Couldn't find a 'make' binary" unless make
+
+ checkout_or_clone_version(version: version, repo: REPO, target_dir: args.dir, clone_opts: %w[--depth 1])
+
+ Dir.chdir(args.dir) { run_command!([make]) }
+ end
+ end
+end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index a6623c3f468..9a74540c087 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -12270,6 +12270,9 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
+msgid "DependencyProxy|Scheduled for deletion"
+msgstr ""
+
msgid "DependencyProxy|Storage settings"
msgstr ""
diff --git a/metrics_server/metrics_server.rb b/metrics_server/metrics_server.rb
index 695f3a65930..7bc48ed1ff8 100644
--- a/metrics_server/metrics_server.rb
+++ b/metrics_server/metrics_server.rb
@@ -7,6 +7,10 @@ class MetricsServer # rubocop:disable Gitlab/NamespacedClass
PumaProcessSupervisor = Class.new(Gitlab::ProcessSupervisor)
class << self
+ def version
+ Rails.root.join('GITLAB_METRICS_EXPORTER_VERSION').read.chomp
+ end
+
def start_for_puma
metrics_dir = ::Prometheus::Client.configuration.multiprocess_files_dir
@@ -25,15 +29,41 @@ class MetricsServer # rubocop:disable Gitlab/NamespacedClass
end
end
- def spawn(target, metrics_dir:, gitlab_config: nil, wipe_metrics_dir: false)
+ def start_for_sidekiq(**options)
+ if new_metrics_server?
+ self.spawn('sidekiq', **options)
+ else
+ self.fork('sidekiq', **options)
+ end
+ end
+
+ def spawn(target, metrics_dir:, **options)
+ return spawn_ruby_server(target, metrics_dir: metrics_dir, **options) unless new_metrics_server?
+
+ settings = settings_for(target)
+ path = options[:path]&.then { |p| Pathname.new(p) } || Pathname.new('')
+ cmd = path.join('gitlab-metrics-exporter').to_path
+ env = {
+ 'GME_MMAP_METRICS_DIR' => metrics_dir.to_s,
+ 'GME_PROBES' => 'self,mmap',
+ 'GME_SERVER_HOST' => settings['address'],
+ 'GME_SERVER_PORT' => settings['port'].to_s
+ }
+
+ Process.spawn(env, cmd, err: $stderr, out: $stdout, pgroup: true).tap do |pid|
+ Process.detach(pid)
+ end
+ end
+
+ def spawn_ruby_server(target, metrics_dir:, wipe_metrics_dir: false, **options)
ensure_valid_target!(target)
cmd = "#{Rails.root}/bin/metrics-server"
env = {
'METRICS_SERVER_TARGET' => target,
- 'WIPE_METRICS_DIR' => wipe_metrics_dir ? '1' : '0'
+ 'WIPE_METRICS_DIR' => wipe_metrics_dir ? '1' : '0',
+ 'GITLAB_CONFIG' => ENV['GITLAB_CONFIG']
}
- env['GITLAB_CONFIG'] = gitlab_config if gitlab_config
Process.spawn(env, cmd, err: $stderr, out: $stdout, pgroup: true).tap do |pid|
Process.detach(pid)
@@ -66,9 +96,23 @@ class MetricsServer # rubocop:disable Gitlab/NamespacedClass
private
+ def new_metrics_server?
+ Gitlab::Utils.to_boolean(ENV['GITLAB_GOLANG_METRICS_SERVER'])
+ end
+
def ensure_valid_target!(target)
raise "Target must be one of [puma,sidekiq]" unless %w(puma sidekiq).include?(target)
end
+
+ def settings_for(target)
+ settings_key =
+ case target
+ when 'puma' then 'web_exporter'
+ when 'sidekiq' then 'sidekiq_exporter'
+ else ensure_valid_target!(target)
+ end
+ ::Settings.monitoring[settings_key]
+ end
end
def initialize(target, metrics_dir, wipe_metrics_dir)
diff --git a/sidekiq_cluster/cli.rb b/sidekiq_cluster/cli.rb
index c0940370d3b..4f02812d2e2 100644
--- a/sidekiq_cluster/cli.rb
+++ b/sidekiq_cluster/cli.rb
@@ -164,8 +164,7 @@ module Gitlab
def restart_metrics_server
@logger.info("Starting metrics server on port #{sidekiq_exporter_port}")
- MetricsServer.fork(
- 'sidekiq',
+ MetricsServer.start_for_sidekiq(
metrics_dir: @metrics_dir,
reset_signals: TERMINATE_SIGNALS + FORWARD_SIGNALS
)
diff --git a/spec/commands/metrics_server/metrics_server_spec.rb b/spec/commands/metrics_server/metrics_server_spec.rb
index 217aa185767..f93be1d9f88 100644
--- a/spec/commands/metrics_server/metrics_server_spec.rb
+++ b/spec/commands/metrics_server/metrics_server_spec.rb
@@ -1,44 +1,83 @@
# frozen_string_literal: true
require 'spec_helper'
+require 'rake_helper'
require_relative '../../../metrics_server/metrics_server'
# End-to-end tests for the metrics server process we use to serve metrics
# from forking applications (Sidekiq, Puma) to the Prometheus scraper.
-RSpec.describe 'bin/metrics-server', :aggregate_failures do
+RSpec.describe 'GitLab metrics server', :aggregate_failures do
let(:config_file) { Tempfile.new('gitlab.yml') }
+ let(:address) { '127.0.0.1' }
+ let(:port) { 3807 }
let(:config) do
{
'test' => {
'monitoring' => {
'web_exporter' => {
- 'address' => 'localhost',
+ 'address' => address,
'enabled' => true,
- 'port' => 3807
+ 'port' => port
},
'sidekiq_exporter' => {
- 'address' => 'localhost',
+ 'address' => address,
'enabled' => true,
- 'port' => 3807
+ 'port' => port
}
}
}
}
end
- %w(puma sidekiq).each do |target|
- context "with a running server targeting #{target}" do
+ before(:all) do
+ Rake.application.rake_require 'tasks/gitlab/metrics_exporter'
+
+ @exporter_path = Rails.root.join('tmp', 'test', 'gme')
+
+ run_rake_task('gitlab:metrics_exporter:install', @exporter_path)
+ end
+
+ after(:all) do
+ FileUtils.rm_rf(@exporter_path)
+ end
+
+ shared_examples 'serves metrics endpoint' do
+ it 'serves /metrics endpoint' do
+ start_server!
+
+ expect do
+ Timeout.timeout(10) do
+ http_ok = false
+ until http_ok
+ sleep 1
+ response = Gitlab::HTTP.try_get("http://#{address}:#{port}/metrics", allow_local_requests: true)
+ http_ok = response&.success?
+ end
+ end
+ end.not_to raise_error
+ end
+ end
+
+ shared_examples 'spawns a server' do |target, use_golang_server|
+ context "targeting #{target} when using Golang server is #{use_golang_server}" do
let(:metrics_dir) { Dir.mktmpdir }
+ subject(:start_server!) do
+ @pid = MetricsServer.spawn(target, metrics_dir: metrics_dir, path: @exporter_path.join('bin'))
+ end
+
before do
+ if use_golang_server
+ stub_env('GITLAB_GOLANG_METRICS_SERVER', '1')
+ allow(Settings).to receive(:monitoring).and_return(config.dig('test', 'monitoring'))
+ else
+ config_file.write(YAML.dump(config))
+ config_file.close
+ stub_env('GITLAB_CONFIG', config_file.path)
+ end
# We need to send a request to localhost
WebMock.allow_net_connect!
-
- config_file.write(YAML.dump(config))
- config_file.close
-
- @pid = MetricsServer.spawn(target, metrics_dir: metrics_dir, gitlab_config: config_file.path, wipe_metrics_dir: true)
end
after do
@@ -54,25 +93,25 @@ RSpec.describe 'bin/metrics-server', :aggregate_failures do
expect(Gitlab::ProcessManagement.process_alive?(@pid)).to be(false)
end
- rescue Errno::ESRCH => _
- # 'No such process' means the process died before
+ rescue Errno::ESRCH, Errno::ECHILD => _
+ # 'No such process' or 'No child processes' means the process died before
ensure
config_file.unlink
FileUtils.rm_rf(metrics_dir, secure: true)
end
- it 'serves /metrics endpoint' do
- expect do
- Timeout.timeout(10) do
- http_ok = false
- until http_ok
- sleep 1
- response = Gitlab::HTTP.try_get("http://localhost:3807/metrics", allow_local_requests: true)
- http_ok = response&.success?
- end
- end
- end.not_to raise_error
+ it_behaves_like 'serves metrics endpoint'
+
+ context 'when using Pathname instance as target directory' do
+ let(:metrics_dir) { Pathname.new(Dir.mktmpdir) }
+
+ it_behaves_like 'serves metrics endpoint'
end
end
end
+
+ it_behaves_like 'spawns a server', 'puma', true
+ it_behaves_like 'spawns a server', 'puma', false
+ it_behaves_like 'spawns a server', 'sidekiq', true
+ it_behaves_like 'spawns a server', 'sidekiq', false
end
diff --git a/spec/commands/sidekiq_cluster/cli_spec.rb b/spec/commands/sidekiq_cluster/cli_spec.rb
index bbf5f2bc4d9..d949be8d102 100644
--- a/spec/commands/sidekiq_cluster/cli_spec.rb
+++ b/spec/commands/sidekiq_cluster/cli_spec.rb
@@ -314,7 +314,7 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, stub_settings_source: true do # rubo
let(:sidekiq_exporter_enabled) { true }
it 'does not start a sidekiq metrics server' do
- expect(MetricsServer).not_to receive(:fork)
+ expect(MetricsServer).not_to receive(:start_for_sidekiq)
cli.run(%w(foo))
end
@@ -324,7 +324,7 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, stub_settings_source: true do # rubo
let(:sidekiq_exporter_enabled) { true }
it 'does not start a sidekiq metrics server' do
- expect(MetricsServer).not_to receive(:fork)
+ expect(MetricsServer).not_to receive(:start_for_sidekiq)
cli.run(%w(foo))
end
@@ -347,7 +347,7 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, stub_settings_source: true do # rubo
end
it 'does not start a sidekiq metrics server' do
- expect(MetricsServer).not_to receive(:fork)
+ expect(MetricsServer).not_to receive(:start_for_sidekiq)
cli.run(%w(foo))
end
@@ -366,7 +366,7 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, stub_settings_source: true do # rubo
end
it 'does not start a sidekiq metrics server' do
- expect(MetricsServer).not_to receive(:fork)
+ expect(MetricsServer).not_to receive(:start_for_sidekiq)
cli.run(%w(foo))
end
@@ -389,9 +389,9 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, stub_settings_source: true do # rubo
with_them do
specify do
if start_metrics_server
- expect(MetricsServer).to receive(:fork).with('sidekiq', metrics_dir: metrics_dir, reset_signals: trapped_signals)
+ expect(MetricsServer).to receive(:start_for_sidekiq).with(metrics_dir: metrics_dir, reset_signals: trapped_signals)
else
- expect(MetricsServer).not_to receive(:fork)
+ expect(MetricsServer).not_to receive(:start_for_sidekiq)
end
cli.run(%w(foo))
@@ -421,7 +421,7 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, stub_settings_source: true do # rubo
let(:sidekiq_exporter_enabled) { true }
it 'does not start the server' do
- expect(MetricsServer).not_to receive(:fork)
+ expect(MetricsServer).not_to receive(:start_for_sidekiq)
cli.run(%w(foo --dryrun))
end
@@ -442,7 +442,7 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, stub_settings_source: true do # rubo
it 'stops the entire process cluster if one of the workers has been terminated' do
expect(supervisor).to receive(:alive).and_return(true)
expect(supervisor).to receive(:supervise).and_yield([2])
- expect(MetricsServer).to receive(:fork).once.and_return(metrics_server_pid)
+ expect(MetricsServer).to receive(:start_for_sidekiq).once.and_return(metrics_server_pid)
expect(Gitlab::ProcessManagement).to receive(:signal_processes).with([42, 99], :TERM)
cli.run(%w(foo))
@@ -452,7 +452,7 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, stub_settings_source: true do # rubo
it 'restarts the metrics server when it is down' do
expect(supervisor).to receive(:alive).and_return(true)
expect(supervisor).to receive(:supervise).and_yield([metrics_server_pid])
- expect(MetricsServer).to receive(:fork).twice.and_return(metrics_server_pid)
+ expect(MetricsServer).to receive(:start_for_sidekiq).twice.and_return(metrics_server_pid)
cli.run(%w(foo))
end
@@ -462,7 +462,7 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, stub_settings_source: true do # rubo
it 'does not restart the metrics server' do
expect(supervisor).to receive(:alive).and_return(false)
expect(supervisor).to receive(:supervise).and_yield([metrics_server_pid])
- expect(MetricsServer).to receive(:fork).once.and_return(metrics_server_pid)
+ expect(MetricsServer).to receive(:start_for_sidekiq).once.and_return(metrics_server_pid)
cli.run(%w(foo))
end
diff --git a/spec/controllers/jira_connect/events_controller_spec.rb b/spec/controllers/jira_connect/events_controller_spec.rb
index 5e90ceb0f9c..80375a02b33 100644
--- a/spec/controllers/jira_connect/events_controller_spec.rb
+++ b/spec/controllers/jira_connect/events_controller_spec.rb
@@ -27,7 +27,7 @@ RSpec.describe JiraConnect::EventsController do
shared_context 'valid JWT token' do
before do
- allow_next_instance_of(Atlassian::JiraConnect::AsymmetricJwt) do |asymmetric_jwt|
+ allow_next_instance_of(Atlassian::JiraConnect::Jwt::Asymmetric) do |asymmetric_jwt|
allow(asymmetric_jwt).to receive(:valid?).and_return(true)
allow(asymmetric_jwt).to receive(:iss_claim).and_return(client_key)
end
@@ -36,7 +36,7 @@ RSpec.describe JiraConnect::EventsController do
shared_context 'invalid JWT token' do
before do
- allow_next_instance_of(Atlassian::JiraConnect::AsymmetricJwt) do |asymmetric_jwt|
+ allow_next_instance_of(Atlassian::JiraConnect::Jwt::Asymmetric) do |asymmetric_jwt|
allow(asymmetric_jwt).to receive(:valid?).and_return(false)
end
end
diff --git a/spec/frontend/packages_and_registries/dependency_proxy/components/manifest_row_spec.js b/spec/frontend/packages_and_registries/dependency_proxy/components/manifest_row_spec.js
index b7cbd875497..be3236d1f9c 100644
--- a/spec/frontend/packages_and_registries/dependency_proxy/components/manifest_row_spec.js
+++ b/spec/frontend/packages_and_registries/dependency_proxy/components/manifest_row_spec.js
@@ -3,6 +3,7 @@ import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import ListItem from '~/vue_shared/components/registry/list_item.vue';
import TimeagoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import Component from '~/packages_and_registries/dependency_proxy/components/manifest_row.vue';
+import { MANIFEST_PENDING_DESTRUCTION_STATUS } from '~/packages_and_registries/dependency_proxy/constants';
import { proxyManifests } from 'jest/packages_and_registries/dependency_proxy/mock_data';
describe('Manifest Row', () => {
@@ -26,34 +27,63 @@ describe('Manifest Row', () => {
const findListItem = () => wrapper.findComponent(ListItem);
const findCachedMessages = () => wrapper.findByTestId('cached-message');
const findTimeAgoTooltip = () => wrapper.findComponent(TimeagoTooltip);
-
- beforeEach(() => {
- createComponent();
- });
+ const findStatus = () => wrapper.findByTestId('status');
afterEach(() => {
wrapper.destroy();
});
- it('has a list item', () => {
- expect(findListItem().exists()).toBe(true);
- });
+ describe('With a manifest on the DEFAULT status', () => {
+ beforeEach(() => {
+ createComponent();
+ });
- it('displays the name', () => {
- expect(wrapper.text()).toContain('alpine');
- });
+ it('has a list item', () => {
+ expect(findListItem().exists()).toBe(true);
+ });
- it('displays the version', () => {
- expect(wrapper.text()).toContain('latest');
- });
+ it('displays the name', () => {
+ expect(wrapper.text()).toContain('alpine');
+ });
- it('displays the cached time', () => {
- expect(findCachedMessages().text()).toContain('Cached');
+ it('displays the version', () => {
+ expect(wrapper.text()).toContain('latest');
+ });
+
+ it('displays the cached time', () => {
+ expect(findCachedMessages().text()).toContain('Cached');
+ });
+
+ it('has a time ago tooltip component', () => {
+ expect(findTimeAgoTooltip().props()).toMatchObject({
+ time: defaultProps.manifest.createdAt,
+ });
+ });
+
+ it('does not have a status element displayed', () => {
+ expect(findStatus().exists()).toBe(false);
+ });
});
- it('has a time ago tooltip component', () => {
- expect(findTimeAgoTooltip().props()).toMatchObject({
- time: defaultProps.manifest.createdAt,
+ describe('With a manifest on the PENDING_DESTRUCTION_STATUS', () => {
+ const pendingDestructionManifest = {
+ manifest: {
+ ...defaultProps.manifest,
+ status: MANIFEST_PENDING_DESTRUCTION_STATUS,
+ },
+ };
+
+ beforeEach(() => {
+ createComponent(pendingDestructionManifest);
+ });
+
+ it('has a list item', () => {
+ expect(findListItem().exists()).toBe(true);
+ });
+
+ it('has a status element displayed', () => {
+ expect(findStatus().exists()).toBe(true);
+ expect(findStatus().text()).toBe('Scheduled for deletion');
});
});
});
diff --git a/spec/frontend/packages_and_registries/dependency_proxy/mock_data.js b/spec/frontend/packages_and_registries/dependency_proxy/mock_data.js
index 2aa427bc6af..37c8eb669ba 100644
--- a/spec/frontend/packages_and_registries/dependency_proxy/mock_data.js
+++ b/spec/frontend/packages_and_registries/dependency_proxy/mock_data.js
@@ -8,8 +8,18 @@ export const proxyData = () => ({
export const proxySettings = (extend = {}) => ({ enabled: true, ...extend });
export const proxyManifests = () => [
- { id: 'proxy-1', createdAt: '2021-09-22T09:45:28Z', imageName: 'alpine:latest' },
- { id: 'proxy-2', createdAt: '2021-09-21T09:45:28Z', imageName: 'alpine:stable' },
+ {
+ id: 'proxy-1',
+ createdAt: '2021-09-22T09:45:28Z',
+ imageName: 'alpine:latest',
+ status: 'DEFAULT',
+ },
+ {
+ id: 'proxy-2',
+ createdAt: '2021-09-21T09:45:28Z',
+ imageName: 'alpine:stable',
+ status: 'DEFAULT',
+ },
];
export const pagination = (extend) => ({
diff --git a/spec/frontend/vue_shared/components/registry/list_item_spec.js b/spec/frontend/vue_shared/components/registry/list_item_spec.js
index 1b93292e37b..6e9abb2bfb3 100644
--- a/spec/frontend/vue_shared/components/registry/list_item_spec.js
+++ b/spec/frontend/vue_shared/components/registry/list_item_spec.js
@@ -101,20 +101,6 @@ describe('list item', () => {
});
});
- describe('disabled prop', () => {
- it('when true applies gl-opacity-5 class', () => {
- mountComponent({ disabled: true });
-
- expect(wrapper.classes('gl-opacity-5')).toBe(true);
- });
-
- it('when false does not apply gl-opacity-5 class', () => {
- mountComponent({ disabled: false });
-
- expect(wrapper.classes('gl-opacity-5')).toBe(false);
- });
- });
-
describe('borders and selection', () => {
it.each`
first | selected | shouldHave | shouldNotHave
diff --git a/spec/lib/atlassian/jira_connect/asymmetric_jwt_spec.rb b/spec/lib/atlassian/jira_connect/jwt/asymmetric_spec.rb
index c57d8ece86b..fc2c7e7892b 100644
--- a/spec/lib/atlassian/jira_connect/asymmetric_jwt_spec.rb
+++ b/spec/lib/atlassian/jira_connect/jwt/asymmetric_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Atlassian::JiraConnect::AsymmetricJwt do
+RSpec.describe Atlassian::JiraConnect::Jwt::Asymmetric do
describe '#valid?' do
subject(:asymmetric_jwt) { described_class.new(jwt, verification_claims) }
@@ -10,15 +10,19 @@ RSpec.describe Atlassian::JiraConnect::AsymmetricJwt do
let(:jwt_claims) { { aud: aud, iss: client_key, qsh: qsh } }
let(:aud) { 'https://test.host/-/jira_connect' }
let(:client_key) { '1234' }
- let(:qsh) { Atlassian::Jwt.create_query_string_hash('https://gitlab.test/events/installed', 'POST', 'https://gitlab.test') }
let(:public_key_id) { '123e4567-e89b-12d3-a456-426614174000' }
let(:jwt_headers) { { kid: public_key_id } }
let(:private_key) { OpenSSL::PKey::RSA.generate 2048 }
let(:jwt) { JWT.encode(jwt_claims, private_key, 'RS256', jwt_headers) }
let(:public_key) { private_key.public_key }
+ let(:install_keys_url) { "https://connect-install-keys.atlassian.com/#{public_key_id}" }
+ let(:qsh) do
+ Atlassian::Jwt.create_query_string_hash('https://gitlab.test/events/installed', 'POST', 'https://gitlab.test')
+ end
before do
- stub_request(:get, "https://connect-install-keys.atlassian.com/#{public_key_id}").to_return(body: public_key.to_s, status: 200)
+ stub_request(:get, install_keys_url)
+ .to_return(body: public_key.to_s, status: 200)
end
it 'returns true when verified with public key from CDN' do
@@ -26,7 +30,7 @@ RSpec.describe Atlassian::JiraConnect::AsymmetricJwt do
expect(asymmetric_jwt).to be_valid
- expect(WebMock).to have_requested(:get, "https://connect-install-keys.atlassian.com/#{public_key_id}")
+ expect(WebMock).to have_requested(:get, install_keys_url)
end
context 'JWT does not contain a key ID' do
@@ -43,7 +47,7 @@ RSpec.describe Atlassian::JiraConnect::AsymmetricJwt do
context 'public key can not be retrieved' do
before do
- stub_request(:get, "https://connect-install-keys.atlassian.com/#{public_key_id}").to_return(body: '', status: 404)
+ stub_request(:get, install_keys_url).to_return(body: '', status: 404)
end
it { is_expected.not_to be_valid }
diff --git a/spec/lib/tasks/gitlab/metrics_exporter_task_spec.rb b/spec/lib/tasks/gitlab/metrics_exporter_task_spec.rb
new file mode 100644
index 00000000000..dfb3c511470
--- /dev/null
+++ b/spec/lib/tasks/gitlab/metrics_exporter_task_spec.rb
@@ -0,0 +1,81 @@
+# frozen_string_literal: true
+
+require 'rake_helper'
+require_relative '../../../support/helpers/next_instance_of'
+
+RSpec.describe 'gitlab:metrics_exporter:install' do
+ before do
+ Rake.application.rake_require 'tasks/gitlab/metrics_exporter'
+ end
+
+ subject(:task) do
+ Rake::Task['gitlab:metrics_exporter:install']
+ end
+
+ context 'when no target directory is specified' do
+ it 'aborts with an error message' do
+ expect do
+ expect { task.execute }.to output(/Please specify the directory/).to_stdout
+ end.to raise_error(SystemExit)
+ end
+ end
+
+ context 'when target directory is specified' do
+ let(:args) { Rake::TaskArguments.new(%w(dir), %w(path/to/exporter)) }
+ let(:context) { TOPLEVEL_BINDING.eval('self') }
+ let(:expected_clone_params) do
+ {
+ repo: 'https://gitlab.com/gitlab-org/gitlab-metrics-exporter.git',
+ version: 'main',
+ target_dir: 'path/to/exporter'
+ }
+ end
+
+ context 'when dependencies are missing' do
+ it 'aborts with an error message' do
+ expect(Gitlab::Utils).to receive(:which).with('gmake').ordered
+ expect(Gitlab::Utils).to receive(:which).with('make').ordered
+
+ expect do
+ expect { task.execute(args) }.to output(/Couldn't find a 'make' binary/).to_stdout
+ end.to raise_error(SystemExit)
+ end
+ end
+
+ it 'installs the exporter with gmake' do
+ expect(Gitlab::Utils).to receive(:which).with('gmake').and_return('path/to/gmake').ordered
+ expect(context).to receive(:checkout_or_clone_version).with(hash_including(expected_clone_params)).ordered
+ expect(Dir).to receive(:chdir).with('path/to/exporter').and_yield.ordered
+ expect(context).to receive(:run_command!).with(['path/to/gmake']).ordered
+
+ task.execute(args)
+ end
+
+ it 'installs the exporter with make' do
+ expect(Gitlab::Utils).to receive(:which).with('gmake').ordered
+ expect(Gitlab::Utils).to receive(:which).with('make').and_return('path/to/make').ordered
+ expect(context).to receive(:checkout_or_clone_version).with(hash_including(expected_clone_params)).ordered
+ expect(Dir).to receive(:chdir).with('path/to/exporter').and_yield.ordered
+ expect(context).to receive(:run_command!).with(['path/to/make']).ordered
+
+ task.execute(args)
+ end
+
+ context 'when overriding version via environment variable' do
+ before do
+ stub_env('GITLAB_METRICS_EXPORTER_VERSION', '1.0')
+ end
+
+ it 'clones from repository with that version instead' do
+ expect(Gitlab::Utils).to receive(:which).with('gmake').and_return('path/to/gmake').ordered
+ expect(context).to receive(:checkout_or_clone_version).with(
+ hash_including(expected_clone_params.merge(version: '1.0'))
+ ).ordered
+ expect(Dir).to receive(:chdir).with('path/to/exporter').and_yield.ordered
+ expect(context).to receive(:run_command!).with(['path/to/gmake']).ordered
+
+ task.execute(args)
+ end
+ end
+ end
+end
diff --git a/spec/metrics_server/metrics_server_spec.rb b/spec/metrics_server/metrics_server_spec.rb
index 591840dcba2..4a3580ed4b1 100644
--- a/spec/metrics_server/metrics_server_spec.rb
+++ b/spec/metrics_server/metrics_server_spec.rb
@@ -15,6 +15,8 @@ RSpec.describe MetricsServer do # rubocop:disable RSpec/FilePath
let(:ruby_sampler_double) { double(Gitlab::Metrics::Samplers::RubySampler) }
before do
+ # Make sure we never actually spawn any new processes in a unit test.
+ %i(spawn fork detach).each { |m| allow(Process).to receive(m) }
# We do not want this to have knock-on effects on the test process.
allow(Gitlab::ProcessManagement).to receive(:modify_signals)
@@ -67,35 +69,69 @@ RSpec.describe MetricsServer do # rubocop:disable RSpec/FilePath
end
describe '.spawn' do
- let(:expected_env) do
- {
- 'METRICS_SERVER_TARGET' => target,
- 'WIPE_METRICS_DIR' => '0'
- }
- end
+ context 'for legacy Ruby server' do
+ let(:expected_env) do
+ {
+ 'METRICS_SERVER_TARGET' => target,
+ 'WIPE_METRICS_DIR' => '0',
+ 'GITLAB_CONFIG' => 'path/to/config/gitlab.yml'
+ }
+ end
- it 'spawns a new server process and returns its PID' do
- expect(Process).to receive(:spawn).with(
- expected_env,
- end_with('bin/metrics-server'),
- hash_including(pgroup: true)
- ).and_return(99)
- expect(Process).to receive(:detach).with(99)
+ before do
+ stub_env('GITLAB_CONFIG', 'path/to/config/gitlab.yml')
+ end
+
+ it 'spawns a new server process and returns its PID' do
+ expect(Process).to receive(:spawn).with(
+ expected_env,
+ end_with('bin/metrics-server'),
+ hash_including(pgroup: true)
+ ).and_return(99)
+ expect(Process).to receive(:detach).with(99)
- pid = described_class.spawn(target, metrics_dir: metrics_dir)
+ pid = described_class.spawn(target, metrics_dir: metrics_dir)
- expect(pid).to eq(99)
+ expect(pid).to eq(99)
+ end
end
- context 'when path to gitlab.yml is passed' do
- it 'sets the GITLAB_CONFIG environment variable' do
+ context 'for Golang server' do
+ let(:expected_port) { target == 'puma' ? '8083' : '8082' }
+ let(:expected_env) do
+ {
+ 'GME_MMAP_METRICS_DIR' => metrics_dir,
+ 'GME_PROBES' => 'self,mmap',
+ 'GME_SERVER_HOST' => 'localhost',
+ 'GME_SERVER_PORT' => expected_port
+ }
+ end
+
+ before do
+ stub_env('GITLAB_GOLANG_METRICS_SERVER', '1')
+ end
+
+ it 'spawns a new server process and returns its PID' do
expect(Process).to receive(:spawn).with(
- expected_env.merge('GITLAB_CONFIG' => 'path/to/config/gitlab.yml'),
- end_with('bin/metrics-server'),
+ expected_env,
+ 'gitlab-metrics-exporter',
+ hash_including(pgroup: true)
+ ).and_return(99)
+ expect(Process).to receive(:detach).with(99)
+
+ pid = described_class.spawn(target, metrics_dir: metrics_dir)
+
+ expect(pid).to eq(99)
+ end
+
+ it 'can launch from explicit path instead of PATH' do
+ expect(Process).to receive(:spawn).with(
+ expected_env,
+ '/path/to/gme/gitlab-metrics-exporter',
hash_including(pgroup: true)
).and_return(99)
- described_class.spawn(target, metrics_dir: metrics_dir, gitlab_config: 'path/to/config/gitlab.yml')
+ described_class.spawn(target, metrics_dir: metrics_dir, path: '/path/to/gme/')
end
end
end
@@ -112,10 +148,21 @@ RSpec.describe MetricsServer do # rubocop:disable RSpec/FilePath
end
describe '.spawn' do
- it 'raises an error' do
- expect { described_class.spawn('unsupported', metrics_dir: metrics_dir) }.to(
- raise_error('Target must be one of [puma,sidekiq]')
- )
+ context 'for legacy Ruby server' do
+ it 'raises an error' do
+ expect { described_class.spawn('unsupported', metrics_dir: metrics_dir) }.to(
+ raise_error('Target must be one of [puma,sidekiq]')
+ )
+ end
+ end
+
+ context 'for Golang server' do
+ it 'raises an error' do
+ stub_env('GITLAB_GOLANG_METRICS_SERVER', '1')
+ expect { described_class.spawn('unsupported', metrics_dir: metrics_dir) }.to(
+ raise_error('Target must be one of [puma,sidekiq]')
+ )
+ end
end
end
end
@@ -245,4 +292,23 @@ RSpec.describe MetricsServer do # rubocop:disable RSpec/FilePath
end
end
end
+
+ describe '.start_for_sidekiq' do
+ context 'for legacy Ruby server' do
+ it 'forks the parent process' do
+ expect(Process).to receive(:fork).and_return(42)
+
+ described_class.start_for_sidekiq(metrics_dir: '/path/to/metrics')
+ end
+ end
+
+ context 'for Golang server' do
+ it 'spawns the server process' do
+ stub_env('GITLAB_GOLANG_METRICS_SERVER', '1')
+ expect(Process).to receive(:spawn).and_return(42)
+
+ described_class.start_for_sidekiq(metrics_dir: '/path/to/metrics')
+ end
+ end
+ end
end