diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-04-26 00:09:46 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-04-26 00:09:46 +0300 |
commit | 44fb0702f3d2161d286df9b409f4309ed41207df (patch) | |
tree | 413f71c07a4ef9d13f17fee357832693e6cb3c48 | |
parent | c7531da771f30a54e2220f8f62efeba4b0b1a674 (diff) |
Add latest changes from gitlab-org/gitlab@master
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> </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 + " " + 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 |