Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2023-02-08 21:11:09 +00:00
parent a3487798ae
commit 3d42e098d9
47 changed files with 1053 additions and 492 deletions

View File

@ -1,18 +1,63 @@
<script>
import { GlDropdown, GlDropdownItem, GlTooltipDirective as GlTooltip } from '@gitlab/ui';
import { GlTooltip, GlDisclosureDropdown } from '@gitlab/ui';
import { uniqueId } from 'lodash';
import { __ } from '~/locale';
export default {
components: {
GlDropdown,
GlDropdownItem,
},
directives: {
GlDisclosureDropdown,
GlTooltip,
},
inject: ['tiptapEditor'],
data() {
return {
isActive: {},
toggleId: uniqueId('dropdown-toggle-btn-'),
items: [
{
text: __('Comment'),
action: () => this.insert('comment'),
},
{
text: __('Code block'),
action: () => this.insert('codeBlock'),
},
{
text: __('Details block'),
action: () => this.insertList('details', 'detailsContent'),
},
{
text: __('Bullet list'),
action: () => this.insertList('bulletList', 'listItem'),
wrapperClass: 'gl-sm-display-none!',
},
{
text: __('Ordered list'),
action: () => this.insertList('orderedList', 'listItem'),
wrapperClass: 'gl-sm-display-none!',
},
{
text: __('Task list'),
action: () => this.insertList('taskList', 'taskItem'),
wrapperClass: 'gl-sm-display-none!',
},
{
text: __('Horizontal rule'),
action: () => this.execute('setHorizontalRule', 'horizontalRule'),
},
{
text: __('Mermaid diagram'),
action: () => this.insert('diagram', { language: 'mermaid' }),
},
{
text: __('PlantUML diagram'),
action: () => this.insert('diagram', { language: 'plantuml' }),
},
{
text: __('Table of contents'),
action: () => this.execute('insertTableOfContents', 'tableOfContents'),
},
],
};
},
methods: {
@ -46,47 +91,17 @@ export default {
};
</script>
<template>
<gl-dropdown
v-gl-tooltip
size="small"
category="tertiary"
icon="plus"
:text="__('More')"
:title="__('More')"
text-sr-only
class="content-editor-dropdown"
right
lazy
>
<gl-dropdown-item @click="insert('comment')">
{{ __('Comment') }}
</gl-dropdown-item>
<gl-dropdown-item @click="insert('codeBlock')">
{{ __('Code block') }}
</gl-dropdown-item>
<gl-dropdown-item @click="insertList('details', 'detailsContent')">
{{ __('Details block') }}
</gl-dropdown-item>
<gl-dropdown-item class="gl-sm-display-none!" @click="insertList('bulletList', 'listItem')">
{{ __('Bullet list') }}
</gl-dropdown-item>
<gl-dropdown-item class="gl-sm-display-none!" @click="insertList('orderedList', 'listItem')">
{{ __('Ordered list') }}
</gl-dropdown-item>
<gl-dropdown-item class="gl-sm-display-none!" @click="insertList('taskList', 'taskItem')">
{{ __('Task list') }}
</gl-dropdown-item>
<gl-dropdown-item @click="execute('setHorizontalRule', 'horizontalRule')">
{{ __('Horizontal rule') }}
</gl-dropdown-item>
<gl-dropdown-item @click="insert('diagram', { language: 'mermaid' })">
{{ __('Mermaid diagram') }}
</gl-dropdown-item>
<gl-dropdown-item @click="insert('diagram', { language: 'plantuml' })">
{{ __('PlantUML diagram') }}
</gl-dropdown-item>
<gl-dropdown-item @click="execute('insertTableOfContents', 'tableOfContents')">
{{ __('Table of contents') }}
</gl-dropdown-item>
</gl-dropdown>
<div class="gl-display-inline-flex gl-vertical-align-middle">
<gl-disclosure-dropdown
:items="items"
:toggle-id="toggleId"
size="small"
category="tertiary"
icon="plus"
:toggle-text="__('More options')"
text-sr-only
right
/>
<gl-tooltip :target="toggleId" placement="top">{{ __('More options') }}</gl-tooltip>
</div>
</template>

View File

@ -1,76 +0,0 @@
<script>
import { GlAlert, GlSprintf, GlLink, GlButton } from '@gitlab/ui';
import { s__ } from '~/locale';
import Tracking from '~/tracking';
import { UPGRADE_DOCS_URL, ABOUT_RELEASES_PAGE } from '../constants';
export default {
name: 'SecurityPatchUpgradeAlert',
i18n: {
alertTitle: s__('VersionCheck|Critical security upgrade available'),
alertBody: s__(
'VersionCheck|You are currently on version %{currentVersion}. We strongly recommend upgrading your GitLab installation. %{link}',
),
learnMore: s__('VersionCheck|Learn more about this critical security release.'),
primaryButtonText: s__('VersionCheck|Upgrade now'),
},
components: {
GlAlert,
GlSprintf,
GlLink,
GlButton,
},
mixins: [Tracking.mixin()],
props: {
currentVersion: {
type: String,
required: true,
},
},
mounted() {
this.track('render', {
label: 'security_patch_upgrade_alert',
property: this.currentVersion,
});
},
methods: {
trackLearnMoreClick() {
this.track('click_link', {
label: 'security_patch_upgrade_alert_learn_more',
property: this.currentVersion,
});
},
trackUpgradeNowClick() {
this.track('click_link', {
label: 'security_patch_upgrade_alert_upgrade_now',
property: this.currentVersion,
});
},
},
UPGRADE_DOCS_URL,
ABOUT_RELEASES_PAGE,
};
</script>
<template>
<gl-alert :title="$options.i18n.alertTitle" variant="danger" :dismissible="false">
<gl-sprintf :message="$options.i18n.alertBody">
<template #currentVersion>
<span class="gl-font-weight-bold">{{ currentVersion }}</span>
</template>
<template #link>
<gl-link :href="$options.ABOUT_RELEASES_PAGE" @click="trackLearnMoreClick">{{
$options.i18n.learnMore
}}</gl-link>
</template>
</gl-sprintf>
<template #actions>
<gl-button
:href="$options.UPGRADE_DOCS_URL"
variant="confirm"
@click="trackUpgradeNowClick"
>{{ $options.i18n.primaryButtonText }}</gl-button
>
</template>
</gl-alert>
</template>

View File

@ -1,7 +1,6 @@
import Vue from 'vue';
import { parseBoolean, convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import GitlabVersionCheckBadge from './components/gitlab_version_check_badge.vue';
import SecurityPatchUpgradeAlert from './components/security_patch_upgrade_alert.vue';
import SecurityPatchUpgradeAlertModal from './components/security_patch_upgrade_alert_modal.vue';
const mountGitlabVersionCheckBadge = (el) => {
@ -33,25 +32,6 @@ const mountGitlabVersionCheckBadge = (el) => {
}
};
const mountSecurityPatchUpgradeAlert = (el) => {
const { currentVersion } = el.dataset;
try {
return new Vue({
el,
render(createElement) {
return createElement(SecurityPatchUpgradeAlert, {
props: {
currentVersion,
},
});
},
});
} catch {
return null;
}
};
const mountSecurityPatchUpgradeAlertModal = (el) => {
const { currentVersion, version } = el.dataset;
@ -78,16 +58,11 @@ const mountSecurityPatchUpgradeAlertModal = (el) => {
export default () => {
const renderedApps = [];
const securityPatchUpgradeAlert = document.getElementById('js-security-patch-upgrade-alert');
const securityPatchUpgradeAlertModal = document.getElementById(
'js-security-patch-upgrade-alert-modal',
);
const versionCheckBadges = [...document.querySelectorAll('.js-gitlab-version-check-badge')];
if (securityPatchUpgradeAlert) {
renderedApps.push(mountSecurityPatchUpgradeAlert(securityPatchUpgradeAlert));
}
if (securityPatchUpgradeAlertModal) {
renderedApps.push(mountSecurityPatchUpgradeAlertModal(securityPatchUpgradeAlertModal));
}

View File

@ -0,0 +1,258 @@
<script>
import {
GlAlert,
GlButton,
GlCard,
GlFormInput,
GlLink,
GlLoadingIcon,
GlSprintf,
GlToggle,
} from '@gitlab/ui';
import { createAlert } from '~/flash';
import { __, s__ } from '~/locale';
import { helpPagePath } from '~/helpers/help_page_helper';
import inboundAddProjectCIJobTokenScopeMutation from '../graphql/mutations/inbound_add_project_ci_job_token_scope.mutation.graphql';
import inboundRemoveProjectCIJobTokenScopeMutation from '../graphql/mutations/inbound_remove_project_ci_job_token_scope.mutation.graphql';
import inboundUpdateCIJobTokenScopeMutation from '../graphql/mutations/inbound_update_ci_job_token_scope.mutation.graphql';
import inboundGetCIJobTokenScopeQuery from '../graphql/queries/inbound_get_ci_job_token_scope.query.graphql';
import inboundGetProjectsWithCIJobTokenScopeQuery from '../graphql/queries/inbound_get_projects_with_ci_job_token_scope.query.graphql';
import TokenProjectsTable from './token_projects_table.vue';
export default {
i18n: {
toggleLabelTitle: s__('CICD|Allow access to this project with a CI_JOB_TOKEN'),
toggleHelpText: s__(
`CICD|Manage which projects can use their CI_JOB_TOKEN to access this project. It is a security risk to disable this feature, because unauthorized projects might attempt to retrieve an active token and access the API. %{linkStart}Learn more.%{linkEnd}`,
),
cardHeaderTitle: s__(
'CICD|Allow CI job tokens from the following projects to access this project',
),
settingDisabledMessage: s__(
'CICD|Enable feature to allow job token access by the following projects.',
),
addProject: __('Add project'),
cancel: __('Cancel'),
addProjectPlaceholder: __('Paste project path (i.e. gitlab-org/gitlab)'),
projectsFetchError: __('There was a problem fetching the projects'),
scopeFetchError: __('There was a problem fetching the job token scope value'),
},
fields: [
{
key: 'project',
label: __('Project with access'),
thClass: 'gl-border-t-none!',
columnClass: 'gl-w-40p',
},
{
key: 'namespace',
label: __('Namespace'),
thClass: 'gl-border-t-none!',
columnClass: 'gl-w-40p',
},
{
key: 'actions',
label: '',
tdClass: 'gl-text-right',
thClass: 'gl-border-t-none!',
columnClass: 'gl-w-10p',
},
],
components: {
GlAlert,
GlButton,
GlCard,
GlFormInput,
GlLink,
GlLoadingIcon,
GlSprintf,
GlToggle,
TokenProjectsTable,
},
inject: {
fullPath: {
default: '',
},
},
apollo: {
inboundJobTokenScopeEnabled: {
query: inboundGetCIJobTokenScopeQuery,
variables() {
return {
fullPath: this.fullPath,
};
},
update({ project }) {
return project.ciCdSettings.inboundJobTokenScopeEnabled;
},
error() {
createAlert({ message: this.$options.i18n.scopeFetchError });
},
},
projects: {
query: inboundGetProjectsWithCIJobTokenScopeQuery,
variables() {
return {
fullPath: this.fullPath,
};
},
update({ project }) {
return project?.ciJobTokenScope?.inboundAllowlist?.nodes ?? [];
},
error() {
createAlert({ message: this.$options.i18n.projectsFetchError });
},
},
},
data() {
return {
inboundJobTokenScopeEnabled: null,
targetProjectPath: '',
projects: [],
};
},
computed: {
isProjectPathEmpty() {
return this.targetProjectPath === '';
},
ciJobTokenHelpPage() {
return helpPagePath('ci/jobs/ci_job_token');
},
},
methods: {
async updateCIJobTokenScope() {
try {
const {
data: {
ciCdSettingsUpdate: { errors },
},
} = await this.$apollo.mutate({
mutation: inboundUpdateCIJobTokenScopeMutation,
variables: {
input: {
fullPath: this.fullPath,
inboundJobTokenScopeEnabled: this.inboundJobTokenScopeEnabled,
},
},
});
if (errors.length) {
throw new Error(errors[0]);
}
} catch (error) {
this.inboundJobTokenScopeEnabled = !this.inboundJobTokenScopeEnabled;
createAlert({ message: error.message });
}
},
async addProject() {
try {
const {
data: {
ciJobTokenScopeAddProject: { errors },
},
} = await this.$apollo.mutate({
mutation: inboundAddProjectCIJobTokenScopeMutation,
variables: {
projectPath: this.fullPath,
targetProjectPath: this.targetProjectPath,
},
});
if (errors.length) {
throw new Error(errors[0]);
}
} catch (error) {
createAlert({ message: error.message });
} finally {
this.clearTargetProjectPath();
this.getProjects();
}
},
async removeProject(removeTargetPath) {
try {
const {
data: {
ciJobTokenScopeRemoveProject: { errors },
},
} = await this.$apollo.mutate({
mutation: inboundRemoveProjectCIJobTokenScopeMutation,
variables: {
projectPath: this.fullPath,
targetProjectPath: removeTargetPath,
},
});
if (errors.length) {
throw new Error(errors[0]);
}
} catch (error) {
createAlert({ message: error.message });
} finally {
this.getProjects();
}
},
clearTargetProjectPath() {
this.targetProjectPath = '';
},
getProjects() {
this.$apollo.queries.projects.refetch();
},
},
};
</script>
<template>
<div>
<gl-loading-icon v-if="$apollo.loading" size="lg" class="gl-mt-5" />
<template v-else>
<gl-toggle
v-model="inboundJobTokenScopeEnabled"
:label="$options.i18n.toggleLabelTitle"
@change="updateCIJobTokenScope"
>
<template #help>
<gl-sprintf :message="$options.i18n.toggleHelpText">
<template #link="{ content }">
<gl-link :href="ciJobTokenHelpPage" class="inline-link" target="_blank">
{{ content }}
</gl-link>
</template>
</gl-sprintf>
</template>
</gl-toggle>
<div>
<gl-card class="gl-mt-5 gl-mb-3">
<template #header>
<h5 class="gl-my-0">{{ $options.i18n.cardHeaderTitle }}</h5>
</template>
<template #default>
<gl-form-input
v-model="targetProjectPath"
:placeholder="$options.i18n.addProjectPlaceholder"
/>
</template>
<template #footer>
<gl-button variant="confirm" :disabled="isProjectPathEmpty" @click="addProject">
{{ $options.i18n.addProject }}
</gl-button>
<gl-button @click="clearTargetProjectPath">{{ $options.i18n.cancel }}</gl-button>
</template>
</gl-card>
<gl-alert
v-if="!inboundJobTokenScopeEnabled"
class="gl-mb-3"
variant="warning"
:dismissible="false"
:show-icon="false"
>
{{ $options.i18n.settingDisabledMessage }}
</gl-alert>
<token-projects-table
:projects="projects"
:table-fields="$options.fields"
@removeProject="removeProject"
/>
</div>
</template>
</div>
</template>

View File

@ -17,7 +17,6 @@ import removeProjectCIJobTokenScopeMutation from '../graphql/mutations/remove_pr
import updateCIJobTokenScopeMutation from '../graphql/mutations/update_ci_job_token_scope.mutation.graphql';
import getCIJobTokenScopeQuery from '../graphql/queries/get_ci_job_token_scope.query.graphql';
import getProjectsWithCIJobTokenScopeQuery from '../graphql/queries/get_projects_with_ci_job_token_scope.query.graphql';
import OptInJwt from './opt_in_jwt.vue';
import TokenProjectsTable from './token_projects_table.vue';
export default {
@ -36,6 +35,27 @@ export default {
projectsFetchError: __('There was a problem fetching the projects'),
scopeFetchError: __('There was a problem fetching the job token scope value'),
},
fields: [
{
key: 'project',
label: __('Project that can be accessed'),
thClass: 'gl-border-t-none!',
columnClass: 'gl-w-40p',
},
{
key: 'namespace',
label: __('Namespace'),
thClass: 'gl-border-t-none!',
columnClass: 'gl-w-40p',
},
{
key: 'actions',
label: '',
tdClass: 'gl-text-right',
thClass: 'gl-border-t-none!',
columnClass: 'gl-w-10p',
},
],
components: {
GlAlert,
GlButton,
@ -45,7 +65,6 @@ export default {
GlLoadingIcon,
GlSprintf,
GlToggle,
OptInJwt,
TokenProjectsTable,
},
inject: {
@ -230,9 +249,12 @@ export default {
>
{{ $options.i18n.settingDisabledMessage }}
</gl-alert>
<token-projects-table :projects="projects" @removeProject="removeProject" />
<token-projects-table
:projects="projects"
:table-fields="$options.fields"
@removeProject="removeProject"
/>
</div>
<opt-in-jwt />
</template>
</div>
</template>

View File

@ -0,0 +1,27 @@
<script>
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import OutboundTokenAccess from './outbound_token_access.vue';
import InboundTokenAccess from './inbound_token_access.vue';
import OptInJwt from './opt_in_jwt.vue';
export default {
components: {
OutboundTokenAccess,
InboundTokenAccess,
OptInJwt,
},
mixins: [glFeatureFlagMixin()],
computed: {
inboundTokenAccessEnabled() {
return this.glFeatures.ciInboundJobTokenScope;
},
},
};
</script>
<template>
<div>
<outbound-token-access />
<inbound-token-access v-if="inboundTokenAccessEnabled" class="gl-pt-5" />
<opt-in-jwt />
</div>
</template>

View File

@ -1,32 +1,11 @@
<script>
import { GlButton, GlTable } from '@gitlab/ui';
import { __, s__ } from '~/locale';
import { s__ } from '~/locale';
export default {
i18n: {
emptyText: s__('CI/CD|No projects have been added to the scope'),
},
fields: [
{
key: 'project',
label: __('Projects that can be accessed'),
thClass: 'gl-border-t-none!',
columnClass: 'gl-w-40p',
},
{
key: 'namespace',
label: __('Namespace'),
thClass: 'gl-border-t-none!',
columnClass: 'gl-w-40p',
},
{
key: 'actions',
label: '',
tdClass: 'gl-text-right',
thClass: 'gl-border-t-none!',
columnClass: 'gl-w-10p',
},
],
components: {
GlButton,
GlTable,
@ -41,6 +20,10 @@ export default {
type: Array,
required: true,
},
tableFields: {
type: Array,
required: true,
},
},
methods: {
removeProject(project) {
@ -52,7 +35,7 @@ export default {
<template>
<gl-table
:items="projects"
:fields="$options.fields"
:fields="tableFields"
:tbody-tr-attr="{ 'data-testid': 'projects-token-table-row' }"
:empty-text="$options.i18n.emptyText"
show-empty

View File

@ -0,0 +1,7 @@
mutation inboundAddProjectCIJobTokenScope($projectPath: ID!, $targetProjectPath: ID!) {
ciJobTokenScopeAddProject(
input: { projectPath: $projectPath, targetProjectPath: $targetProjectPath, direction: INBOUND }
) {
errors
}
}

View File

@ -0,0 +1,7 @@
mutation inboundRemoveProjectCIJobTokenScope($projectPath: ID!, $targetProjectPath: ID!) {
ciJobTokenScopeRemoveProject(
input: { projectPath: $projectPath, targetProjectPath: $targetProjectPath, direction: INBOUND }
) {
errors
}
}

View File

@ -0,0 +1,8 @@
mutation inboundUpdateCIJobTokenScope($input: CiCdSettingsUpdateInput!) {
ciCdSettingsUpdate(input: $input) {
ciCdSettings {
inboundJobTokenScopeEnabled
}
errors
}
}

View File

@ -0,0 +1,8 @@
query inboundGetCIJobTokenScope($fullPath: ID!) {
project(fullPath: $fullPath) {
id
ciCdSettings {
inboundJobTokenScopeEnabled
}
}
}

View File

@ -0,0 +1,18 @@
query inboundGetProjectsWithCIJobTokenScope($fullPath: ID!) {
project(fullPath: $fullPath) {
id
ciJobTokenScope {
inboundAllowlist {
nodes {
id
name
namespace {
id
fullPath
}
fullPath
}
}
}
}
}

View File

@ -1,7 +1,7 @@
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
import TokenAccess from './components/token_access.vue';
import TokenAccessApp from './components/token_access_app.vue';
Vue.use(VueApollo);
@ -25,7 +25,7 @@ export const initTokenAccess = (containerId = 'js-ci-token-access-app') => {
fullPath,
},
render(createElement) {
return createElement(TokenAccess);
return createElement(TokenAccessApp);
},
});
};

View File

@ -7,6 +7,8 @@ class Explore::GroupsController < Explore::ApplicationController
urgency :low
def index
render_group_tree GroupsFinder.new(nil).execute
user = Feature.enabled?(:generic_explore_groups, current_user, type: :experiment) ? nil : current_user
render_group_tree GroupsFinder.new(user).execute
end
end

View File

@ -14,6 +14,7 @@ module Projects
before_action do
push_frontend_feature_flag(:ci_remove_character_limitation_raw_masked_var, type: :development)
push_frontend_feature_flag(:ci_inbound_job_token_scope, @project)
end
helper_method :highlight_badge

View File

@ -3,8 +3,6 @@
module VersionCheckHelper
include Gitlab::Utils::StrongMemoize
SECURITY_ALERT_SEVERITY = 'danger'
def show_version_check?
return false unless Gitlab::CurrentSettings.version_check_enabled
return false if User.single_user&.requires_usage_stats_consent?
@ -18,9 +16,9 @@ module VersionCheckHelper
strong_memoize_attr :gitlab_version_check
def show_security_patch_upgrade_alert?
return false unless Feature.enabled?(:critical_security_alert) && show_version_check? && gitlab_version_check
return false unless show_version_check? && gitlab_version_check
gitlab_version_check['severity'] === SECURITY_ALERT_SEVERITY
Gitlab::Utils.to_boolean(gitlab_version_check['critical_vulnerability'])
end
def link_to_version

View File

@ -696,22 +696,14 @@ class Repository
end
def head_tree(skip_flat_paths: true)
if Feature.enabled?(:optimized_head_tree)
return if empty? || root_ref.nil?
return if empty? || root_ref.nil?
@head_tree ||= Tree.new(self, root_ref, nil, skip_flat_paths: skip_flat_paths)
elsif head_commit
@head_tree ||= Tree.new(self, head_commit.sha, nil, skip_flat_paths: skip_flat_paths)
end
@head_tree ||= Tree.new(self, root_ref, nil, skip_flat_paths: skip_flat_paths)
end
def tree(sha = :head, path = nil, recursive: false, skip_flat_paths: true, pagination_params: nil)
if sha == :head
if Feature.enabled?(:optimized_head_tree)
return if empty? || root_ref.nil?
else
return unless head_commit
end
return if empty? || root_ref.nil?
if path.nil?
return head_tree(skip_flat_paths: skip_flat_paths)

View File

@ -1,4 +1,3 @@
- return unless show_security_patch_upgrade_alert?
#js-security-patch-upgrade-alert{ data: { "current_version": Gitlab.version_info } }
#js-security-patch-upgrade-alert-modal{ data: { "current_version": Gitlab.version_info, "version": gitlab_version_check.to_json } }

View File

@ -1,8 +0,0 @@
---
name: critical_security_alert
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/108732
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/387719
milestone: '15.8'
type: development
group: group::distribution
default_enabled: false

View File

@ -1,8 +0,0 @@
---
name: optimized_head_tree
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/110248
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/389448
milestone: '15.9'
type: development
group: group::source code
default_enabled: false

View File

@ -0,0 +1,8 @@
---
name: generic_explore_groups
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/103019"
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/381564
milestone: '15.6'
type: experiment
group: group::source code
default_enabled: true

View File

@ -1,15 +1,22 @@
# REQUIRED FIELDS
#
- title: "Support for Praefect custom metrics endpoint configuration"
announcement_milestone: "15.9" # (required) The milestone when this feature was first announced as deprecated.
removal_milestone: "16.0" # (required) The milestone when this feature is planned to be removed
breaking_change: true # (required) Change to false if this is not a breaking change.
reporter: mjwood # (required) GitLab username of the person reporting the change
stage: Gitaly # (required) String value of the stage that the feature was created in. e.g., Growth
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/390266 # (required) Link to the deprecation issue in GitLab
body: | # (required) Do not modify this line, instead modify the lines below.
Support for using the `prometheus_exclude_database_from_default_metrics` configuration value is deprecated because using it is non-performant. Instead, all metrics
that scrape the Praefect database will be exported to the `/db_metrics` endpoint. This may require updating your metrics collection targets.
announcement_milestone: "15.9"
removal_milestone: "16.0"
breaking_change: true
reporter: mjwood
stage: Gitaly
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/390266
body: |
Support for using the `prometheus_exclude_database_from_default_metrics` configuration value is deprecated in GitLab
15.9 and will be removed in GitLab 16.0. We are removing this configuration value because using it is non-performant.
This change means the following metrics will become unavailable on `/metrics`:
- `gitaly_praefect_unavailable_repositories`.
- `gitaly_praefect_verification_queue_depth`.
- `gitaly_praefect_replication_queue_depth`.
This may require updating your metrics collection targets to also scrape `/db_metrics`.
#
# OPTIONAL END OF SUPPORT FIELDS
#

View File

@ -1,10 +1,11 @@
---
table_name: ar_internal_metadata
classes: []
classes:
- ActiveRecord::InternalMetadata
feature_categories:
- database
description: >-
An internal table used by ActiveRecord to store information about how the database was migrated.
description: An internal table used by ActiveRecord to store information about how
the database was migrated.
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9ba1224867665844b117fa037e1465bb706b3685
milestone: '0.8'
gitlab_schema: gitlab_internal

View File

@ -1,9 +1,9 @@
---
table_name: dast_profiles_tags
classes:
- Dast::ScannerProfileTag
- Dast::ProfileTag
feature_categories:
- dynamic_application_security_testing
- dynamic_application_security_testing
description: Join Table for Runner tags and DAST Profiles
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/108371
milestone: '15.8'

View File

@ -1,9 +1,8 @@
---
table_name: dast_scanner_profiles_tags
classes:
- Dast::ScannerProfileTag
classes: []
feature_categories:
- dynamic_application_security_testing
- dynamic_application_security_testing
description: Join Table for Runner tags and DAST Scanner Profiles
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/104909
milestone: '15.7'

View File

@ -668,7 +668,7 @@ variables:
test:
script:
- pwd
- pwd -P
```
The `$CI_CONCURRENT_PROJECT_ID` should be used in conjunction with `$CI_PROJECT_PATH`
@ -680,7 +680,7 @@ variables:
test:
script:
- pwd
- pwd -P
```
#### Nested paths

View File

@ -109,9 +109,7 @@ shared runner resources.
The fair usage queue algorithm assigns jobs based on the projects that have the
fewest number of jobs already running on shared runners.
**Example 1**
If these jobs are in the queue:
For example, if these jobs are in the queue:
- Job 1 for Project 1
- Job 2 for Project 1
@ -120,7 +118,7 @@ If these jobs are in the queue:
- Job 5 for Project 2
- Job 6 for Project 3
The fair usage algorithm assigns jobs in this order:
When several CI/CD jobs run concurrently, the fair usage algorithm assigns jobs in this order:
1. Job 1 is first, because it has the lowest job number from projects with no running jobs (that is, all projects).
1. Job 4 is next, because 4 is now the lowest job number from projects with no running jobs (Project 1 has a job running).
@ -129,20 +127,7 @@ The fair usage algorithm assigns jobs in this order:
1. Job 5 is next, because Project 1 now has 2 jobs running and Job 5 is the lowest remaining job number between Projects 2 and 3.
1. Finally is Job 3... because it's the only job left.
---
**Example 2**
If these jobs are in the queue:
- Job 1 for Project 1
- Job 2 for Project 1
- Job 3 for Project 1
- Job 4 for Project 2
- Job 5 for Project 2
- Job 6 for Project 3
The fair usage algorithm assigns jobs in this order:
When only one job runs at a time, the fair usage algorithm assigns jobs in this order:
1. Job 1 is chosen first, because it has the lowest job number from projects with no running jobs (that is, all projects).
1. We finish Job 1.

View File

@ -179,8 +179,15 @@ WARNING:
This is a [breaking change](https://docs.gitlab.com/ee/development/deprecation_guidelines/).
Review the details carefully before upgrading.
Support for using the `prometheus_exclude_database_from_default_metrics` configuration value is deprecated because using it is non-performant. Instead, all metrics
that scrape the Praefect database will be exported to the `/db_metrics` endpoint. This may require updating your metrics collection targets.
Support for using the `prometheus_exclude_database_from_default_metrics` configuration value is deprecated in GitLab
15.9 and will be removed in GitLab 16.0. We are removing this configuration value because using it is non-performant.
This change means the following metrics will become unavailable on `/metrics`:
- `gitaly_praefect_unavailable_repositories`.
- `gitaly_praefect_verification_queue_depth`.
- `gitaly_praefect_replication_queue_depth`.
This may require updating your metrics collection targets to also scrape `/db_metrics`.
</div>
</div>

View File

@ -275,11 +275,11 @@ and [Helm Chart deployments](https://docs.gitlab.com/charts/). They come with ap
### 15.7.2
- Geo: [Container registry push events are rejected](https://gitlab.com/gitlab-org/gitlab/-/issues/386389) by the `/api/v4/container_registry_event/events` endpoint resulting in Geo secondary sites not being aware of updates to container registry images and subsequently not replicating the updates. Secondary sites may contain out of date container images after a failover as a consequence. This impacts versions 15.6.x and 15.7.0 - 15.7.2. If you're using Geo with container repositories, you are advised to upgrade to GitLab 15.7.3 or 15.8.0 which contain a fix for this issue and avoid potential data loss after a failover.
- Geo: [Container registry push events are rejected](https://gitlab.com/gitlab-org/gitlab/-/issues/386389) by the `/api/v4/container_registry_event/events` endpoint resulting in Geo secondary sites not being aware of updates to container registry images and subsequently not replicating the updates. Secondary sites may contain out of date container images after a failover as a consequence. This impacts versions 15.6.0 - 15.6.6 and 15.7.0 - 15.7.2. If you're using Geo with container repositories, you are advised to upgrade to GitLab 15.6.7, 15.7.3, or 15.8.0 which contain a fix for this issue and avoid potential data loss after a failover.
### 15.7.1
- Geo: [Container registry push events are rejected](https://gitlab.com/gitlab-org/gitlab/-/issues/386389) by the `/api/v4/container_registry_event/events` endpoint resulting in Geo secondary sites not being aware of updates to container registry images and subsequently not replicating the updates. Secondary sites may contain out of date container images after a failover as a consequence. This impacts versions 15.6.x and 15.7.0 - 15.7.2. If you're using Geo with container repositories, you are advised to upgrade to GitLab 15.7.3 or 15.8.0 which contain a fix for this issue and avoid potential data loss after a failover.
- Geo: [Container registry push events are rejected](https://gitlab.com/gitlab-org/gitlab/-/issues/386389) by the `/api/v4/container_registry_event/events` endpoint resulting in Geo secondary sites not being aware of updates to container registry images and subsequently not replicating the updates. Secondary sites may contain out of date container images after a failover as a consequence. This impacts versions 15.6.0 - 15.6.6 and 15.7.0 - 15.7.2. If you're using Geo with container repositories, you are advised to upgrade to GitLab 15.6.7, 15.7.3, or 15.8.0 which contain a fix for this issue and avoid potential data loss after a failover.
### 15.7.0
@ -320,23 +320,31 @@ and [Helm Chart deployments](https://docs.gitlab.com/charts/). They come with ap
Sites that have configured `max_concurrency` will not be affected by this change.
[Read more about the Sidekiq concurrency setting](../administration/sidekiq/extra_sidekiq_processes.md#concurrency).
- Geo: [Container registry push events are rejected](https://gitlab.com/gitlab-org/gitlab/-/issues/386389) by the `/api/v4/container_registry_event/events` endpoint resulting in Geo secondary sites not being aware of updates to container registry images and subsequently not replicating the updates. Secondary sites may contain out of date container images after a failover as a consequence. This impacts versions 15.6.x and 15.7.0 - 15.7.2. If you're using Geo with container repositories, you are advised to upgrade to GitLab 15.7.3 or 15.8.0 which contain a fix for this issue and avoid potential data loss after a failover.
- Geo: [Container registry push events are rejected](https://gitlab.com/gitlab-org/gitlab/-/issues/386389) by the `/api/v4/container_registry_event/events` endpoint resulting in Geo secondary sites not being aware of updates to container registry images and subsequently not replicating the updates. Secondary sites may contain out of date container images after a failover as a consequence. This impacts versions 15.6.0 - 15.6.6 and 15.7.0 - 15.7.2. If you're using Geo with container repositories, you are advised to upgrade to GitLab 15.6.7, 15.7.3, or 15.8.0 which contain a fix for this issue and avoid potential data loss after a failover.
### 15.6.6
- Geo: [Container registry push events are rejected](https://gitlab.com/gitlab-org/gitlab/-/issues/386389) by the `/api/v4/container_registry_event/events` endpoint resulting in Geo secondary sites not being aware of updates to container registry images and subsequently not replicating the updates. Secondary sites may contain out of date container images after a failover as a consequence. This impacts versions 15.6.0 - 15.6.6 and 15.7.0 - 15.7.2. If you're using Geo with container repositories, you are advised to upgrade to GitLab 15.6.7, 15.7.3, or 15.8.0 which contain a fix for this issue and avoid potential data loss after a failover.
### 15.6.5
- Geo: [Container registry push events are rejected](https://gitlab.com/gitlab-org/gitlab/-/issues/386389) by the `/api/v4/container_registry_event/events` endpoint resulting in Geo secondary sites not being aware of updates to container registry images and subsequently not replicating the updates. Secondary sites may contain out of date container images after a failover as a consequence. This impacts versions 15.6.0 - 15.6.6 and 15.7.0 - 15.7.2. If you're using Geo with container repositories, you are advised to upgrade to GitLab 15.6.7, 15.7.3, or 15.8.0 which contain a fix for this issue and avoid potential data loss after a failover.
### 15.6.4
- Geo: [Container registry push events are rejected](https://gitlab.com/gitlab-org/gitlab/-/issues/386389) by the `/api/v4/container_registry_event/events` endpoint resulting in Geo secondary sites not being aware of updates to container registry images and subsequently not replicating the updates. Secondary sites may contain out of date container images after a failover as a consequence. This impacts versions 15.6.x and 15.7.0 - 15.7.2. If you're using Geo with container repositories, you are advised to upgrade to GitLab 15.7.3 or 15.8.0 which contain a fix for this issue and avoid potential data loss after a failover.
- Geo: [Container registry push events are rejected](https://gitlab.com/gitlab-org/gitlab/-/issues/386389) by the `/api/v4/container_registry_event/events` endpoint resulting in Geo secondary sites not being aware of updates to container registry images and subsequently not replicating the updates. Secondary sites may contain out of date container images after a failover as a consequence. This impacts versions 15.6.0 - 15.6.6, and 15.7.0 - 15.7.2. If you're using Geo with container repositories, you are advised to upgrade to GitLab 15.6.7, 15.7.3, or 15.8.0 which contain a fix for this issue and avoid potential data loss after a failover.
### 15.6.3
- Geo: [Container registry push events are rejected](https://gitlab.com/gitlab-org/gitlab/-/issues/386389) by the `/api/v4/container_registry_event/events` endpoint resulting in Geo secondary sites not being aware of updates to container registry images and subsequently not replicating the updates. Secondary sites may contain out of date container images after a failover as a consequence. This impacts versions 15.6.x and 15.7.0 - 15.7.2. If you're using Geo with container repositories, you are advised to upgrade to GitLab 15.7.3 or 15.8.0 which contain a fix for this issue and avoid potential data loss after a failover.
- Geo: [Container registry push events are rejected](https://gitlab.com/gitlab-org/gitlab/-/issues/386389) by the `/api/v4/container_registry_event/events` endpoint resulting in Geo secondary sites not being aware of updates to container registry images and subsequently not replicating the updates. Secondary sites may contain out of date container images after a failover as a consequence. This impacts versions 15.6.0 - 15.6.6 and 15.7.0 - 15.7.2. If you're using Geo with container repositories, you are advised to upgrade to GitLab 15.6.7, 15.7.3, or 15.8.0 which contain a fix for this issue and avoid potential data loss after a failover.
### 15.6.2
- Geo: [Container registry push events are rejected](https://gitlab.com/gitlab-org/gitlab/-/issues/386389) by the `/api/v4/container_registry_event/events` endpoint resulting in Geo secondary sites not being aware of updates to container registry images and subsequently not replicating the updates. Secondary sites may contain out of date container images after a failover as a consequence. This impacts versions 15.6.x and 15.7.0 - 15.7.2. If you're using Geo with container repositories, you are advised to upgrade to GitLab 15.7.3 or 15.8.0 which contain a fix for this issue and avoid potential data loss after a failover.
- Geo: [Container registry push events are rejected](https://gitlab.com/gitlab-org/gitlab/-/issues/386389) by the `/api/v4/container_registry_event/events` endpoint resulting in Geo secondary sites not being aware of updates to container registry images and subsequently not replicating the updates. Secondary sites may contain out of date container images after a failover as a consequence. This impacts versions 15.6.0 - 15.6.6 and 15.7.0 - 15.7.2. If you're using Geo with container repositories, you are advised to upgrade to GitLab 15.6.7, 15.7.3, or 15.8.0 which contain a fix for this issue and avoid potential data loss after a failover.
### 15.6.1
- Geo: [Container registry push events are rejected](https://gitlab.com/gitlab-org/gitlab/-/issues/386389) by the `/api/v4/container_registry_event/events` endpoint resulting in Geo secondary sites not being aware of updates to container registry images and subsequently not replicating the updates. Secondary sites may contain out of date container images after a failover as a consequence. This impacts versions 15.6.x and 15.7.0 - 15.7.2. If you're using Geo with container repositories, you are advised to upgrade to GitLab 15.7.3 or 15.8.0 which contain a fix for this issue and avoid potential data loss after a failover.
- Geo: [Container registry push events are rejected](https://gitlab.com/gitlab-org/gitlab/-/issues/386389) by the `/api/v4/container_registry_event/events` endpoint resulting in Geo secondary sites not being aware of updates to container registry images and subsequently not replicating the updates. Secondary sites may contain out of date container images after a failover as a consequence. This impacts versions 15.6.0 - 15.6.6 and 15.7.0 - 15.7.2. If you're using Geo with container repositories, you are advised to upgrade to GitLab 15.6.7, 15.7.3, or 15.8.0 which contain a fix for this issue and avoid potential data loss after a failover.
### 15.6.0
@ -356,7 +364,7 @@ and [Helm Chart deployments](https://docs.gitlab.com/charts/). They come with ap
This issue was [fixed in GitLab 15.7](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/105375) and backported
to GitLab 15.6.2. The issue can also be worked around:
[read about how to create these indexes](https://gitlab.com/gitlab-org/gitlab/-/issues/378343#note_1199863087).
- Geo: [Container registry push events are rejected](https://gitlab.com/gitlab-org/gitlab/-/issues/386389) by the `/api/v4/container_registry_event/events` endpoint resulting in Geo secondary sites not being aware of updates to container registry images and subsequently not replicating the updates. Secondary sites may contain out of date container images after a failover as a consequence. This impacts versions 15.6.x and 15.7.0 - 15.7.2. If you're using Geo with container repositories, you are advised to upgrade to GitLab 15.7.3 or 15.8.0 which contain a fix for this issue and avoid potential data loss after a failover.
- Geo: [Container registry push events are rejected](https://gitlab.com/gitlab-org/gitlab/-/issues/386389) by the `/api/v4/container_registry_event/events` endpoint resulting in Geo secondary sites not being aware of updates to container registry images and subsequently not replicating the updates. Secondary sites may contain out of date container images after a failover as a consequence. This impacts versions 15.6.0 - 15.6.6 and 15.7.0 - 15.7.2. If you're using Geo with container repositories, you are advised to upgrade to GitLab 15.6.7, 15.7.3, or 15.8.0 which contain a fix for this issue and avoid potential data loss after a failover.
### 15.5.0

View File

@ -13,6 +13,21 @@ GitLab uses the SSH protocol to securely communicate with Git.
When you use SSH keys to authenticate to the GitLab remote server,
you don't need to supply your username and password each time.
## What are SSH keys
SSH uses two keys, a public key and a private key.
- The public key can be distributed.
- The private key should be protected.
When you need to copy or upload your SSH public key, make sure you do not accidentally copy or upload your private key instead.
You cannot expose data by uploading your public key. For example, you can use your public key to
[sign commits](project/repository/ssh_signed_commits/index.md),
which makes your use of GitLab and your data even more secure.
For details, see [Asymmetric cryptography, also known as public-key cryptography](https://en.wikipedia.org/wiki/Public-key_cryptography).
## Prerequisites
To use SSH to communicate with GitLab, you need:

View File

@ -485,7 +485,7 @@ namespace :gitlab do
outdated = true
end
if existing_metadata['classes'].sort != table_metadata['classes'].sort
if existing_metadata['classes'] && existing_metadata['classes'].sort != table_metadata['classes'].sort
existing_metadata['classes'] = table_metadata['classes']
outdated = true
end
@ -514,10 +514,9 @@ namespace :gitlab do
File.join(path, sub_directory, "#{source_name}.yml")
end
# Temporary disable this, see https://gitlab.com/gitlab-org/gitlab/-/merge_requests/85760#note_998452069
# Rake::Task['db:migrate'].enhance do
# Rake::Task['gitlab:db:dictionary:generate'].invoke if Rails.env.development?
# end
Rake::Task['db:migrate'].enhance do
Rake::Task['gitlab:db:dictionary:generate'].invoke if Rails.env.development?
end
end
end
end

View File

@ -7783,6 +7783,12 @@ msgstr ""
msgid "CICD|Add an existing project to the scope"
msgstr ""
msgid "CICD|Allow CI job tokens from the following projects to access this project"
msgstr ""
msgid "CICD|Allow access to this project with a CI_JOB_TOKEN"
msgstr ""
msgid "CICD|An error occurred while update the setting. Please try again."
msgstr ""
@ -7807,6 +7813,9 @@ msgstr ""
msgid "CICD|Deployment strategy"
msgstr ""
msgid "CICD|Enable feature to allow job token access by the following projects."
msgstr ""
msgid "CICD|Enable feature to limit job token access to the following projects."
msgstr ""
@ -7822,6 +7831,9 @@ msgstr ""
msgid "CICD|Limit JSON Web Token (JWT) access"
msgstr ""
msgid "CICD|Manage which projects can use their CI_JOB_TOKEN to access this project. It is a security risk to disable this feature, because unauthorized projects might attempt to retrieve an active token and access the API. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "CICD|Select the projects that can be accessed by API requests authenticated with this project's CI_JOB_TOKEN CI/CD variable. It is a security risk to disable this feature, because unauthorized projects might attempt to retrieve an active token and access the API. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
@ -12766,9 +12778,6 @@ msgstr ""
msgid "DastProfiles|Manage profiles"
msgstr ""
msgid "DastProfiles|Manage site profiles"
msgstr ""
msgid "DastProfiles|Minimum = 0 (no timeout enabled), Maximum = 2880 minutes"
msgstr ""
@ -27387,9 +27396,6 @@ msgstr ""
msgid "Months"
msgstr ""
msgid "More"
msgstr ""
msgid "More Details"
msgstr ""
@ -27414,6 +27420,9 @@ msgstr ""
msgid "More information."
msgstr ""
msgid "More options"
msgstr ""
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
msgstr ""
@ -33014,6 +33023,9 @@ msgstr ""
msgid "Project slug"
msgstr ""
msgid "Project that can be accessed"
msgstr ""
msgid "Project uploads"
msgstr ""
@ -33026,6 +33038,9 @@ msgstr ""
msgid "Project was not found or you do not have permission to add this project to Security Dashboards."
msgstr ""
msgid "Project with access"
msgstr ""
msgid "Project: %{name}"
msgstr ""
@ -33890,9 +33905,6 @@ msgstr ""
msgid "Projects shared with %{group_name}"
msgstr ""
msgid "Projects that can be accessed"
msgstr ""
msgid "Projects to index"
msgstr ""
@ -46657,9 +46669,6 @@ msgstr ""
msgid "VersionCheck|%{details}"
msgstr ""
msgid "VersionCheck|Critical security upgrade available"
msgstr ""
msgid "VersionCheck|Important notice - Critical security release"
msgstr ""
@ -46687,9 +46696,6 @@ msgstr ""
msgid "VersionCheck|You are currently on version %{currentVersion}! We strongly recommend upgrading your GitLab installation to one of the following versions immediately: %{latestStableVersions}."
msgstr ""
msgid "VersionCheck|You are currently on version %{currentVersion}. We strongly recommend upgrading your GitLab installation. %{link}"
msgstr ""
msgid "VersionCheck|Your GitLab Version"
msgstr ""

View File

@ -56,8 +56,8 @@
"@gitlab/at.js": "1.5.7",
"@gitlab/favicon-overlay": "2.0.0",
"@gitlab/fonts": "^1.2.0",
"@gitlab/svgs": "3.18.0",
"@gitlab/ui": "55.0.1",
"@gitlab/svgs": "3.20.0",
"@gitlab/ui": "55.1.0",
"@gitlab/visual-review-tools": "1.7.3",
"@gitlab/web-ide": "0.0.1-dev-20230120231236",
"@rails/actioncable": "6.1.4-7",

View File

@ -40,4 +40,12 @@ RSpec.describe Explore::GroupsController do
end
it_behaves_like 'explore groups'
context 'generic_explore_groups flag is disabled' do
before do
stub_feature_flags(generic_explore_groups: false)
end
it_behaves_like 'explore groups'
end
end

View File

@ -1,10 +1,9 @@
import { GlDropdown } from '@gitlab/ui';
import { GlDisclosureDropdown } from '@gitlab/ui';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import ToolbarMoreDropdown from '~/content_editor/components/toolbar_more_dropdown.vue';
import Diagram from '~/content_editor/extensions/diagram';
import HorizontalRule from '~/content_editor/extensions/horizontal_rule';
import eventHubFactory from '~/helpers/event_hub_factory';
import { stubComponent } from 'helpers/stub_component';
import { createTestEditor, mockChainedCommands, emitEditorEvent } from '../test_utils';
describe('content_editor/components/toolbar_more_dropdown', () => {
@ -25,14 +24,11 @@ describe('content_editor/components/toolbar_more_dropdown', () => {
tiptapEditor,
eventHub,
},
stubs: {
GlDropdown: stubComponent(GlDropdown),
},
propsData,
});
};
const findDropdown = () => wrapper.findComponent(GlDropdown);
const findDropdown = () => wrapper.findComponent(GlDisclosureDropdown);
beforeEach(() => {
buildEditor();
@ -60,7 +56,7 @@ describe('content_editor/components/toolbar_more_dropdown', () => {
beforeEach(async () => {
commands = mockChainedCommands(tiptapEditor, [command, 'focus', 'run']);
btn = wrapper.findByRole('menuitem', { name });
btn = wrapper.findByRole('button', { name });
});
it(`inserts a ${contentType}`, async () => {
@ -76,12 +72,11 @@ describe('content_editor/components/toolbar_more_dropdown', () => {
});
describe('a11y tests', () => {
it('sets text, title, and text-sr-only properties to the table button dropdown', () => {
it('sets toggleText and text-sr-only properties to the table button dropdown', () => {
expect(findDropdown().props()).toMatchObject({
text: 'More',
textSrOnly: true,
toggleText: 'More options',
});
expect(findDropdown().attributes('title')).toBe('More');
});
});
});

View File

@ -1,84 +0,0 @@
import { GlAlert, GlButton, GlLink, GlSprintf } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
import SecurityPatchUpgradeAlert from '~/gitlab_version_check/components/security_patch_upgrade_alert.vue';
import { UPGRADE_DOCS_URL, ABOUT_RELEASES_PAGE } from '~/gitlab_version_check/constants';
describe('SecurityPatchUpgradeAlert', () => {
let wrapper;
let trackingSpy;
const defaultProps = {
currentVersion: '99.9',
};
const createComponent = () => {
trackingSpy = mockTracking(undefined, undefined, jest.spyOn);
wrapper = shallowMount(SecurityPatchUpgradeAlert, {
propsData: {
...defaultProps,
},
stubs: {
GlAlert,
GlSprintf,
},
});
};
afterEach(() => {
unmockTracking();
});
const findGlAlert = () => wrapper.findComponent(GlAlert);
const findGlButton = () => wrapper.findComponent(GlButton);
const findGlLink = () => wrapper.findComponent(GlLink);
describe('template', () => {
beforeEach(() => {
createComponent();
});
it('renders non-dismissible GlAlert with version information', () => {
expect(findGlAlert().text()).toContain(
`You are currently on version ${defaultProps.currentVersion}.`,
);
expect(findGlAlert().props('dismissible')).toBe(false);
});
it('tracks render security_patch_upgrade_alert correctly', () => {
expect(trackingSpy).toHaveBeenCalledWith(undefined, 'render', {
label: 'security_patch_upgrade_alert',
property: defaultProps.currentVersion,
});
});
it('renders GlLink with correct text and link', () => {
expect(findGlLink().text()).toBe('Learn more about this critical security release.');
expect(findGlLink().attributes('href')).toBe(ABOUT_RELEASES_PAGE);
});
it('tracks click security_patch_upgrade_alert_learn_more when link is clicked', async () => {
await findGlLink().vm.$emit('click');
expect(trackingSpy).toHaveBeenCalledWith(undefined, 'click_link', {
label: 'security_patch_upgrade_alert_learn_more',
property: defaultProps.currentVersion,
});
});
it('renders GlButton with correct text and link', () => {
expect(findGlButton().text()).toBe('Upgrade now');
expect(findGlButton().attributes('href')).toBe(UPGRADE_DOCS_URL);
});
it('tracks click security_patch_upgrade_alert_upgrade_now when button is clicked', async () => {
await findGlButton().vm.$emit('click');
expect(trackingSpy).toHaveBeenCalledWith(undefined, 'click_link', {
label: 'security_patch_upgrade_alert_upgrade_now',
property: defaultProps.currentVersion,
});
});
});
});

View File

@ -7,9 +7,6 @@ import {
VERSION_CHECK_BADGE_FIXTURE,
VERSION_CHECK_BADGE_FINDER,
VERSION_BADGE_TEXT,
SECURITY_PATCH_FIXTURE,
SECURITY_PATCH_FINDER,
SECURITY_PATCH_TEXT,
SECURITY_MODAL_FIXTURE,
SECURITY_MODAL_FINDER,
SECURITY_MODAL_TEXT,
@ -29,15 +26,13 @@ describe('initGitlabVersionCheck', () => {
});
describe.each`
description | fixture | finders | componentTexts
${'with no version check elements'} | ${'<div></div>'} | ${[]} | ${[]}
${'with version check badge el but no prop data'} | ${VERSION_CHECK_BADGE_NO_PROP_FIXTURE} | ${[VERSION_CHECK_BADGE_FINDER]} | ${[undefined]}
${'with version check badge el but no severity data'} | ${VERSION_CHECK_BADGE_NO_SEVERITY_FIXTURE} | ${[VERSION_CHECK_BADGE_FINDER]} | ${[undefined]}
${'with version check badge el and version data'} | ${VERSION_CHECK_BADGE_FIXTURE} | ${[VERSION_CHECK_BADGE_FINDER]} | ${[VERSION_BADGE_TEXT]}
${'with security patch el'} | ${SECURITY_PATCH_FIXTURE} | ${[SECURITY_PATCH_FINDER]} | ${[SECURITY_PATCH_TEXT]}
${'with security patch and version badge els'} | ${`${SECURITY_PATCH_FIXTURE}${VERSION_CHECK_BADGE_FIXTURE}`} | ${[SECURITY_PATCH_FINDER, VERSION_CHECK_BADGE_FINDER]} | ${[SECURITY_PATCH_TEXT, VERSION_BADGE_TEXT]}
${'with security modal el'} | ${SECURITY_MODAL_FIXTURE} | ${[SECURITY_MODAL_FINDER]} | ${[SECURITY_MODAL_TEXT]}
${'with security modal, security patch, and version badge els'} | ${`${SECURITY_PATCH_FIXTURE}${SECURITY_MODAL_FIXTURE}${VERSION_CHECK_BADGE_FIXTURE}`} | ${[SECURITY_PATCH_FINDER, SECURITY_MODAL_FINDER, VERSION_CHECK_BADGE_FINDER]} | ${[SECURITY_PATCH_TEXT, SECURITY_MODAL_TEXT, VERSION_BADGE_TEXT]}
description | fixture | finders | componentTexts
${'with no version check elements'} | ${'<div></div>'} | ${[]} | ${[]}
${'with version check badge el but no prop data'} | ${VERSION_CHECK_BADGE_NO_PROP_FIXTURE} | ${[VERSION_CHECK_BADGE_FINDER]} | ${[undefined]}
${'with version check badge el but no severity data'} | ${VERSION_CHECK_BADGE_NO_SEVERITY_FIXTURE} | ${[VERSION_CHECK_BADGE_FINDER]} | ${[undefined]}
${'with version check badge el and version data'} | ${VERSION_CHECK_BADGE_FIXTURE} | ${[VERSION_CHECK_BADGE_FINDER]} | ${[VERSION_BADGE_TEXT]}
${'with security modal el'} | ${SECURITY_MODAL_FIXTURE} | ${[SECURITY_MODAL_FINDER]} | ${[SECURITY_MODAL_TEXT]}
${'with security modal and version badge els'} | ${`${SECURITY_MODAL_FIXTURE}${VERSION_CHECK_BADGE_FIXTURE}`} | ${[SECURITY_MODAL_FINDER, VERSION_CHECK_BADGE_FINDER]} | ${[SECURITY_MODAL_TEXT, VERSION_BADGE_TEXT]}
`('$description', ({ fixture, finders, componentTexts }) => {
beforeEach(() => {
createApp(fixture);

View File

@ -9,12 +9,6 @@ export const VERSION_CHECK_BADGE_FINDER = '[data-testid="badge-click-wrapper"]';
export const VERSION_BADGE_TEXT = 'Up to date';
export const SECURITY_PATCH_FIXTURE = `<div id="js-security-patch-upgrade-alert" data-current-version="15.1"></div>`;
export const SECURITY_PATCH_FINDER = 'h2';
export const SECURITY_PATCH_TEXT = 'Critical security upgrade available';
export const SECURITY_MODAL_FIXTURE = `<div id="js-security-patch-upgrade-alert-modal" data-current-version="15.1" data-version='{ "details": "test details", "latest-stable-versions": "[]" }'></div>`;
export const SECURITY_MODAL_FINDER = '[data-testid="alert-modal-title"]';

View File

@ -0,0 +1,311 @@
import { GlAlert, GlFormInput, GlToggle, GlLoadingIcon } from '@gitlab/ui';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { createAlert } from '~/flash';
import InboundTokenAccess from '~/token_access/components/inbound_token_access.vue';
import inboundAddProjectCIJobTokenScopeMutation from '~/token_access/graphql/mutations/inbound_add_project_ci_job_token_scope.mutation.graphql';
import inboundRemoveProjectCIJobTokenScopeMutation from '~/token_access/graphql/mutations/inbound_remove_project_ci_job_token_scope.mutation.graphql';
import inboundUpdateCIJobTokenScopeMutation from '~/token_access/graphql/mutations/inbound_update_ci_job_token_scope.mutation.graphql';
import inboundGetCIJobTokenScopeQuery from '~/token_access/graphql/queries/inbound_get_ci_job_token_scope.query.graphql';
import inboundGetProjectsWithCIJobTokenScopeQuery from '~/token_access/graphql/queries/inbound_get_projects_with_ci_job_token_scope.query.graphql';
import {
inboundJobTokenScopeEnabledResponse,
inboundJobTokenScopeDisabledResponse,
inboundProjectsWithScopeResponse,
inboundAddProjectSuccessResponse,
inboundRemoveProjectSuccess,
inboundUpdateScopeSuccessResponse,
} from './mock_data';
const projectPath = 'root/my-repo';
const message = 'An error occurred';
const error = new Error(message);
Vue.use(VueApollo);
jest.mock('~/flash');
describe('TokenAccess component', () => {
let wrapper;
const inboundJobTokenScopeEnabledResponseHandler = jest
.fn()
.mockResolvedValue(inboundJobTokenScopeEnabledResponse);
const inboundJobTokenScopeDisabledResponseHandler = jest
.fn()
.mockResolvedValue(inboundJobTokenScopeDisabledResponse);
const inboundProjectsWithScopeResponseHandler = jest
.fn()
.mockResolvedValue(inboundProjectsWithScopeResponse);
const inboundAddProjectSuccessResponseHandler = jest
.fn()
.mockResolvedValue(inboundAddProjectSuccessResponse);
const inboundRemoveProjectSuccessHandler = jest
.fn()
.mockResolvedValue(inboundRemoveProjectSuccess);
const inboundUpdateScopeSuccessResponseHandler = jest
.fn()
.mockResolvedValue(inboundUpdateScopeSuccessResponse);
const failureHandler = jest.fn().mockRejectedValue(error);
const findToggle = () => wrapper.findComponent(GlToggle);
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
const findAddProjectBtn = () => wrapper.findByRole('button', { name: 'Add project' });
const findCancelBtn = () => wrapper.findByRole('button', { name: 'Cancel' });
const findProjectInput = () => wrapper.findComponent(GlFormInput);
const findRemoveProjectBtn = () => wrapper.findByRole('button', { name: 'Remove access' });
const findTokenDisabledAlert = () => wrapper.findComponent(GlAlert);
const createMockApolloProvider = (requestHandlers) => {
return createMockApollo(requestHandlers);
};
const createComponent = (requestHandlers, mountFn = shallowMountExtended) => {
wrapper = mountFn(InboundTokenAccess, {
provide: {
fullPath: projectPath,
},
apolloProvider: createMockApolloProvider(requestHandlers),
data() {
return {
targetProjectPath: 'root/test',
};
},
});
};
describe('loading state', () => {
it('shows loading state while waiting on query to resolve', async () => {
createComponent([
[inboundGetCIJobTokenScopeQuery, inboundJobTokenScopeEnabledResponseHandler],
[inboundGetProjectsWithCIJobTokenScopeQuery, inboundProjectsWithScopeResponseHandler],
]);
expect(findLoadingIcon().exists()).toBe(true);
await waitForPromises();
expect(findLoadingIcon().exists()).toBe(false);
});
});
describe('fetching projects and scope', () => {
it('fetches projects and scope correctly', () => {
const expectedVariables = {
fullPath: 'root/my-repo',
};
createComponent([
[inboundGetCIJobTokenScopeQuery, inboundJobTokenScopeEnabledResponseHandler],
[inboundGetProjectsWithCIJobTokenScopeQuery, inboundProjectsWithScopeResponseHandler],
]);
expect(inboundJobTokenScopeEnabledResponseHandler).toHaveBeenCalledWith(expectedVariables);
expect(inboundProjectsWithScopeResponseHandler).toHaveBeenCalledWith(expectedVariables);
});
it('handles fetch projects error correctly', async () => {
createComponent([
[inboundGetCIJobTokenScopeQuery, inboundJobTokenScopeEnabledResponseHandler],
[inboundGetProjectsWithCIJobTokenScopeQuery, failureHandler],
]);
await waitForPromises();
expect(createAlert).toHaveBeenCalledWith({
message: 'There was a problem fetching the projects',
});
});
it('handles fetch scope error correctly', async () => {
createComponent([
[inboundGetCIJobTokenScopeQuery, failureHandler],
[inboundGetProjectsWithCIJobTokenScopeQuery, inboundProjectsWithScopeResponseHandler],
]);
await waitForPromises();
expect(createAlert).toHaveBeenCalledWith({
message: 'There was a problem fetching the job token scope value',
});
});
});
describe('toggle', () => {
it('the toggle is on and the alert is hidden', async () => {
createComponent([
[inboundGetCIJobTokenScopeQuery, inboundJobTokenScopeEnabledResponseHandler],
[inboundGetProjectsWithCIJobTokenScopeQuery, inboundProjectsWithScopeResponseHandler],
]);
await waitForPromises();
expect(findToggle().props('value')).toBe(true);
expect(findTokenDisabledAlert().exists()).toBe(false);
});
it('the toggle is off and the alert is visible', async () => {
createComponent([
[inboundGetCIJobTokenScopeQuery, inboundJobTokenScopeDisabledResponseHandler],
[inboundGetProjectsWithCIJobTokenScopeQuery, inboundProjectsWithScopeResponseHandler],
]);
await waitForPromises();
expect(findToggle().props('value')).toBe(false);
expect(findTokenDisabledAlert().exists()).toBe(true);
});
describe('update ci job token scope', () => {
it('calls inboundUpdateCIJobTokenScopeMutation mutation', async () => {
createComponent(
[
[inboundGetCIJobTokenScopeQuery, inboundJobTokenScopeEnabledResponseHandler],
[inboundUpdateCIJobTokenScopeMutation, inboundUpdateScopeSuccessResponseHandler],
],
mountExtended,
);
await waitForPromises();
expect(findToggle().props('value')).toBe(true);
findToggle().vm.$emit('change', false);
await waitForPromises();
expect(findToggle().props('value')).toBe(false);
expect(inboundUpdateScopeSuccessResponseHandler).toHaveBeenCalledWith({
input: {
fullPath: 'root/my-repo',
inboundJobTokenScopeEnabled: false,
},
});
});
it('handles update scope error correctly', async () => {
createComponent(
[
[inboundGetCIJobTokenScopeQuery, inboundJobTokenScopeDisabledResponseHandler],
[inboundUpdateCIJobTokenScopeMutation, failureHandler],
],
mountExtended,
);
await waitForPromises();
expect(findToggle().props('value')).toBe(false);
findToggle().vm.$emit('change', true);
await waitForPromises();
expect(findToggle().props('value')).toBe(false);
expect(createAlert).toHaveBeenCalledWith({ message });
});
});
});
describe('add project', () => {
it('calls add project mutation', async () => {
createComponent(
[
[inboundGetCIJobTokenScopeQuery, inboundJobTokenScopeEnabledResponseHandler],
[inboundGetProjectsWithCIJobTokenScopeQuery, inboundProjectsWithScopeResponseHandler],
[inboundAddProjectCIJobTokenScopeMutation, inboundAddProjectSuccessResponseHandler],
],
mountExtended,
);
await waitForPromises();
findAddProjectBtn().trigger('click');
expect(inboundAddProjectSuccessResponseHandler).toHaveBeenCalledWith({
projectPath,
targetProjectPath: 'root/test',
});
});
it('add project handles error correctly', async () => {
createComponent(
[
[inboundGetCIJobTokenScopeQuery, inboundJobTokenScopeEnabledResponseHandler],
[inboundGetProjectsWithCIJobTokenScopeQuery, inboundProjectsWithScopeResponseHandler],
[inboundAddProjectCIJobTokenScopeMutation, failureHandler],
],
mountExtended,
);
await waitForPromises();
findAddProjectBtn().trigger('click');
await waitForPromises();
expect(createAlert).toHaveBeenCalledWith({ message });
});
it('clicking cancel clears target path', async () => {
createComponent(
[
[inboundGetCIJobTokenScopeQuery, inboundJobTokenScopeEnabledResponseHandler],
[inboundGetProjectsWithCIJobTokenScopeQuery, inboundProjectsWithScopeResponseHandler],
],
mountExtended,
);
await waitForPromises();
expect(findProjectInput().element.value).toBe('root/test');
await findCancelBtn().trigger('click');
expect(findProjectInput().element.value).toBe('');
});
});
describe('remove project', () => {
it('calls remove project mutation', async () => {
createComponent(
[
[inboundGetCIJobTokenScopeQuery, inboundJobTokenScopeEnabledResponseHandler],
[inboundGetProjectsWithCIJobTokenScopeQuery, inboundProjectsWithScopeResponseHandler],
[inboundRemoveProjectCIJobTokenScopeMutation, inboundRemoveProjectSuccessHandler],
],
mountExtended,
);
await waitForPromises();
findRemoveProjectBtn().trigger('click');
expect(inboundRemoveProjectSuccessHandler).toHaveBeenCalledWith({
projectPath,
targetProjectPath: 'root/ci-project',
});
});
it('remove project handles error correctly', async () => {
createComponent(
[
[inboundGetCIJobTokenScopeQuery, inboundJobTokenScopeEnabledResponseHandler],
[inboundGetProjectsWithCIJobTokenScopeQuery, inboundProjectsWithScopeResponseHandler],
[inboundRemoveProjectCIJobTokenScopeMutation, failureHandler],
],
mountExtended,
);
await waitForPromises();
findRemoveProjectBtn().trigger('click');
await waitForPromises();
expect(createAlert).toHaveBeenCalledWith({ message });
});
});
});

View File

@ -106,6 +106,21 @@ export const mockProjects = [
},
];
export const mockFields = [
{
key: 'project',
label: 'Project with access',
},
{
key: 'namespace',
label: 'Namespace',
},
{
key: 'actions',
label: '',
},
];
export const optInJwtQueryResponse = (optInJwt) => ({
data: {
project: {
@ -131,3 +146,84 @@ export const optInJwtMutationResponse = (optInJwt) => ({
},
},
});
export const inboundJobTokenScopeEnabledResponse = {
data: {
project: {
id: '1',
ciCdSettings: {
inboundJobTokenScopeEnabled: true,
__typename: 'ProjectCiCdSetting',
},
__typename: 'Project',
},
},
};
export const inboundJobTokenScopeDisabledResponse = {
data: {
project: {
id: '1',
ciCdSettings: {
inboundJobTokenScopeEnabled: false,
__typename: 'ProjectCiCdSetting',
},
__typename: 'Project',
},
},
};
export const inboundProjectsWithScopeResponse = {
data: {
project: {
__typename: 'Project',
id: '1',
ciJobTokenScope: {
__typename: 'CiJobTokenScopeType',
inboundAllowlist: {
__typename: 'ProjectConnection',
nodes: [
{
__typename: 'Project',
fullPath: 'root/ci-project',
id: 'gid://gitlab/Project/23',
name: 'ci-project',
namespace: { id: 'gid://gitlab/Namespaces::UserNamespace/1', fullPath: 'root' },
},
],
},
},
},
},
};
export const inboundAddProjectSuccessResponse = {
data: {
ciJobTokenScopeAddProject: {
errors: [],
__typename: 'CiJobTokenScopeAddProjectPayload',
},
},
};
export const inboundRemoveProjectSuccess = {
data: {
ciJobTokenScopeRemoveProject: {
errors: [],
__typename: 'CiJobTokenScopeRemoveProjectPayload',
},
},
};
export const inboundUpdateScopeSuccessResponse = {
data: {
ciCdSettingsUpdate: {
ciCdSettings: {
inboundJobTokenScopeEnabled: false,
__typename: 'ProjectCiCdSetting',
},
errors: [],
__typename: 'CiCdSettingsUpdatePayload',
},
},
};

View File

@ -5,8 +5,7 @@ import createMockApollo from 'helpers/mock_apollo_helper';
import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { createAlert } from '~/flash';
import OptInJwt from '~/token_access/components/opt_in_jwt.vue';
import TokenAccess from '~/token_access/components/token_access.vue';
import OutboundTokenAccess from '~/token_access/components/outbound_token_access.vue';
import addProjectCIJobTokenScopeMutation from '~/token_access/graphql/mutations/add_project_ci_job_token_scope.mutation.graphql';
import removeProjectCIJobTokenScopeMutation from '~/token_access/graphql/mutations/remove_project_ci_job_token_scope.mutation.graphql';
import updateCIJobTokenScopeMutation from '~/token_access/graphql/mutations/update_ci_job_token_scope.mutation.graphql';
@ -41,7 +40,6 @@ describe('TokenAccess component', () => {
const failureHandler = jest.fn().mockRejectedValue(error);
const findToggle = () => wrapper.findComponent(GlToggle);
const findOptInJwt = () => wrapper.findComponent(OptInJwt);
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
const findAddProjectBtn = () => wrapper.findByRole('button', { name: 'Add project' });
const findRemoveProjectBtn = () => wrapper.findByRole('button', { name: 'Remove access' });
@ -52,7 +50,7 @@ describe('TokenAccess component', () => {
};
const createComponent = (requestHandlers, mountFn = shallowMountExtended) => {
wrapper = mountFn(TokenAccess, {
wrapper = mountFn(OutboundTokenAccess, {
provide: {
fullPath: projectPath,
},
@ -65,10 +63,6 @@ describe('TokenAccess component', () => {
});
};
afterEach(() => {
wrapper.destroy();
});
describe('loading state', () => {
it('shows loading state while waiting on query to resolve', async () => {
createComponent([
@ -84,21 +78,6 @@ describe('TokenAccess component', () => {
});
});
describe('template', () => {
beforeEach(async () => {
createComponent([
[getCIJobTokenScopeQuery, enabledJobTokenScopeHandler],
[getProjectsWithCIJobTokenScopeQuery, getProjectsWithScopeHandler],
]);
await waitForPromises();
});
it('renders the opt in jwt component', () => {
expect(findOptInJwt().exists()).toBe(true);
});
});
describe('fetching projects and scope', () => {
it('fetches projects and scope correctly', () => {
const expectedVariables = {

View File

@ -0,0 +1,47 @@
import { shallowMount } from '@vue/test-utils';
import OutboundTokenAccess from '~/token_access/components/outbound_token_access.vue';
import InboundTokenAccess from '~/token_access/components/inbound_token_access.vue';
import OptInJwt from '~/token_access/components/opt_in_jwt.vue';
import TokenAccessApp from '~/token_access/components/token_access_app.vue';
describe('TokenAccessApp component', () => {
let wrapper;
const findOutboundTokenAccess = () => wrapper.findComponent(OutboundTokenAccess);
const findInboundTokenAccess = () => wrapper.findComponent(InboundTokenAccess);
const findOptInJwt = () => wrapper.findComponent(OptInJwt);
const createComponent = (flagState = false) => {
wrapper = shallowMount(TokenAccessApp, {
provide: {
glFeatures: { ciInboundJobTokenScope: flagState },
},
});
};
describe('default', () => {
beforeEach(() => {
createComponent();
});
it('renders the opt in jwt component', () => {
expect(findOptInJwt().exists()).toBe(true);
});
it('renders the outbound token access component', () => {
expect(findOutboundTokenAccess().exists()).toBe(true);
});
it('does not render the inbound token access component', () => {
expect(findInboundTokenAccess().exists()).toBe(false);
});
});
describe('with feature flag enabled', () => {
it('renders the inbound token access component', () => {
createComponent(true);
expect(findInboundTokenAccess().exists()).toBe(true);
});
});
});

View File

@ -1,7 +1,7 @@
import { GlTable, GlButton } from '@gitlab/ui';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import TokenProjectsTable from '~/token_access/components/token_projects_table.vue';
import { mockProjects } from './mock_data';
import { mockProjects, mockFields } from './mock_data';
describe('Token projects table', () => {
let wrapper;
@ -12,6 +12,7 @@ describe('Token projects table', () => {
fullPath: 'root/ci-project',
},
propsData: {
tableFields: mockFields,
projects: mockProjects,
},
});
@ -28,10 +29,6 @@ describe('Token projects table', () => {
createComponent();
});
afterEach(() => {
wrapper.destroy();
});
it('displays a table', () => {
expect(findTable().exists()).toBe(true);
});

View File

@ -49,26 +49,29 @@ RSpec.describe VersionCheckHelper do
describe '#show_security_patch_upgrade_alert?' do
describe 'return conditions' do
where(:feature_enabled, :show_version_check, :gitlab_version_check, :result) do
where(:show_version_check, :gitlab_version_check, :result) do
[
[false, false, nil, false],
[false, false, { "severity" => "success" }, false],
[false, false, { "severity" => "danger" }, false],
[false, true, nil, false],
[false, true, { "severity" => "success" }, false],
[false, true, { "severity" => "danger" }, false],
[true, false, nil, false],
[true, false, { "severity" => "success" }, false],
[true, false, { "severity" => "danger" }, false],
[true, true, nil, false],
[true, true, { "severity" => "success" }, false],
[true, true, { "severity" => "danger" }, true]
[false, nil, false],
[false, { "severity" => "success" }, false],
[false, { "severity" => "danger" }, false],
[false, { "severity" => "danger", "critical_vulnerability" => 'some text' }, false],
[false, { "severity" => "danger", "critical_vulnerability" => 'false' }, false],
[false, { "severity" => "danger", "critical_vulnerability" => false }, false],
[false, { "severity" => "danger", "critical_vulnerability" => 'true' }, false],
[false, { "severity" => "danger", "critical_vulnerability" => true }, false],
[true, nil, false],
[true, { "severity" => "success" }, nil],
[true, { "severity" => "danger" }, nil],
[true, { "severity" => "danger", "critical_vulnerability" => 'some text' }, nil],
[true, { "severity" => "danger", "critical_vulnerability" => 'false' }, false],
[true, { "severity" => "danger", "critical_vulnerability" => false }, false],
[true, { "severity" => "danger", "critical_vulnerability" => 'true' }, true],
[true, { "severity" => "danger", "critical_vulnerability" => true }, true]
]
end
with_them do
before do
stub_feature_flags(critical_security_alert: feature_enabled)
allow(helper).to receive(:show_version_check?).and_return(show_version_check)
allow(helper).to receive(:gitlab_version_check).and_return(gitlab_version_check)
end

View File

@ -2775,16 +2775,6 @@ RSpec.describe Repository, feature_category: :source_code_management do
it 'returns a Tree' do
expect(repository.head_tree).to be_an_instance_of(Tree)
end
context 'when feature flag "optimized_head_tree" is disabled' do
before do
stub_feature_flags(optimized_head_tree: false)
end
it 'returns a Tree' do
expect(repository.head_tree).to be_an_instance_of(Tree)
end
end
end
context 'with a non-existing repository' do
@ -2793,18 +2783,6 @@ RSpec.describe Repository, feature_category: :source_code_management do
expect(repository.head_tree).to be_nil
end
context 'when feature flag "optimized_head_tree" is disabled' do
before do
stub_feature_flags(optimized_head_tree: false)
end
it 'returns nil' do
expect(repository).to receive(:head_commit).and_return(nil)
expect(repository.head_tree).to be_nil
end
end
end
end
@ -2817,33 +2795,16 @@ RSpec.describe Repository, feature_category: :source_code_management do
let(:pagination_params) { nil }
context 'using a non-existing repository' do
context 'when feature flag "optimized_head_tree" is enabled' do
before do
allow(repository).to receive(:root_ref).and_return(nil)
end
it { is_expected.to be_nil }
context 'when path is defined' do
let(:path) { 'README.md' }
it { is_expected.to be_nil }
end
before do
allow(repository).to receive(:root_ref).and_return(nil)
end
context 'when feature flag "optimized_head_tree" is disabled' do
before do
stub_feature_flags(optimized_head_tree: false)
allow(repository).to receive(:head_commit).and_return(nil)
end
it { is_expected.to be_nil }
context 'when path is defined' do
let(:path) { 'README.md' }
it { is_expected.to be_nil }
context 'when path is defined' do
let(:path) { 'README.md' }
it { is_expected.to be_nil }
end
end
end

View File

@ -9,10 +9,6 @@ RSpec.describe 'shared/gitlab_version/_security_patch_upgrade_alert' do
render
end
it 'renders the security patch upgrade alert' do
expect(rendered).to have_selector('#js-security-patch-upgrade-alert')
end
it 'renders the security patch upgrade alert modal' do
expect(rendered).to have_selector('#js-security-patch-upgrade-alert-modal')
end

View File

@ -1342,15 +1342,15 @@
stylelint-declaration-strict-value "1.8.0"
stylelint-scss "4.2.0"
"@gitlab/svgs@3.18.0":
version "3.18.0"
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-3.18.0.tgz#d89364feb42404a35824a54d518b51af8c1e900f"
integrity sha512-ni9TmhusXpt/3k/DZzovMEUeB/6UTXiDpuujI8HDBqR4Mwlah6FBco5ZfolkW6YjFL0YvtcLWhnwZA0iM3hfMw==
"@gitlab/svgs@3.20.0":
version "3.20.0"
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-3.20.0.tgz#4ee4f2f24304d13ccce58f82c2ecd87e556f35b4"
integrity sha512-nYTF4j5kon4XbBr/sAzuubgxjIne9+RTZLmSrSaL9FL4eyuv9aa7YMCcOrlIbYX5jlSYlcD+ck2F2M1sqXXOBA==
"@gitlab/ui@55.0.1":
version "55.0.1"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-55.0.1.tgz#3d5c22b864d64435eff01fb39e4edb6e1b8a0432"
integrity sha512-vPwmGhc73HTSBGoMi4jL+Wf11w/1o62pwXuYSYNOs2xis1xMLJiaPBGXNKDFliC5AaRDXAIxCiC5CMJZH3qXMg==
"@gitlab/ui@55.1.0":
version "55.1.0"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-55.1.0.tgz#a2ea6951365c495df7acdd1351b1660771607b67"
integrity sha512-0E+l76jNsK3BPqQmbuTKAvC4RfjQfpaLvmlShe8wxrnMrS0IKsse43RST0ttV+mhkOVfac0me8pDhN4ijSm7Tw==
dependencies:
"@popperjs/core" "^2.11.2"
bootstrap-vue "2.20.1"