Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-04-25 21:09:46 +00:00
parent c7531da771
commit 44fb0702f3
90 changed files with 619 additions and 329 deletions

View File

@ -0,0 +1 @@
main

View File

@ -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: {

View File

@ -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">

View File

@ -1 +1,2 @@
export const GRAPHQL_PAGE_SIZE = 20;
export const MANIFEST_PENDING_DESTRUCTION_STATUS = 'PENDING_DESTRUCTION';

View File

@ -20,6 +20,7 @@ query getDependencyProxyDetails(
id
createdAt
imageName
status
}
pageInfo {
...PageInfo

View File

@ -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,
};

View File

@ -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?

View File

@ -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' }

View File

@ -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

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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

View File

@ -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.

View File

@ -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).

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -12270,6 +12270,9 @@ msgstr ""
msgid "DependencyProxy|Image list"
msgstr ""
msgid "DependencyProxy|Scheduled for deletion"
msgstr ""
msgid "DependencyProxy|Storage settings"
msgstr ""

View File

@ -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)

View File

@ -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
)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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('has a list item', () => {
expect(findListItem().exists()).toBe(true);
});
it('displays the name', () => {
expect(wrapper.text()).toContain('alpine');
});
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('displays the name', () => {
expect(wrapper.text()).toContain('alpine');
});
describe('With a manifest on the PENDING_DESTRUCTION_STATUS', () => {
const pendingDestructionManifest = {
manifest: {
...defaultProps.manifest,
status: MANIFEST_PENDING_DESTRUCTION_STATUS,
},
};
it('displays the version', () => {
expect(wrapper.text()).toContain('latest');
});
beforeEach(() => {
createComponent(pendingDestructionManifest);
});
it('displays the cached time', () => {
expect(findCachedMessages().text()).toContain('Cached');
});
it('has a list item', () => {
expect(findListItem().exists()).toBe(true);
});
it('has a time ago tooltip component', () => {
expect(findTimeAgoTooltip().props()).toMatchObject({
time: defaultProps.manifest.createdAt,
it('has a status element displayed', () => {
expect(findStatus().exists()).toBe(true);
expect(findStatus().text()).toBe('Scheduled for deletion');
});
});
});

View File

@ -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) => ({

View File

@ -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

View File

@ -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 }

View File

@ -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

View File

@ -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
pid = described_class.spawn(target, metrics_dir: metrics_dir)
expect(pid).to eq(99)
end
context 'when path to gitlab.yml is passed' do
it 'sets the GITLAB_CONFIG environment variable' do
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'),
expected_env,
end_with('bin/metrics-server'),
hash_including(pgroup: true)
).and_return(99)
expect(Process).to receive(:detach).with(99)
described_class.spawn(target, metrics_dir: metrics_dir, gitlab_config: 'path/to/config/gitlab.yml')
pid = described_class.spawn(target, metrics_dir: metrics_dir)
expect(pid).to eq(99)
end
end
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,
'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, 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