Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-03-04 18:20:01 +00:00
parent 73e15fde38
commit 698fe342b9
107 changed files with 1394 additions and 950 deletions

View File

@ -1,11 +1,13 @@
import $ from 'jquery';
import { memoize, throttle } from 'lodash';
import createEventHub from '~/helpers/event_hub_factory';
class DirtySubmitForm {
constructor(form) {
this.form = form;
this.dirtyInputs = [];
this.isDisabled = true;
this.events = createEventHub();
this.init();
}
@ -36,11 +38,21 @@ class DirtySubmitForm {
this.form.addEventListener('submit', (event) => this.formSubmit(event));
}
addInputsListener(callback) {
this.events.$on('input', callback);
}
removeInputsListener(callback) {
this.events.$off('input', callback);
}
updateDirtyInput(event) {
const { target } = event;
if (!target.dataset.isDirtySubmitInput) return;
this.events.$emit('input', event);
this.updateDirtyInputs(target);
this.toggleSubmission();
}

View File

@ -92,6 +92,9 @@ export default {
hasUpstreamPipelines() {
return Boolean(this.pipeline?.upstream?.length > 0);
},
isMultiProjectVizAvailable() {
return Boolean(this.pipeline?.user?.namespace?.crossProjectPipelineAvailable);
},
isStageView() {
return this.viewType === STAGE_VIEW;
},
@ -178,6 +181,7 @@ export default {
<linked-pipelines-column
v-if="showUpstreamPipelines"
:config-paths="configPaths"
:is-multi-project-viz-available="isMultiProjectVizAvailable"
:linked-pipelines="upstreamPipelines"
:column-title="__('Upstream')"
:show-links="showJobLinks"
@ -226,6 +230,7 @@ export default {
v-if="showDownstreamPipelines"
class="gl-mr-6"
:config-paths="configPaths"
:is-multi-project-viz-available="isMultiProjectVizAvailable"
:linked-pipelines="downstreamPipelines"
:column-title="__('Downstream')"
:show-links="showJobLinks"

View File

@ -1,12 +1,29 @@
<script>
import { GlBadge, GlButton, GlLink, GlLoadingIcon, GlTooltipDirective } from '@gitlab/ui';
import {
GlBadge,
GlButton,
GlLink,
GlLoadingIcon,
GlPopover,
GlSprintf,
GlTooltipDirective,
} from '@gitlab/ui';
import TierBadge from '~/vue_shared/components/tier_badge.vue';
import { BV_HIDE_TOOLTIP } from '~/lib/utils/constants';
import { __, sprintf } from '~/locale';
import { __, s__, sprintf } from '~/locale';
import CiStatus from '~/vue_shared/components/ci_icon.vue';
import { reportToSentry } from '../../utils';
import { DOWNSTREAM, UPSTREAM } from './constants';
export default {
i18n: {
popover: {
title: s__('Pipelines|Multi-project pipeline graphs'),
description: s__(
'Pipelines|Gitlab Premium users have access to the multi-project pipeline graph to improve the visualization of these pipelines. %{linkStart}Learn More%{linkEnd}',
),
},
},
directives: {
GlTooltip: GlTooltipDirective,
},
@ -16,7 +33,11 @@ export default {
GlButton,
GlLink,
GlLoadingIcon,
GlPopover,
GlSprintf,
TierBadge,
},
inject: ['multiProjectHelpPath'],
props: {
columnTitle: {
type: String,
@ -26,6 +47,10 @@ export default {
type: Boolean,
required: true,
},
isMultiProjectVizAvailable: {
type: Boolean,
required: true,
},
isLoading: {
type: Boolean,
required: true,
@ -90,6 +115,9 @@ export default {
pipelineStatus() {
return this.pipeline.status;
},
popoverContainerId() {
return `popoverContainer-${this.pipeline.id}`;
},
projectName() {
return this.pipeline.project.name;
},
@ -128,16 +156,21 @@ export default {
<template>
<div
ref="linkedPipeline"
v-gl-tooltip
class="gl-h-full gl-display-flex! gl-border-solid gl-border-gray-100 gl-border-1"
:class="flexDirection"
:title="tooltipText"
data-qa-selector="child_pipeline"
data-testid="linkedPipeline"
@mouseover="onDownstreamHovered"
@mouseleave="onDownstreamHoverLeave"
>
<div class="gl-w-full gl-bg-white gl-p-3" :class="cardSpacingClass">
<div
v-gl-tooltip
class="gl-w-full gl-bg-white gl-p-3"
:class="cardSpacingClass"
data-testid="linkedPipelineBody"
data-qa-selector="linked_pipeline_body"
:title="tooltipText"
>
<div class="gl-display-flex gl-pr-3">
<ci-status
v-if="!pipelineIsLoading"
@ -163,17 +196,38 @@ export default {
</gl-badge>
</div>
</div>
<div class="gl-display-flex">
<div :id="popoverContainerId" class="gl-display-flex">
<gl-button
:id="buttonId"
class="gl-shadow-none! gl-rounded-0!"
:class="`js-pipeline-expand-${pipeline.id} ${buttonBorderClass}`"
:icon="expandedIcon"
:aria-label="__('Expand pipeline')"
:disabled="!isMultiProjectVizAvailable"
data-testid="expand-pipeline-button"
data-qa-selector="expand_pipeline_button"
@click="onClickLinkedPipeline"
/>
<gl-popover
v-if="!isMultiProjectVizAvailable"
placement="top"
:target="popoverContainerId"
triggers="hover"
>
<template #title>
<b>{{ $options.i18n.popover.title }}</b>
<tier-badge class="gl-mt-3" tier="premium"
/></template>
<p class="gl-my-0">
<gl-sprintf :message="$options.i18n.popover.description">
<template #link="{ content }"
><gl-link :href="multiProjectHelpPath" class="gl-font-sm" target="_blank">{{
content
}}</gl-link>
</template>
</gl-sprintf>
</p>
</gl-popover>
</div>
</div>
</template>

View File

@ -28,6 +28,10 @@ export default {
required: true,
validator: validateConfigPaths,
},
isMultiProjectVizAvailable: {
type: Boolean,
required: true,
},
linkedPipelines: {
type: Array,
required: true,
@ -208,6 +212,7 @@ export default {
<linked-pipeline
class="gl-display-inline-block"
:is-loading="isLoadingPipeline(pipeline.id)"
:is-multi-project-viz-available="isMultiProjectVizAvailable"
:pipeline="pipeline"
:column-title="columnTitle"
:type="type"

View File

@ -60,6 +60,15 @@ export default {
iid: this.pipelineIid,
};
},
loading() {
return this.$apollo.queries.jobs.loading;
},
showSkeletonLoader() {
return this.firstLoad && this.loading;
},
showLoadingSpinner() {
return !this.firstLoad && this.loading;
},
},
mounted() {
eventHub.$on('jobActionPerformed', this.handleJobAction);
@ -69,7 +78,7 @@ export default {
},
methods: {
handleJobAction() {
this.firstLoad = true;
this.firstLoad = false;
this.$apollo.queries.jobs.refetch();
},
@ -98,7 +107,7 @@ export default {
<template>
<div>
<div v-if="$apollo.loading && firstLoad" class="gl-mt-5">
<div v-if="showSkeletonLoader" class="gl-mt-5">
<gl-skeleton-loader :width="1248" :height="73">
<circle cx="748.031" cy="37.7193" r="15.0307" />
<circle cx="787.241" cy="37.7193" r="15.0307" />
@ -118,7 +127,7 @@ export default {
<jobs-table v-else :jobs="jobs" :table-fields="$options.fields" data-testid="jobs-tab-table" />
<gl-intersection-observer v-if="jobsPageInfo.hasNextPage" @appear="fetchMoreJobs">
<gl-loading-icon v-if="$apollo.loading" size="md" />
<gl-loading-icon v-if="showLoadingSpinner" size="md" />
</gl-intersection-observer>
</div>
</template>

View File

@ -1,8 +1,7 @@
<script>
import { GlIcon, GlLink, GlPopover, GlSprintf, GlTooltipDirective, GlBadge } from '@gitlab/ui';
import { __, sprintf } from '~/locale';
import { __ } from '~/locale';
import { helpPagePath } from '~/helpers/help_page_helper';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate/tooltip_on_truncate.vue';
import { SCHEDULE_ORIGIN, ICONS } from '../../constants';
@ -18,7 +17,6 @@ export default {
directives: {
GlTooltip: GlTooltipDirective,
},
mixins: [glFeatureFlagMixin()],
inject: {
targetProjectFullPath: {
default: '',
@ -139,91 +137,67 @@ export default {
commitTitle() {
return this.pipeline?.commit?.title;
},
hasAuthor() {
return (
this.commitAuthor?.avatar_url && this.commitAuthor?.path && this.commitAuthor?.username
);
},
userImageAltDescription() {
return this.commitAuthor?.username
? sprintf(__("%{username}'s avatar"), { username: this.commitAuthor.username })
: null;
},
rearrangePipelinesTable() {
return this.glFeatures?.rearrangePipelinesTable;
},
},
};
</script>
<template>
<div class="pipeline-tags" data-testid="pipeline-url-table-cell">
<template v-if="rearrangePipelinesTable">
<div class="commit-title gl-mb-2" data-testid="commit-title-container">
<span v-if="commitTitle" class="gl-display-flex">
<tooltip-on-truncate :title="commitTitle" class="flex-truncate-child gl-flex-grow-1">
<gl-link
:href="commitUrl"
class="commit-row-message gl-text-gray-900"
data-testid="commit-title"
>{{ commitTitle }}</gl-link
>
</tooltip-on-truncate>
</span>
<span v-else>{{ __("Can't find HEAD commit for this branch") }}</span>
</div>
<div class="gl-mb-2">
<gl-link
:href="pipeline.path"
class="gl-text-decoration-underline gl-text-blue-600! gl-mr-3"
data-testid="pipeline-url-link"
data-qa-selector="pipeline_url_link"
>
#{{ pipeline[pipelineKey] }}
</gl-link>
<!--Commit row-->
<div class="icon-container gl-display-inline-block gl-mr-1">
<gl-icon
v-gl-tooltip
:name="commitIcon"
:title="commitIconTooltipTitle"
data-testid="commit-icon-type"
/>
</div>
<tooltip-on-truncate :title="tooltipTitle" truncate-target="child" placement="top">
<div class="commit-title gl-mb-2" data-testid="commit-title-container">
<span v-if="commitTitle" class="gl-display-flex">
<tooltip-on-truncate :title="commitTitle" class="gl-flex-grow-1 gl-text-truncate">
<gl-link
v-if="mergeRequestRef"
:href="mergeRequestRef.path"
class="ref-name gl-mr-3"
data-testid="merge-request-ref"
>{{ mergeRequestRef.iid }}</gl-link
:href="commitUrl"
class="commit-row-message gl-text-gray-900"
data-testid="commit-title"
>{{ commitTitle }}</gl-link
>
<gl-link v-else :href="refUrl" class="ref-name gl-mr-3" data-testid="commit-ref-name">{{
commitRef.name
}}</gl-link>
</tooltip-on-truncate>
</span>
<span v-else>{{ __("Can't find HEAD commit for this branch") }}</span>
</div>
<div class="gl-mb-2">
<gl-link
:href="pipeline.path"
class="gl-text-decoration-underline gl-text-blue-600! gl-mr-3"
data-testid="pipeline-url-link"
data-qa-selector="pipeline_url_link"
>
#{{ pipeline[pipelineKey] }}
</gl-link>
<!--Commit row-->
<div class="icon-container gl-display-inline-block gl-mr-1">
<gl-icon
v-gl-tooltip
name="commit"
class="commit-icon gl-mr-1"
:title="__('Commit')"
data-testid="commit-icon"
:name="commitIcon"
:title="commitIconTooltipTitle"
data-testid="commit-icon-type"
/>
<gl-link :href="commitUrl" class="commit-sha mr-0" data-testid="commit-short-sha">{{
commitShortSha
}}</gl-link>
<!--End of commit row-->
</div>
</template>
<gl-link
v-if="!rearrangePipelinesTable"
:href="pipeline.path"
class="gl-text-decoration-underline"
data-testid="pipeline-url-link"
data-qa-selector="pipeline_url_link"
>
#{{ pipeline[pipelineKey] }}
</gl-link>
<tooltip-on-truncate :title="tooltipTitle" truncate-target="child" placement="top">
<gl-link
v-if="mergeRequestRef"
:href="mergeRequestRef.path"
class="ref-name gl-mr-3"
data-testid="merge-request-ref"
>{{ mergeRequestRef.iid }}</gl-link
>
<gl-link v-else :href="refUrl" class="ref-name gl-mr-3" data-testid="commit-ref-name">{{
commitRef.name
}}</gl-link>
</tooltip-on-truncate>
<gl-icon
v-gl-tooltip
name="commit"
class="commit-icon gl-mr-1"
:title="__('Commit')"
data-testid="commit-icon"
/>
<gl-link :href="commitUrl" class="commit-sha mr-0" data-testid="commit-short-sha">{{
commitShortSha
}}</gl-link>
<!--End of commit row-->
</div>
<div class="label-container gl-mt-1">
<gl-badge
v-if="isScheduled"

View File

@ -1,85 +0,0 @@
<script>
import { CHILD_VIEW } from '~/pipelines/constants';
import CommitComponent from '~/vue_shared/components/commit.vue';
export default {
components: {
CommitComponent,
},
props: {
pipeline: {
type: Object,
required: true,
},
viewType: {
type: String,
required: true,
},
},
computed: {
commitAuthor() {
let commitAuthorInformation;
if (!this.pipeline || !this.pipeline.commit) {
return null;
}
// 1. person who is an author of a commit might be a GitLab user
if (this.pipeline.commit.author) {
// 2. if person who is an author of a commit is a GitLab user
// they can have a GitLab avatar
if (this.pipeline.commit.author.avatar_url) {
commitAuthorInformation = this.pipeline.commit.author;
// 3. If GitLab user does not have avatar, they might have a Gravatar
} else if (this.pipeline.commit.author_gravatar_url) {
commitAuthorInformation = {
...this.pipeline.commit.author,
avatar_url: this.pipeline.commit.author_gravatar_url,
};
}
// 4. If committer is not a GitLab User, they can have a Gravatar
} else {
commitAuthorInformation = {
avatar_url: this.pipeline.commit.author_gravatar_url,
path: `mailto:${this.pipeline.commit.author_email}`,
username: this.pipeline.commit.author_name,
};
}
return commitAuthorInformation;
},
commitTag() {
return this.pipeline?.ref?.tag;
},
commitRef() {
return this.pipeline?.ref;
},
commitUrl() {
return this.pipeline?.commit?.commit_path;
},
commitShortSha() {
return this.pipeline?.commit?.short_id;
},
commitTitle() {
return this.pipeline?.commit?.title;
},
isChildView() {
return this.viewType === CHILD_VIEW;
},
},
};
</script>
<template>
<commit-component
:tag="commitTag"
:commit-ref="commitRef"
:commit-url="commitUrl"
:merge-request-ref="pipeline.merge_request"
:short-sha="commitShortSha"
:title="commitTitle"
:author="commitAuthor"
:show-ref-info="!isChildView"
/>
</template>

View File

@ -3,7 +3,6 @@ import CodeQualityWalkthrough from '~/code_quality_walkthrough/components/step.v
import { PIPELINE_STATUSES } from '~/code_quality_walkthrough/constants';
import { CHILD_VIEW } from '~/pipelines/constants';
import CiBadge from '~/vue_shared/components/ci_badge_link.vue';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import PipelinesTimeago from './time_ago.vue';
export default {
@ -12,7 +11,6 @@ export default {
CiBadge,
PipelinesTimeago,
},
mixins: [glFeatureFlagsMixin()],
props: {
pipeline: {
type: Object,
@ -44,9 +42,6 @@ export default {
codeQualityBuildPath() {
return this.pipeline?.details?.code_quality_build_path;
},
rearrangePipelinesTable() {
return this.glFeatures?.rearrangePipelinesTable;
},
},
};
</script>
@ -61,7 +56,7 @@ export default {
:icon-classes="'gl-vertical-align-middle!'"
data-qa-selector="pipeline_commit_status"
/>
<pipelines-timeago v-if="rearrangePipelinesTable" class="gl-mt-3" :pipeline="pipeline" />
<pipelines-timeago class="gl-mt-3" :pipeline="pipeline" />
<code-quality-walkthrough
v-if="shouldRenderCodeQualityWalkthrough"
:step="codeQualityStep"

View File

@ -1,16 +1,13 @@
<script>
import { GlTableLite, GlTooltipDirective } from '@gitlab/ui';
import { s__, __ } from '~/locale';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import eventHub from '../../event_hub';
import PipelineMiniGraph from './pipeline_mini_graph.vue';
import PipelineOperations from './pipeline_operations.vue';
import PipelineStopModal from './pipeline_stop_modal.vue';
import PipelineTriggerer from './pipeline_triggerer.vue';
import PipelineUrl from './pipeline_url.vue';
import PipelinesCommit from './pipelines_commit.vue';
import PipelinesStatusBadge from './pipelines_status_badge.vue';
import PipelinesTimeago from './time_ago.vue';
const DEFAULT_TD_CLASS = 'gl-p-5!';
const HIDE_TD_ON_MOBILE = 'gl-display-none! gl-lg-display-table-cell!';
@ -22,19 +19,16 @@ export default {
GlTableLite,
LinkedPipelinesMiniList: () =>
import('ee_component/vue_shared/components/linked_pipelines_mini_list.vue'),
PipelinesCommit,
PipelineMiniGraph,
PipelineOperations,
PipelinesStatusBadge,
PipelineStopModal,
PipelinesTimeago,
PipelineTriggerer,
PipelineUrl,
},
directives: {
GlTooltip: GlTooltipDirective,
},
mixins: [glFeatureFlagMixin()],
props: {
pipelines: {
type: Array,
@ -74,18 +68,16 @@ export default {
key: 'status',
label: s__('Pipeline|Status'),
thClass: DEFAULT_TH_CLASSES,
columnClass: this.rearrangePipelinesTable ? 'gl-w-15p' : 'gl-w-10p',
columnClass: 'gl-w-15p',
tdClass: DEFAULT_TD_CLASS,
thAttr: { 'data-testid': 'status-th' },
},
{
key: 'pipeline',
label: this.rearrangePipelinesTable ? __('Pipeline') : this.pipelineKeyOption.label,
label: __('Pipeline'),
thClass: DEFAULT_TH_CLASSES,
tdClass: this.rearrangePipelinesTable
? `${DEFAULT_TD_CLASS}`
: `${DEFAULT_TD_CLASS} ${HIDE_TD_ON_MOBILE}`,
columnClass: this.rearrangePipelinesTable ? 'gl-w-30p' : 'gl-w-10p',
tdClass: `${DEFAULT_TD_CLASS}`,
columnClass: 'gl-w-30p',
thAttr: { 'data-testid': 'pipeline-th' },
},
{
@ -96,14 +88,6 @@ export default {
columnClass: 'gl-w-10p',
thAttr: { 'data-testid': 'triggerer-th' },
},
{
key: 'commit',
label: s__('Pipeline|Commit'),
thClass: DEFAULT_TH_CLASSES,
tdClass: DEFAULT_TD_CLASS,
columnClass: 'gl-w-20p',
thAttr: { 'data-testid': 'commit-th' },
},
{
key: 'stages',
label: s__('Pipeline|Stages'),
@ -112,14 +96,6 @@ export default {
columnClass: 'gl-w-quarter',
thAttr: { 'data-testid': 'stages-th' },
},
{
key: 'timeago',
label: s__('Pipeline|Duration'),
thClass: DEFAULT_TH_CLASSES,
tdClass: DEFAULT_TD_CLASS,
columnClass: this.rearrangePipelinesTable ? 'gl-w-5p' : 'gl-w-15p',
thAttr: { 'data-testid': 'timeago-th' },
},
{
key: 'actions',
thClass: DEFAULT_TH_CLASSES,
@ -129,12 +105,7 @@ export default {
},
];
return !this.rearrangePipelinesTable
? fields
: fields.filter((field) => !['commit', 'timeago'].includes(field.key));
},
rearrangePipelinesTable() {
return this.glFeatures?.rearrangePipelinesTable;
return fields;
},
},
watch: {
@ -200,10 +171,6 @@ export default {
<pipeline-triggerer :pipeline="item" />
</template>
<template #cell(commit)="{ item }">
<pipelines-commit :pipeline="item" :view-type="viewType" />
</template>
<template #cell(stages)="{ item }">
<div class="stage-cell">
<!-- This empty div should be removed, see https://gitlab.com/gitlab-org/gitlab/-/issues/323488 -->
@ -229,10 +196,6 @@ export default {
</div>
</template>
<template #cell(timeago)="{ item }">
<pipelines-timeago :pipeline="item" />
</template>
<template #cell(actions)="{ item }">
<pipeline-operations :pipeline="item" :canceling-pipeline="cancelingPipeline" />
</template>

View File

@ -1,6 +1,5 @@
<script>
import { GlIcon, GlTooltipDirective } from '@gitlab/ui';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import timeagoMixin from '~/vue_shared/mixins/timeago';
export default {
@ -8,7 +7,7 @@ export default {
GlTooltip: GlTooltipDirective,
},
components: { GlIcon },
mixins: [timeagoMixin, glFeatureFlagMixin()],
mixins: [timeagoMixin],
props: {
pipeline: {
type: Object,
@ -54,14 +53,11 @@ export default {
showSkipped() {
return !this.duration && !this.finishedTime && this.skipped;
},
shouldDisplayAsBlock() {
return this.glFeatures?.rearrangePipelinesTable;
},
},
};
</script>
<template>
<div class="{ 'gl-display-block': shouldDisplayAsBlock }">
<div class="gl-display-block">
<span v-if="showInProgress" data-testid="pipeline-in-progress">
<gl-icon v-if="stuck" name="warning" class="gl-mr-2" :size="12" data-testid="warning-icon" />
<gl-icon

View File

@ -8,7 +8,7 @@ Vue.use(VueApollo);
const createPipelinesDetailApp = (
selector,
apolloProvider,
{ pipelineProjectPath, pipelineIid, metricsPath, graphqlResourceEtag } = {},
{ pipelineProjectPath, pipelineIid, metricsPath, graphqlResourceEtag, multiProjectHelpPath } = {},
) => {
// eslint-disable-next-line no-new
new Vue({
@ -22,6 +22,7 @@ const createPipelinesDetailApp = (
pipelineProjectPath,
pipelineIid,
graphqlResourceEtag,
multiProjectHelpPath,
},
errorCaptured(err, _vm, info) {
reportToSentry('pipeline_details_graph', `error: ${err}, info: ${info}`);

View File

@ -1,12 +1,7 @@
<script>
import { GlLink, GlIcon } from '@gitlab/ui';
import { escape } from 'lodash';
import { GlLink, GlIcon, GlSprintf } from '@gitlab/ui';
import { __, sprintf } from '~/locale';
function buildDocsLinkStart(path) {
return `<a href="${escape(path)}" target="_blank" rel="noopener noreferrer">`;
}
const NoteableTypeText = {
Issue: __('issue'),
Epic: __('epic'),
@ -17,6 +12,7 @@ export default {
components: {
GlIcon,
GlLink,
GlSprintf,
},
props: {
isLocked: {
@ -59,20 +55,6 @@ export default {
noteableTypeText() {
return NoteableTypeText[this.noteableType];
},
confidentialAndLockedDiscussionText() {
return sprintf(
__(
'This %{noteableTypeText} is %{confidentialLinkStart}confidential%{linkEnd} and %{lockedLinkStart}locked%{linkEnd}.',
),
{
noteableTypeText: this.noteableTypeText,
confidentialLinkStart: buildDocsLinkStart(this.confidentialNoteableDocsPath),
lockedLinkStart: buildDocsLinkStart(this.lockedNoteableDocsPath),
linkEnd: '</a>',
},
false,
);
},
confidentialContextText() {
return sprintf(__('This is a confidential %{noteableTypeText}.'), {
noteableTypeText: this.noteableTypeText,
@ -91,9 +73,23 @@ export default {
<gl-icon v-if="!isLockedAndConfidential" :name="warningIcon" :size="16" class="icon inline" />
<span v-if="isLockedAndConfidential" ref="lockedAndConfidential">
<span
v-html="confidentialAndLockedDiscussionText /* eslint-disable-line vue/no-v-html */"
></span>
<span>
<gl-sprintf
:message="
__(
'This %{noteableTypeText} is %{confidentialLinkStart}confidential%{confidentialLinkEnd} and %{lockedLinkStart}locked%{lockedLinkEnd}.',
)
"
>
<template #noteableTypeText>{{ noteableTypeText }}</template>
<template #confidentialLink="{ content }">
<gl-link :href="confidentialNoteableDocsPath" target="_blank">{{ content }}</gl-link>
</template>
<template #lockedLink="{ content }">
<gl-link :href="lockedNoteableDocsPath" target="_blank">{{ content }}</gl-link>
</template>
</gl-sprintf>
</span>
{{
__("People without permission will never get a notification and won't be able to comment.")
}}

View File

@ -0,0 +1,40 @@
<script>
import { GlBadge, GlIcon } from '@gitlab/ui';
import { s__ } from '~/locale';
const gitlabTiers = {
free: s__('GitlabTiers|Free'),
premium: s__('GitlabTiers|Premium'),
ultimate: s__('GitlabTiers|Ultimate'),
};
export default {
components: {
GlBadge,
GlIcon,
},
props: {
tier: {
type: String,
required: true,
validator: (value) => Object.keys(gitlabTiers).includes(value),
},
size: {
type: String,
required: false,
default: 'md',
},
},
computed: {
tierName() {
return gitlabTiers[this.tier];
},
},
};
</script>
<template>
<gl-badge :size="size" class="gl-text-purple-600! gl-font-weight-bold gl-bg-purple-50!">
<gl-icon name="license" /> {{ tierName }}
</gl-badge>
</template>

View File

@ -5,6 +5,8 @@ class Admin::CohortsController < Admin::ApplicationController
feature_category :devops_reports
urgency :low
def index
@cohorts = load_cohorts
track_cohorts_visit

View File

@ -9,6 +9,8 @@ class Admin::DevOpsReportController < Admin::ApplicationController
feature_category :devops_reports
urgency :low
# rubocop: disable CodeReuse/ActiveRecord
def show
@metric = DevOpsReport::Metric.order(:created_at).last&.present

View File

@ -2,6 +2,8 @@
class Admin::InstanceReviewController < Admin::ApplicationController
feature_category :devops_reports
urgency :low
def index
redirect_to("#{Gitlab::SubscriptionPortal.subscriptions_instance_review_url}?#{instance_review_params}")
end

View File

@ -7,6 +7,8 @@ class Admin::UsageTrendsController < Admin::ApplicationController
feature_category :devops_reports
urgency :low
def index
end
end

View File

@ -45,7 +45,6 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
push_frontend_feature_flag(:restructured_mr_widget, project, default_enabled: :yaml)
push_frontend_feature_flag(:refactor_mr_widgets_extensions, project, default_enabled: :yaml)
push_frontend_feature_flag(:rebase_without_ci_ui, project, default_enabled: :yaml)
push_frontend_feature_flag(:rearrange_pipelines_table, project, default_enabled: :yaml)
push_frontend_feature_flag(:markdown_continue_lists, project, default_enabled: :yaml)
# Usage data feature flags
push_frontend_feature_flag(:users_expanding_widgets_usage_data, project, default_enabled: :yaml)

View File

@ -16,9 +16,6 @@ class Projects::PipelinesController < Projects::ApplicationController
before_action :authorize_create_pipeline!, only: [:new, :create, :config_variables]
before_action :authorize_update_pipeline!, only: [:retry, :cancel]
before_action :ensure_pipeline, only: [:show, :downloadable_artifacts]
before_action do
push_frontend_feature_flag(:rearrange_pipelines_table, project, default_enabled: :yaml)
end
# Will be removed with https://gitlab.com/gitlab-org/gitlab/-/issues/225596
before_action :redirect_for_legacy_scope_filter, only: [:index], if: -> { request.format.html? }

View File

@ -47,6 +47,15 @@ query getPipelineDetails($projectPath: ID!, $iid: ID!) {
id
iid
complete
user {
__typename
id
namespace {
__typename
id
crossProjectPipelineAvailable
}
}
usesNeeds
userPermissions {
updatePipeline

View File

@ -38,7 +38,7 @@ module Types
description(enum_mod.description) if use_description
enum_mod.definition.each do |key, content|
value(key.to_s.upcase, **content)
value(key.to_s.upcase, value: key.to_s, description: content[:description])
end
end
# rubocop: enable Graphql/Descriptions

View File

@ -0,0 +1,15 @@
# frozen_string_literal: true
module Projects
module PipelineHelper
def js_pipeline_details_data(project, pipeline)
{
graphql_resource_etag: graphql_etag_pipeline_path(pipeline),
metrics_path: namespace_project_ci_prometheus_metrics_histograms_path(namespace_id: project.namespace, project_id: project, format: :json),
multi_project_help_path: help_page_path('ci/pipelines/multi_project_pipelines.md', anchor: 'multi-project-pipeline-visualization'),
pipeline_iid: pipeline.iid,
pipeline_project_path: project.full_path
}
end
end
end

View File

@ -12,21 +12,32 @@ module Boards
end
# rubocop: disable CodeReuse/ActiveRecord
def metadata
issuables = item_model.arel_table
keys = metadata_fields.keys
def metadata(required_fields = [:issue_count, :total_issue_weight])
fields = metadata_fields(required_fields)
keys = fields.keys
# TODO: eliminate need for SQL literal fragment
columns = Arel.sql(metadata_fields.values_at(*keys).join(', '))
results = item_model.where(id: init_collection.select(issuables[:id])).pluck(columns)
columns = Arel.sql(fields.values_at(*keys).join(', '))
results = item_model.where(id: collection_ids)
results = query_additions(results, required_fields)
results = results.select(columns)
Hash[keys.zip(results.flatten)]
Hash[keys.zip(results.pluck(columns).flatten)]
end
# rubocop: enable CodeReuse/ActiveRecord
private
def metadata_fields
{ size: 'COUNT(*)' }
# override if needed
def query_additions(items, required_fields)
items
end
def collection_ids
@collection_ids ||= init_collection.select(item_model.arel_table[:id])
end
def metadata_fields(required_fields)
required_fields&.include?(:issue_count) ? { size: 'COUNT(*)' } : {}
end
def order(items)

View File

@ -4,11 +4,13 @@ module IssuableLinks
class DestroyService < BaseService
include IncidentManagement::UsageData
attr_reader :link, :current_user
attr_reader :link, :current_user, :source, :target
def initialize(link, user)
@link = link
@current_user = user
@source = link.source
@target = link.target
end
def execute
@ -22,6 +24,11 @@ module IssuableLinks
private
def create_notes
SystemNoteService.unrelate_issuable(source, target, current_user)
SystemNoteService.unrelate_issuable(target, source, current_user)
end
def after_destroy
create_notes
track_event

View File

@ -4,23 +4,10 @@ module IssueLinks
class DestroyService < IssuableLinks::DestroyService
private
def source
@source ||= link.source
end
def target
@target ||= link.target
end
def permission_to_remove_relation?
can?(current_user, :admin_issue_link, source) && can?(current_user, :admin_issue_link, target)
end
def create_notes
SystemNoteService.unrelate_issue(source, target, current_user)
SystemNoteService.unrelate_issue(target, source, current_user)
end
def track_event
track_incident_action(current_user, target, :incident_unrelate)
end

View File

@ -53,8 +53,8 @@ module SystemNoteService
::SystemNotes::IssuablesService.new(noteable: noteable, project: noteable.project, author: user).relate_issue(noteable_ref)
end
def unrelate_issue(noteable, noteable_ref, user)
::SystemNotes::IssuablesService.new(noteable: noteable, project: noteable.project, author: user).unrelate_issue(noteable_ref)
def unrelate_issuable(noteable, noteable_ref, user)
::SystemNotes::IssuablesService.new(noteable: noteable, project: noteable.project, author: user).unrelate_issuable(noteable_ref)
end
# Called when the due_date of a Noteable is changed

View File

@ -26,8 +26,8 @@ module SystemNotes
# "removed the relation with gitlab-foss#9001"
#
# Returns the created Note object
def unrelate_issue(noteable_ref)
body = "removed the relation with #{noteable_ref.to_reference(noteable.project)}"
def unrelate_issuable(noteable_ref)
body = "removed the relation with #{noteable_ref.to_reference(noteable.resource_parent)}"
issue_activity_counter.track_issue_unrelated_action(author: author) if noteable.is_a?(Issue)

View File

@ -42,10 +42,20 @@ module WebHooks
hook.failed!
end
end
rescue Gitlab::ExclusiveLeaseHelpers::FailedToObtainLockError
raise if raise_lock_error?
end
def lock_name
"web_hooks:update_hook_failure_state:#{hook.id}"
end
# Allow an error to be raised after failing to obtain a lease only if the hook
# is not already in the correct failure state.
def raise_lock_error?
hook.reset # Reload so properties are guaranteed to be current.
hook.executable? != (response_category == :ok)
end
end
end

View File

@ -29,4 +29,4 @@
#js-pipeline-notification{ data: { deprecated_keywords_doc_path: help_page_path('ci/yaml/index.md', anchor: 'deprecated-keywords'), full_path: @project.full_path, pipeline_iid: @pipeline.iid } }
= render "projects/pipelines/with_tabs", pipeline: @pipeline, stages: @stages, pipeline_has_errors: pipeline_has_errors
.js-pipeline-details-vue{ data: { metrics_path: namespace_project_ci_prometheus_metrics_histograms_path(namespace_id: @project.namespace, project_id: @project, format: :json), pipeline_project_path: @project.full_path, pipeline_iid: @pipeline.iid, graphql_resource_etag: graphql_etag_pipeline_path(@pipeline) } }
.js-pipeline-details-vue{ data: js_pipeline_details_data(@project, @pipeline) }

View File

@ -31,6 +31,7 @@
- continuous_delivery
- continuous_integration
- continuous_integration_scaling
- continuous_verification
- database
- dataops
- delivery
@ -74,7 +75,6 @@
- kubernetes_management
- license
- license_compliance
- live_preview
- logging
- memory
- merge_trains
@ -110,7 +110,6 @@
- secrets_management
- security_benchmarking
- security_orchestration
- self_monitoring
- service_desk
- service_ping
- sharding
@ -119,7 +118,6 @@
- static_application_security_testing
- static_site_editor
- subgroups
- synthetic_monitoring
- team_planning
- tracing
- usage_ping

View File

@ -1,7 +1,7 @@
---
name: ci_pending_builds_maintain_denormalized_data
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75425
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/332951
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/354496
milestone: '14.6'
type: development
group: group::pipeline execution

View File

@ -1,7 +1,7 @@
---
name: ci_pending_builds_queue_source
introduced_by_url:
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350884
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/354496
milestone: '14.0'
type: development
group: group::pipeline execution

View File

@ -1,7 +1,7 @@
---
name: ci_queuing_use_denormalized_data_strategy
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76543
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/332951
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/354496
milestone: '14.6'
type: development
group: group::pipeline execution

View File

@ -1,8 +1,8 @@
---
name: rearrange_pipelines_table
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/72545
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/343286
milestone: '14.8'
name: container_registry_follow_redirects_middleware
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81056
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/353291
milestone: '14.9'
type: development
group: group::pipeline execution
default_enabled: true
group: group::package
default_enabled: false

View File

@ -62,3 +62,27 @@
- 'i_testing_group_code_coverage_visit_total'
- 'i_testing_load_performance_widget_total'
- 'i_testing_metrics_report_widget_total'
- name: xmau_plan
operator: OR
source: redis
time_frame: [7d, 28d]
events:
- users_creating_work_items
- users_updating_work_item_title
feature_flag: track_work_items_activity
- name: xmau_project_management
operator: OR
source: redis
time_frame: [7d, 28d]
events:
- users_creating_work_items
- users_updating_work_item_title
feature_flag: track_work_items_activity
- name: users_work_items
operator: OR
source: redis
time_frame: [7d, 28d]
events:
- users_creating_work_items
- users_updating_work_item_title
feature_flag: track_work_items_activity

View File

@ -0,0 +1,21 @@
---
key_path: counts_monthly.aggregated_metrics.xmau_plan
description: Unique users interacting with Plan features
product_category: team planning
product_section: dev
product_stage: plan
product_group: group::project management
value_type: number
status: active
milestone: '14.9'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81336
time_frame: 28d
data_source: redis_hll
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate

View File

@ -0,0 +1,21 @@
---
key_path: counts_monthly.aggregated_metrics.xmau_project_management
description: Unique users interacting with Project Management features
product_category: team planning
product_section: dev
product_stage: plan
product_group: group::project management
value_type: number
status: active
milestone: '14.9'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81336
time_frame: 28d
data_source: redis_hll
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate

View File

@ -0,0 +1,21 @@
---
key_path: counts_monthly.aggregated_metrics.users_work_items
description: Unique users interacting with work items
product_category: team planning
product_section: dev
product_stage: plan
product_group: group::product planning
value_type: number
status: active
milestone: '14.9'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81336
time_frame: 28d
data_source: redis_hll
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate

View File

@ -0,0 +1,21 @@
---
key_path: counts_weekly.aggregated_metrics.xmau_plan
description: Unique users interacting with Plan features
product_category: team planning
product_section: dev
product_stage: plan
product_group: group::project management
value_type: number
status: active
milestone: '14.9'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81336
time_frame: 7d
data_source: redis_hll
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate

View File

@ -0,0 +1,21 @@
---
key_path: counts_weekly.aggregated_metrics.xmau_project_management
description: Unique users interacting with Project Management features
product_category: team planning
product_section: dev
product_stage: plan
product_group: group::project management
value_type: number
status: active
milestone: '14.9'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81336
time_frame: 7d
data_source: redis_hll
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate

View File

@ -0,0 +1,21 @@
---
key_path: counts_weekly.aggregated_metrics.users_work_items
description: Unique users interacting with work items
product_category: team planning
product_section: dev
product_stage: plan
product_group: group::product planning
value_type: number
status: active
milestone: '14.9'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81336
time_frame: 7d
data_source: redis_hll
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate

View File

@ -8,8 +8,8 @@
We are changing how the date filter works in Value Stream Analytics. Instead of filtering by the time that the issue or merge request was created, the date filter will filter by the end event time of the given stage. This will result in completely different figures after this change has rolled out.
If you monitor Value Stream Analytics metrics and rely on the date filter, to avoid losing data, you must save the data prior to this change.
stage: manage # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
stage: manage # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
issue_url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/343210' # (optional) This is a link to the deprecation issue in GitLab
issue_url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/343210' # (optional) This is a link to the deprecation issue in GitLab
documentation_url: "https://docs.gitlab.com/ee/user/analytics/value_stream_analytics.html#filter-value-stream-analytics-data" # (optional) This is a link to the current documentation page
image_url: "vsa_warning.png" # (optional) This is a link to a thumbnail image depicting the feature

View File

@ -18,9 +18,9 @@
[warning](https://gitlab.com/gitlab-org/gitlab/-/issues/335789#note_672853791)
in the Vulnerability Report.
# The following items are not published on the docs page, but may be used in the future.
stage: Secure # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
tiers: [Core, Premium, Ultimate] # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
issue_url: https://gitlab.com/groups/gitlab-org/-/epics/6968 # (optional) This is a link to the deprecation issue in GitLab
stage: Secure # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
tiers: [Core, Premium, Ultimate] # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
issue_url: https://gitlab.com/groups/gitlab-org/-/epics/6968 # (optional) This is a link to the deprecation issue in GitLab
documentation_url: # (optional) This is a link to the current documentation page
image_url: # (optional) This is a link to a thumbnail image depicting the feature
video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg

View File

@ -8,9 +8,9 @@
If you are using our License Compliance API you should stop using the `approved` and `blacklisted` query parameters, they are now `allowed` and `denied`. In 15.0 the responses will also stop using `approved` and `blacklisted` so you need to adjust any of your custom tools to use the old and new values so they do not break with the 15.0 release.
# The following items are not published on the docs page, but may be used in the future.
stage: secure # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
tiers: ultimate # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/335707 # (optional) This is a link to the deprecation issue in GitLab
stage: secure # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
tiers: ultimate # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/335707 # (optional) This is a link to the deprecation issue in GitLab
documentation_url: # (optional) This is a link to the current documentation page
image_url: # (optional) This is a link to a thumbnail image depicting the feature
video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg

View File

@ -8,10 +8,10 @@
If you have explicitly excluded bundler-audit using DS_EXCLUDED_ANALYZERS you will need to clean up (remove the reference) in 15.0. If you have customized your pipeline's Dependency Scanning configuration, for example to edit the `bundler-audit-dependency_scanning` job, you will want to switch to gemnasium-dependency_scanning before removal in 15.0, to prevent your pipeline from failing. If you have not used the DS_EXCLUDED_ANALYZERS to reference bundler-audit, or customized your template specifically for bundler-audit, you will not need to take action.
# The following items are not published on the docs page, but may be used in the future.
stage: secure # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
tiers: ultimate # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/289832 # (optional) This is a link to the deprecation issue in GitLab
documentation_url: https://docs.gitlab.com/ee/user/application_security/dependency_scanning/analyzers.html # (optional) This is a link to the current documentation page
stage: secure # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
tiers: ultimate # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/289832 # (optional) This is a link to the deprecation issue in GitLab
documentation_url: https://docs.gitlab.com/ee/user/application_security/dependency_scanning/analyzers.html # (optional) This is a link to the current documentation page
image_url: # (optional) This is a link to a thumbnail image depicting the feature
video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
removal_date: "2022-05-22" # (optional - may be required in the future) YYYY-MM-DD format. This should almost always be the 22nd of a month (YYYY-MM-22), the date of the milestone release when this feature is planned to be removed

View File

@ -9,7 +9,7 @@
# The following items are not published on the docs page, but may be used in the future.
stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/342800 # (optional) This is a link to the deprecation issue in GitLab
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/342800 # (optional) This is a link to the deprecation issue in GitLab
documentation_url: # (optional) This is a link to the current documentation page
image_url: # (optional) This is a link to a thumbnail image depicting the feature
video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg

View File

@ -15,13 +15,13 @@
announcement_date: "2022-01-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
removal_milestone: "15.0" # The milestone when this feature is planned to be removed
removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
breaking_change: true # If this deprecation is a breaking change, set this value to true
breaking_change: true # If this deprecation is a breaking change, set this value to true
body: | # Do not modify this line, instead modify the lines below.
The `merged_by` field in the [merge request API](https://docs.gitlab.com/ee/api/merge_requests.html#list-merge-requests) is being deprecated and will be removed in GitLab 15.0. This field is being replaced with the `merge_user` field (already present in GraphQL) which more correctly identifies who merged a merge request when performing actions (merge when pipeline succeeds, add to merge train) other than a simple merge.
# The following items are not published on the docs page, but may be used in the future.
stage: create # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
stage: create # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350534 # (optional) This is a link to the deprecation issue in GitLab
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350534 # (optional) This is a link to the deprecation issue in GitLab
documentation_url: # (optional) This is a link to the current documentation page
image_url: # (optional) This is a link to a thumbnail image depicting the feature
video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg

View File

@ -6,9 +6,9 @@
body: | # Do not modify this line, instead modify the lines below.
The Static Site Editor will no longer be available starting in GitLab 15.0. Improvements to the Markdown editing experience across GitLab will deliver smiliar benefit but with a wider reach. Incoming requests to the Static Site Editor will be redirected to the Web IDE. Current users of the Static Site Editor can view the [documentation](https://docs.gitlab.com/ee/user/project/static_site_editor/) for more information, including how to remove the configuration files from existing projects.
# The following items are not published on the docs page, but may be used in the future.
stage: Create # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
tiers: [Free, Premium, Ultimate] # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/347137 # (optional) This is a link to the deprecation issue in GitLab
documentation_url: https://docs.gitlab.com/ee/user/project/static_site_editor/ # (optional) This is a link to the current documentation page
stage: Create # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
tiers: [Free, Premium, Ultimate] # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/347137 # (optional) This is a link to the deprecation issue in GitLab
documentation_url: https://docs.gitlab.com/ee/user/project/static_site_editor/ # (optional) This is a link to the current documentation page
image_url: # (optional) This is a link to a thumbnail image depicting the feature
video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg

View File

@ -8,10 +8,10 @@
If you have explicitly excluded retire.js using DS_EXCLUDED_ANALYZERS you will need to clean up (remove the reference) in 15.0. If you have customized your pipeline's Dependency Scanning configuration related to the `retire-js-dependency_scanning` job you will want to switch to gemnasium-dependency_scanning before the removal in 15.0, to prevent your pipeline from failing. If you have not used the DS_EXCLUDED_ANALYZERS to reference retire.js, or customized your template specifically for retire.js, you will not need to take action.
# The following items are not published on the docs page, but may be used in the future.
stage: secure # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
tiers: ultimate # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350510 # (optional) This is a link to the deprecation issue in GitLab
documentation_url: https://docs.gitlab.com/ee/user/application_security/dependency_scanning/analyzers.html # (optional) This is a link to the current documentation page
stage: secure # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
tiers: ultimate # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350510 # (optional) This is a link to the deprecation issue in GitLab
documentation_url: https://docs.gitlab.com/ee/user/application_security/dependency_scanning/analyzers.html # (optional) This is a link to the current documentation page
image_url: # (optional) This is a link to a thumbnail image depicting the feature
video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
removal_date: "2022-05-22" # (optional - may be required in the future) YYYY-MM-DD format. This should almost always be the 22nd of a month (YYYY-MM-22), the date of the milestone release when this feature is planned to be removed

View File

@ -3,8 +3,8 @@
announcement_date: "2022-02-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
removal_milestone: "15.0" # The milestone when this feature is planned to be removed
removal_date: "2022-05-22" # The date of the milestone release when this feature is planned to be removed. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
breaking_change: true # If this deprecation is a breaking change, set this value to true
reporter: djensen # GitLab username of the person reporting the deprecation
breaking_change: true # If this deprecation is a breaking change, set this value to true
reporter: djensen # GitLab username of the person reporting the deprecation
body: | # Do not modify this line, instead modify the lines below.
The feature to disable enforcement of PAT expiration is unusual from a security perspective.
We have become concerned that this unusual feature could create unexpected behavior for users.

View File

@ -3,8 +3,8 @@
announcement_date: "2022-02-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
removal_milestone: "15.0" # The milestone when this feature is planned to be removed
removal_date: "2022-05-22" # The date of the milestone release when this feature is planned to be removed. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
breaking_change: true # If this deprecation is a breaking change, set this value to true
reporter: djensen # GitLab username of the person reporting the deprecation
breaking_change: true # If this deprecation is a breaking change, set this value to true
reporter: djensen # GitLab username of the person reporting the deprecation
body: | # Do not modify this line, instead modify the lines below.
The feature to disable enforcement of SSH expiration is unusual from a security perspective.
We have become concerned that this unusual feature could create unexpected behavior for users.

View File

@ -2,7 +2,7 @@
announcement_milestone: "14.8" # The milestone when this feature was first announced as deprecated.
announcement_date: "2022-02-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
removal_milestone: "15.0" # The milestone when this feature is planned to be removed
removal_date: 2022-05-22 # The date of the milestone release when this feature is planned to be removed. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
removal_date: "2022-05-22" # The date of the milestone release when this feature is planned to be removed. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
breaking_change: true # If this deprecation is a breaking change, set this value to true
reporter: jacobvosmaer-gitlab # GitLab username of the person reporting the deprecation
body: | # Do not modify this line, instead modify the lines below.

View File

@ -3,7 +3,7 @@
announcement_date: "2022-02-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
removal_milestone: "15.0" # The milestone when this feature is planned to be removed
removal_date: "2022-05-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
breaking_change: true # If this deprecation is a breaking change, set this value to true
breaking_change: true # If this deprecation is a breaking change, set this value to true
body: | # Do not modify this line, instead modify the lines below.
The `started` field in the [iterations API](https://docs.gitlab.com/ee/api/iterations.html#list-project-iterations) is being deprecated and will be removed in GitLab 15.0. This field is being replaced with the `current` field (already available) which aligns with the naming for other time-based entities, such as milestones.
# The following items are not published on the docs page, but may be used in the future.

View File

@ -20,7 +20,7 @@
- [Distributed read capabilities](https://docs.gitlab.com/ee/administration/gitaly/#distributed-reads)
# The following items are not published on the docs page, but may be used in the future.
stage: Gitaly # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
stage: Gitaly # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
issue_url: # (optional) This is a link to the deprecation issue in GitLab
documentation_url: # (optional) This is a link to the current documentation page

View File

@ -3,14 +3,14 @@
announcement_date: "2022-02-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
removal_milestone: "15.0" # The milestone when this feature is planned to be removed
removal_date: "2022-05-22" # The date of the milestone release when this feature is planned to be removed. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
breaking_change: true # If this deprecation is a breaking change, set this value to true
breaking_change: true # If this deprecation is a breaking change, set this value to true
reporter: sarahwaldner # GitLab username of the person reporting the deprecation
body: | # Do not modify this line, instead modify the lines below.
The feature flag `PUSH_RULES_SUPERSEDE_CODE_OWNERS` is being removed in GitLab 15.0. Upon its removal, push rules will supersede CODEOWNERS. The CODEOWNERS feature will no longer be available for access control.
# The following items are not published on the docs page, but may be used in the future.
stage: create # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
stage: create # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/262019 # (optional) This is a link to the deprecation issue in GitLab
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/262019 # (optional) This is a link to the deprecation issue in GitLab
documentation_url: # (optional) This is a link to the current documentation page
image_url: # (optional) This is a link to a thumbnail image depicting the feature
video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg

View File

@ -39,7 +39,7 @@
- `sobelow`: version 2
- `spotbugs`: version 2
# The following items are not published on the docs page, but may be used in the future.
stage: secure, protect # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
tiers: Free, Silver, Gold, Core, Premium, Ultimate # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350936 # (optional) This is a link to the deprecation issue in GitLab
stage: secure, protect # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
tiers: Free, Silver, Gold, Core, Premium, Ultimate # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350936 # (optional) This is a link to the deprecation issue in GitLab
documentation_url: # (optional) This is a link to the current documentation page

View File

@ -2,8 +2,8 @@
announcement_milestone: "14.8" # The milestone when this feature was first announced as deprecated.
announcement_date: "2021-02-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
removal_milestone: "15.0" # The milestone when this feature is planned to be removed
removal_date: 2021-05-22 # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
breaking_change: true # If this deprecation is a breaking change, set this value to true
removal_date: "2021-05-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
breaking_change: true # If this deprecation is a breaking change, set this value to true
body: | # Do not modify this line, instead modify the lines below.
For those using Dependency Scanning for Python projects, we are deprecating the default `gemnasium-python:2` image which uses Python 3.6 as well as the custom `gemnasium-python:2-python-3.9` image which uses Python 3.9. The new default image as of GitLab 15.0 will be for Python 3.9 as it is a [supported version](https://endoflife.date/python) and 3.6 [is no longer supported](https://endoflife.date/python).
@ -25,9 +25,9 @@
name: registry.gitlab.com/gitlab-org/security-products/analyzers/gemnasium-python:2-python-3.9
```
# The following items are not published on the docs page, but may be used in the future.
stage: secure # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
tiers: ultimate # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/334060 # (optional) This is a link to the deprecation issue in GitLab
stage: secure # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
tiers: ultimate # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/334060 # (optional) This is a link to the deprecation issue in GitLab
documentation_url: # (optional) This is a link to the current documentation page
image_url: # (optional) This is a link to a thumbnail image depicting the feature
video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg

View File

@ -3,13 +3,13 @@
announcement_date: "2022-01-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
removal_milestone: "15.0" # The milestone when this feature is planned to be removed
removal_date: "2022-05-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
breaking_change: true # If this deprecation is a breaking change, set this value to true
breaking_change: true # If this deprecation is a breaking change, set this value to true
body: | # Do not modify this line, instead modify the lines below.
The logging features in GitLab allow users to install the ELK stack (Elasticsearch, Logstash, and Kibana) to aggregate and manage application logs. Users can search for relevant logs in GitLab. However, since deprecating certificate-based integration with Kubernetes clusters and GitLab Managed Apps, we don't have a recommended solution for logging within GitLab. For more information, you can follow the issue for [integrating Opstrace with GitLab](https://gitlab.com/groups/gitlab-org/-/epics/6976).
# The following items are not published on the docs page, but may be used in the future.
stage: Monitor # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
tiers: [Free] # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/346485 # (optional) This is a link to the deprecation issue in GitLab
documentation_url: https://docs.gitlab.com/ee/operations/#aggregate-and-store-logs-deprecated # (optional) This is a link to the current documentation page
stage: Monitor # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
tiers: [Free] # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/346485 # (optional) This is a link to the deprecation issue in GitLab
documentation_url: https://docs.gitlab.com/ee/operations/#aggregate-and-store-logs-deprecated # (optional) This is a link to the current documentation page
image_url: # (optional) This is a link to a thumbnail image depicting the feature
video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg

View File

@ -3,14 +3,14 @@
announcement_date: "2022-01-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
removal_milestone: "15.0" # The milestone when this feature is planned to be removed
removal_date: "2022-05-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
breaking_change: true # If this deprecation is a breaking change, set this value to true
breaking_change: true # If this deprecation is a breaking change, set this value to true
body: | # Do not modify this line, instead modify the lines below.
By displaying data stored in a Prometheus instance, GitLab allows users to view performance metrics. GitLab also displays visualizations of these metrics in dashboards. The user can connect to a previously-configured external Prometheus instance, or set up Prometheus as a GitLab Managed App.
However, since certificate-based integration with Kubernetes clusters is deprecated in GitLab, the metrics functionality in GitLab that relies on Prometheus is also deprecated. This includes the metrics visualizations in dashboards. GitLab is working to develop a single user experience based on [Opstrace](https://about.gitlab.com/press/releases/2021-12-14-gitlab-acquires-opstrace-to-expand-its-devops-platform-with-open-source-observability-solution.html). An [issue exists](https://gitlab.com/groups/gitlab-org/-/epics/6976) for you to follow work on the Opstrace integration.
# The following items are not published on the docs page, but may be used in the future.
stage: Monitor # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
tiers: [Free] # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/346541 # (optional) This is a link to the deprecation issue in GitLab
documentation_url: https://docs.gitlab.com/ee/operations/metrics/dashboards/ # (optional) This is a link to the current documentation page
stage: Monitor # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
tiers: [Free] # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/346541 # (optional) This is a link to the deprecation issue in GitLab
documentation_url: https://docs.gitlab.com/ee/operations/metrics/dashboards/ # (optional) This is a link to the current documentation page
image_url: # (optional) This is a link to a thumbnail image depicting the feature
video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg

View File

@ -3,13 +3,13 @@
announcement_date: "2022-01-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
removal_milestone: "15.0" # The milestone when this feature is planned to be removed
removal_date: "2022-05-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
breaking_change: true # If this deprecation is a breaking change, set this value to true
breaking_change: true # If this deprecation is a breaking change, set this value to true
body: | # Do not modify this line, instead modify the lines below.
Tracing in GitLab is an integration with Jaeger, an open-source end-to-end distributed tracing system. GitLab users can navigate to their Jaeger instance to gain insight into the performance of a deployed application, tracking each function or microservice that handles a given request. Tracing in GitLab is deprecated in GitLab 14.7, and scheduled for removal in 15.0. To track work on a possible replacement, see the issue for [Opstrace integration with GitLab](https://gitlab.com/groups/gitlab-org/-/epics/6976).
# The following items are not published on the docs page, but may be used in the future.
stage: Monitor # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
tiers: [Free] # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/346540 # (optional) This is a link to the deprecation issue in GitLab
documentation_url: https://docs.gitlab.com/ee/operations/tracing.html#tracing # (optional) This is a link to the current documentation page
stage: Monitor # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
tiers: [Free] # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/346540 # (optional) This is a link to the deprecation issue in GitLab
documentation_url: https://docs.gitlab.com/ee/operations/tracing.html#tracing # (optional) This is a link to the current documentation page
image_url: # (optional) This is a link to a thumbnail image depicting the feature
video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg

View File

@ -2,8 +2,8 @@
announcement_milestone: "14.8" # The milestone when this feature was first announced as deprecated.
announcement_date: "2022-02-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
removal_milestone: "15.0" # The milestone when this feature is planned to be removed
removal_date: 2022-05-22 # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
breaking_change: true # If this deprecation is a breaking change, set this value to true
removal_date: "2022-05-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
breaking_change: true # If this deprecation is a breaking change, set this value to true
body: | # Do not modify this line, instead modify the lines below.
By default, all new applications expire access tokens after 2 hours. In GitLab 14.2 and earlier, OAuth access tokens
had no expiration. In GitLab 15.0, an expiry will be automatically generated for any existing token that does not

View File

@ -2,7 +2,7 @@
announcement_milestone: "14.0" # The milestone when this feature was first announced as deprecated.
announcement_date: "2021-06-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
removal_milestone: "15.0" # The milestone when this feature is planned to be removed
removal_date: 2022-05-22 # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
removal_date: "2022-05-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
breaking_change: yes # If this deprecation is a breaking change, set this value to true
body: | # Do not modify this line, instead modify the lines below.
The OAuth implicit grant authorization flow will be removed in our next major release, GitLab 15.0. Any applications that use OAuth implicit grant should switch to alternative [supported OAuth flows](https://docs.gitlab.com/ee/api/oauth2.html).

View File

@ -1,7 +1,7 @@
- name: "Max job log file size of 100 MB"
removal_date: August 22, 2021 # day the removal was released
removal_date: August 22, 2021 # day the removal was released
removal_milestone: "14.2"
reporter: jreporter # GitLab username of the person reporting the removal
reporter: jreporter # GitLab username of the person reporting the removal
breaking_change: false
body: |
GitLab values efficiency for all users in our wider community of contributors, so we're always working hard to make sure the application performs at a high level with a lovable UX.

View File

@ -5,5 +5,5 @@
breaking_change: false
body: | # example (supports markdown)
The support for [`gitlab_pages['use_legacy_storage']` setting](https://docs.gitlab.com/ee/administration/pages/index.html#domain-source-configuration-before-140) in Omnibus installations has been removed.
In 14.0 we removed [`domain_config_source`](https://docs.gitlab.com/ee/administration/pages/index.html#domain-source-configuration-before-140) which had been previously deprecated, and allowed users to specify disk storage. In 14.0 we added `use_legacy_storage` as a **temporary** flag to unblock upgrades, and allow us to debug issues with our users and it was deprecated and communicated for removal in 14.3.

View File

@ -1,6 +1,6 @@
- name: "Limit the number of triggered pipeline to 25K in free tier"
removal_date: Dec 22, 2021 # day the removal was released
removal_date: Dec 22, 2021 # day the removal was released
removal_milestone: "14.6"
reporter: dhershkovitch # GitLab username of the person reporting the removal
reporter: dhershkovitch # GitLab username of the person reporting the removal
body: |
A large amount of triggered pipelines in a single project impacts the performance of GitLab.com. In GitLab 14.6, we are limiting the number of triggered pipelines in a single project on GitLab.com at any given moment to 25,000. This change applies to projects in the free tier only, Premium and Ultimate are not affected by this change.

View File

@ -1,6 +1,6 @@
- name: "Release CLI distributed as a generic package"
removal_date: Dec 22, 2021 # day the removal was released
removal_date: Dec 22, 2021 # day the removal was released
removal_milestone: "14.6"
reporter: kbychu # GitLab username of the person reporting the removal
reporter: kbychu # GitLab username of the person reporting the removal
body: |
The [release-cli](https://gitlab.com/gitlab-org/release-cli) will be released as a [generic package](https://gitlab.com/gitlab-org/release-cli/-/packages) starting in GitLab 14.2. We will continue to deploy it as a binary to S3 until GitLab 14.5 and stop distributing it in S3 in GitLab 14.6.

View File

@ -0,0 +1,17 @@
# frozen_string_literal: true
class AddIndexToIssues < Gitlab::Database::Migration[1.0]
DOWNTIME = false
disable_ddl_transaction!
INDEX_NAME = 'index_issues_on_id_and_weight'
def up
add_concurrent_index :issues, [:id, :weight], name: INDEX_NAME
end
def down
remove_concurrent_index_by_name :issues, INDEX_NAME
end
end

View File

@ -0,0 +1,25 @@
# frozen_string_literal: true
class ScheduleMigratePersonalNamespaceProjectMaintainerToOwner < Gitlab::Database::Migration[1.0]
MIGRATION = 'MigratePersonalNamespaceProjectMaintainerToOwner'
INTERVAL = 2.minutes
BATCH_SIZE = 1_000
SUB_BATCH_SIZE = 200
disable_ddl_transaction!
def up
queue_batched_background_migration(
MIGRATION,
:members,
:id,
job_interval: INTERVAL,
batch_size: BATCH_SIZE,
sub_batch_size: SUB_BATCH_SIZE
)
end
def down
# no-op
end
end

View File

@ -0,0 +1 @@
688232dde01ea4e8574dca73459094264bde405d799ecaf1a5867adb72576b98

View File

@ -0,0 +1 @@
84346c2f608792f259ab91dbc2c8aac8397a2997f890f8e077aad809276bb7cd

View File

@ -27884,6 +27884,8 @@ CREATE INDEX index_issues_on_description_trigram ON issues USING gin (descriptio
CREATE INDEX index_issues_on_duplicated_to_id ON issues USING btree (duplicated_to_id) WHERE (duplicated_to_id IS NOT NULL);
CREATE INDEX index_issues_on_id_and_weight ON issues USING btree (id, weight);
CREATE INDEX index_issues_on_incident_issue_type ON issues USING btree (issue_type) WHERE (issue_type = 1);
CREATE INDEX index_issues_on_last_edited_by_id ON issues USING btree (last_edited_by_id);

View File

@ -208,13 +208,18 @@ When the number exceeds the limit the page displays an alert and links to a pagi
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/51401) in GitLab 11.10.
The number of pipelines that can be created in a single push is 4.
This limit prevents the accidental creation of pipelines when `git push --all`
or `git push --mirror` is used.
When pushing multiple changes with a single Git push, like multiple tags or branches,
only four tag or branch pipelines can be triggered. This limit prevents the accidental
creation of a large number of pipelines when using `git push --all` or `git push --mirror`.
This limit does not affect any of the updated merge request pipelines.
All updated merge requests have a pipeline created when using
[merge request pipelines](../ci/pipelines/merge_request_pipelines.md).
[Merge request pipelines](../ci/pipelines/merge_request_pipelines.md) are not limited.
If the Git push updates multiple merge requests at the same time, a merge request pipeline
can trigger for every updated merge request.
To remove the limit so that any number of pipelines can trigger for a single Git push event,
administrators can enable the `git_push_create_all_pipelines` [feature flag](feature_flags.md).
Enabling this feature flag is not recommended, as it can cause excessive load on the GitLab
instance if too many changes are pushed at once and a flood of pipelines are created accidentally.
## Retention of activity history

View File

@ -10759,10 +10759,11 @@ Represents an epic board list.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="epiclistcollapsed"></a>`collapsed` | [`Boolean`](#boolean) | Indicates if this list is collapsed for this user. |
| <a id="epiclistepicscount"></a>`epicsCount` | [`Int`](#int) | Count of epics in the list. |
| <a id="epiclistepicscount"></a>`epicsCount` **{warning-solid}** | [`Int`](#int) | **Deprecated** in 14.9. This was renamed. Use: `metadata`. |
| <a id="epiclistid"></a>`id` | [`BoardsEpicListID!`](#boardsepiclistid) | Global ID of the board list. |
| <a id="epiclistlabel"></a>`label` | [`Label`](#label) | Label of the list. |
| <a id="epiclistlisttype"></a>`listType` | [`String!`](#string) | Type of the list. |
| <a id="epiclistmetadata"></a>`metadata` | [`EpicListMetadata`](#epiclistmetadata) | Epic list metatada. |
| <a id="epiclistposition"></a>`position` | [`Int`](#int) | Position of the list within the board. |
| <a id="epiclisttitle"></a>`title` | [`String!`](#string) | Title of the list. |
@ -10784,6 +10785,17 @@ four standard [pagination arguments](#connection-pagination-arguments):
| ---- | ---- | ----------- |
| <a id="epiclistepicsfilters"></a>`filters` | [`EpicFilters`](#epicfilters) | Filters applied when selecting epics in the board list. |
### `EpicListMetadata`
Represents epic board list metadata.
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="epiclistmetadataepicscount"></a>`epicsCount` | [`Int`](#int) | Count of epics in the list. |
| <a id="epiclistmetadatatotalweight"></a>`totalWeight` | [`Int`](#int) | Total weight of all issues in the list. Available only when feature flag `epic_board_total_weight` is enabled. This flag is disabled by default, because the feature is experimental and is subject to change without notice. |
### `EpicPermissions`
Check permissions for the current user on an epic.
@ -15271,6 +15283,7 @@ Represents the security scan information.
| ---- | ---- | ----------- |
| <a id="scanerrors"></a>`errors` | [`[String!]!`](#string) | List of errors. |
| <a id="scanname"></a>`name` | [`String!`](#string) | Name of the scan. |
| <a id="scanstatus"></a>`status` | [`ScanStatus!`](#scanstatus) | Indicates the status of the scan. |
| <a id="scanwarnings"></a>`warnings` | [`[String!]!`](#string) | List of warnings. |
### `ScanExecutionPolicy`
@ -18142,6 +18155,20 @@ Size of UI component in SAST configuration page.
| <a id="sastuicomponentsizemedium"></a>`MEDIUM` | Size of UI component in SAST configuration page is medium. |
| <a id="sastuicomponentsizesmall"></a>`SMALL` | Size of UI component in SAST configuration page is small. |
### `ScanStatus`
The status of the security scan.
| Value | Description |
| ----- | ----------- |
| <a id="scanstatuscreated"></a>`CREATED` | The scan has been created. |
| <a id="scanstatusjob_failed"></a>`JOB_FAILED` | The related CI build failed. |
| <a id="scanstatuspreparation_failed"></a>`PREPARATION_FAILED` | Report couldn't be prepared. |
| <a id="scanstatuspreparing"></a>`PREPARING` | Preparing the report for the scan. |
| <a id="scanstatuspurged"></a>`PURGED` | Report for the scan has been removed from the database. |
| <a id="scanstatusreport_error"></a>`REPORT_ERROR` | The report artifact provided by the CI build couldn't be parsed. |
| <a id="scanstatussucceeded"></a>`SUCCEEDED` | The report has been successfully prepared. |
### `SecurityReportTypeEnum`
| Value | Description |

View File

@ -12,9 +12,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - It's enabled on GitLab.com.
> - It's recommended for production use.
WARNING:
This feature might not be available to you. Check the **version history** note above for details.
Usage Trends gives you an overview of how much data your instance contains, and how quickly this volume is changing over time.
Usage Trends data refreshes daily.

View File

@ -219,7 +219,7 @@ security issues:
WARNING:
This feature is in its end-of-life process. It is [deprecated](../../update/deprecations.md#vulnerability-check)
for use in GitLab 14.8, and is planned for removal in GitLab 15.0. Users should migrate to the new
[Security Approval Policies](policies/#scan-result-policy-editor).
[Security Approval Policies](policies/scan-result-policies.md).
To prevent a merge request introducing a security vulnerability in a project, enable the
Vulnerability-Check rule. While this rule is enabled, additional merge request approval by

View File

@ -12,16 +12,15 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - [Moved](https://gitlab.com/groups/gitlab-org/-/epics/6290) to GitLab Free in 14.5.
> - Support for Omnibus installations was [introduced](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/5686) in GitLab 14.5.
You can use GitLab CI/CD to safely deploy to and update your Kubernetes clusters.
You can use a GitLab CI/CD workflow to safely deploy to and update your Kubernetes clusters.
To do so, you install a GitLab agent in your cluster. Then in your GitLab CI/CD pipelines,
you can refer to the cluster connection as a Kubernetes context.
Then you can run Kubernetes API commands as part of your GitLab CI/CD pipeline.
To do so, you must first [install an agent in your cluster](install/index.md). When done, you have a Kubernetes context and can
run Kubernetes API commands in your GitLab CI/CD pipeline.
To ensure access to your cluster is safe:
- Each agent has a separate context (`kubecontext`).
- Only the project where the agent is, and any additional projects you authorize can access the agent in your cluster.
- Only the project where the agent is configured, and any additional projects you authorize, can access the agent in your cluster.
You do not need to have a runner in the cluster with the agent.

View File

@ -14,7 +14,22 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - [Renamed](https://gitlab.com/groups/gitlab-org/-/epics/7167) from "GitLab Kubernetes Agent" to "GitLab agent for Kubernetes" in GitLab 14.6.
You can connect your Kubernetes cluster with GitLab to deploy, manage,
and monitor your cloud-native solutions. You can choose from two primary workflows.
and monitor your cloud-native solutions.
To connect a Kubernetes cluster to GitLab, you must first [install an agent in your cluster](install/index.md).
The agent runs in the cluster, and you can use it to:
- Communicate with a cluster, which is behind a firewall or NAT.
- Access API endpoints in a cluster in real time.
- Push information about events happening in the cluster.
- Enable a cache of Kubernetes objects, which are kept up-to-date with very low latency.
For more details about the agent's purpose and architecture, see the [architecture documentation](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/architecture.md).
## Workflows
You can choose from two primary workflows.
In a [**GitOps** workflow](gitops.md), you keep your Kubernetes manifests in GitLab. You install a GitLab agent in your cluster, and
any time you update your manifests, the agent updates the cluster. This workflow is fully driven with Git and is considered pull-based,
@ -23,8 +38,6 @@ because the cluster is pulling updates from your GitLab repository.
In a [**CI/CD** workflow](ci_cd_tunnel.md), you use GitLab CI/CD to query and update your cluster by using the Kubernetes API.
This workflow is considered push-based, because GitLab is pushing requests from GitLab CI/CD to your cluster.
Both of these workflows require you to [install an agent in your cluster](install/index.md).
## Supported cluster versions
GitLab supports the following Kubernetes versions. You can upgrade your

View File

@ -12,7 +12,7 @@ module API
desc 'Get the current application statistics' do
success Entities::ApplicationStatistics
end
get "application/statistics" do
get "application/statistics", urgency: :low do
counts = Gitlab::Database::Count.approximate_counts(COUNTED_ITEMS)
present counts, with: Entities::ApplicationStatistics
end

View File

@ -10,6 +10,21 @@ module ContainerRegistry
REGISTRY_FEATURES_HEADER = 'gitlab-container-registry-features'
REGISTRY_TAG_DELETE_FEATURE = 'tag_delete'
ALLOWED_REDIRECT_SCHEMES = %w[http https].freeze
REDIRECT_OPTIONS = {
clear_authorization_header: true,
limit: 3,
cookies: [],
callback: -> (response_env, request_env) do
request_env.request_headers.delete(::FaradayMiddleware::FollowRedirects::AUTH_HEADER)
redirect_to = request_env.url
unless redirect_to.scheme.in?(ALLOWED_REDIRECT_SCHEMES)
raise ArgumentError, "Invalid scheme for #{redirect_to}"
end
end
}.freeze
def self.supports_tag_delete?
with_dummy_client(return_value_if_disabled: false) do |client|
client.supports_tag_delete?
@ -136,6 +151,10 @@ module ContainerRegistry
def faraday_blob
@faraday_blob ||= faraday_base do |conn|
initialize_connection(conn, @options)
if Feature.enabled?(:container_registry_follow_redirects_middleware)
conn.use ::FaradayMiddleware::FollowRedirects, REDIRECT_OPTIONS
end
end
end
end

View File

@ -0,0 +1,45 @@
# frozen_string_literal: true
module Gitlab
module BackgroundMigration
# Migrates personal namespace project `maintainer` memberships (for the associated user only) to OWNER
# Does not create any missing records, simply migrates existing ones
class MigratePersonalNamespaceProjectMaintainerToOwner
include Gitlab::Database::DynamicModelHelpers
def perform(start_id, end_id, batch_table, batch_column, sub_batch_size, pause_ms)
parent_batch_relation = relation_scoped_to_range(batch_table, batch_column, start_id, end_id)
parent_batch_relation.each_batch(column: batch_column, of: sub_batch_size) do |sub_batch|
batch_metrics.time_operation(:update_all) do
sub_batch.update_all('access_level = 50')
end
pause_ms = 0 if pause_ms < 0
sleep(pause_ms * 0.001)
end
end
def batch_metrics
@batch_metrics ||= Gitlab::Database::BackgroundMigration::BatchMetrics.new
end
private
def relation_scoped_to_range(source_table, source_key_column, start_id, stop_id)
# members of projects within their own personal namespace
# rubocop: disable CodeReuse/ActiveRecord
define_batchable_model(:members, connection: ApplicationRecord.connection)
.where(source_key_column => start_id..stop_id)
.joins("INNER JOIN projects ON members.source_id = projects.id")
.joins("INNER JOIN namespaces ON projects.namespace_id = namespaces.id")
.where(type: 'ProjectMember')
.where("namespaces.type = 'User'")
.where('members.access_level < 50')
.where('namespaces.owner_id = members.user_id')
end
end
# rubocop: enable CodeReuse/ActiveRecord
end
end

View File

@ -16777,6 +16777,15 @@ msgstr ""
msgid "GithubIntegration|This requires mirroring your GitHub repository to this project. %{docs_link}"
msgstr ""
msgid "GitlabTiers|Free"
msgstr ""
msgid "GitlabTiers|Premium"
msgstr ""
msgid "GitlabTiers|Ultimate"
msgstr ""
msgid "Gitpod"
msgstr ""
@ -26990,6 +26999,9 @@ msgstr ""
msgid "Pipelines|GitLab Runner is an application that works with GitLab CI/CD to run jobs in a pipeline. There are active runners available to run your jobs right now. If you prefer, you can %{settingsLinkStart}configure your runners%{settingsLinkEnd} or %{docsLinkStart}learn more%{docsLinkEnd} about runners."
msgstr ""
msgid "Pipelines|Gitlab Premium users have access to the multi-project pipeline graph to improve the visualization of these pipelines. %{linkStart}Learn More%{linkEnd}"
msgstr ""
msgid "Pipelines|If you are unsure, please ask a project maintainer to review it for you."
msgstr ""
@ -27029,6 +27041,9 @@ msgstr ""
msgid "Pipelines|More Information"
msgstr ""
msgid "Pipelines|Multi-project pipeline graphs"
msgstr ""
msgid "Pipelines|No runners detected"
msgstr ""
@ -27179,9 +27194,6 @@ msgstr ""
msgid "Pipeline|Checking pipeline status."
msgstr ""
msgid "Pipeline|Commit"
msgstr ""
msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
@ -27197,9 +27209,6 @@ msgstr ""
msgid "Pipeline|Detached merge request pipeline"
msgstr ""
msgid "Pipeline|Duration"
msgstr ""
msgid "Pipeline|Failed"
msgstr ""
@ -27743,6 +27752,9 @@ msgstr ""
msgid "Preferences|When you type in a description or comment box, selected text is surrounded by the corresponding character after typing one of the following characters: %{supported_characters}."
msgstr ""
msgid "Preparing the report for the scan."
msgstr ""
msgid "Prev"
msgstr ""
@ -30798,6 +30810,12 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
msgid "Report couldn't be prepared."
msgstr ""
msgid "Report for the scan has been removed from the database."
msgstr ""
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@ -36831,6 +36849,9 @@ msgstr ""
msgid "The regular expression used to find test coverage output in the job log. For example, use %{regex} for Simplecov (Ruby). Leave blank to disable."
msgstr ""
msgid "The related CI build failed."
msgstr ""
msgid "The remote mirror URL is invalid."
msgstr ""
@ -36840,6 +36861,12 @@ msgstr ""
msgid "The remote repository is being updated..."
msgstr ""
msgid "The report artifact provided by the CI build couldn't be parsed."
msgstr ""
msgid "The report has been successfully prepared."
msgstr ""
msgid "The repository can be committed to, and issues, comments and other entities can be created."
msgstr ""
@ -36861,6 +36888,9 @@ msgstr ""
msgid "The same shared runner executes code from multiple projects, unless you configure autoscaling with %{link} set to 1 (which it is on GitLab.com)."
msgstr ""
msgid "The scan has been created."
msgstr ""
msgid "The snippet can be accessed without any authentication."
msgstr ""
@ -37314,7 +37344,7 @@ msgstr ""
msgid "This %{issuable} is locked. Only %{strong_open}project members%{strong_close} can comment."
msgstr ""
msgid "This %{noteableTypeText} is %{confidentialLinkStart}confidential%{linkEnd} and %{lockedLinkStart}locked%{linkEnd}."
msgid "This %{noteableTypeText} is %{confidentialLinkStart}confidential%{confidentialLinkEnd} and %{lockedLinkStart}locked%{lockedLinkEnd}."
msgstr ""
msgid "This %{noteableTypeText} is locked."

View File

@ -24,6 +24,7 @@ module QA
view 'app/assets/javascripts/pipelines/components/graph/linked_pipeline.vue' do
element :expand_pipeline_button
element :child_pipeline
element :linked_pipeline_body
end
view 'app/assets/javascripts/reports/components/report_section.vue' do
@ -93,7 +94,7 @@ module QA
end
def find_child_pipeline_by_title(title)
child_pipelines.find { |pipeline| pipeline[:title].include?(title) }
find_element(:child_pipeline, text: title)
end
def expand_child_pipeline(title: nil)

View File

@ -1,104 +0,0 @@
# frozen_string_literal: true
module QA
RSpec.describe 'Verify', :runner do
describe 'Pass dotenv variables to downstream via bridge' do
let(:executor) { "qa-runner-#{Faker::Alphanumeric.alphanumeric(8)}" }
let(:upstream_var) { Faker::Alphanumeric.alphanumeric(8) }
let(:group) { Resource::Group.fabricate_via_api! }
let(:upstream_project) do
Resource::Project.fabricate_via_api! do |project|
project.group = group
project.name = 'upstream-project-with-bridge'
end
end
let(:downstream_project) do
Resource::Project.fabricate_via_api! do |project|
project.group = group
project.name = 'downstream-project-with-bridge'
end
end
let!(:runner) do
Resource::Runner.fabricate! do |runner|
runner.name = executor
runner.tags = [executor]
runner.token = group.reload!.runners_token
end
end
before do
Flow::Login.sign_in
add_ci_file(downstream_project, downstream_ci_file)
add_ci_file(upstream_project, upstream_ci_file)
upstream_project.visit!
Flow::Pipeline.visit_latest_pipeline(pipeline_condition: 'succeeded')
end
after do
runner.remove_via_api!
[upstream_project, downstream_project].each(&:remove_via_api!)
end
it 'runs the pipeline with composed config', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348088' do
Page::Project::Pipeline::Show.perform do |parent_pipeline|
Support::Waiter.wait_until { parent_pipeline.has_child_pipeline? }
parent_pipeline.expand_child_pipeline
parent_pipeline.click_job('downstream_test')
end
Page::Project::Job::Show.perform do |show|
expect(show).to have_passed(timeout: 360)
expect(show.output).to have_content(upstream_var)
end
end
private
def add_ci_file(project, file)
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
commit.commit_message = 'Add config file'
commit.add_files([file])
end
end
def upstream_ci_file
{
file_path: '.gitlab-ci.yml',
content: <<~YAML
build:
stage: build
tags: ["#{executor}"]
script:
- echo "DYNAMIC_ENVIRONMENT_VAR=#{upstream_var}" >> variables.env
artifacts:
reports:
dotenv: variables.env
trigger:
stage: deploy
variables:
PASSED_MY_VAR: $DYNAMIC_ENVIRONMENT_VAR
trigger: #{downstream_project.full_path}
YAML
}
end
def downstream_ci_file
{
file_path: '.gitlab-ci.yml',
content: <<~YAML
downstream_test:
stage: test
tags: ["#{executor}"]
script:
- echo $PASSED_MY_VAR
YAML
}
end
end
end
end

View File

@ -56,7 +56,7 @@ module QA
end
Page::Project::Job::Show.perform do |show|
expect(show).to have_passed(timeout: 360)
expect(show).to have_passed(timeout: 800)
end
end
end

View File

@ -125,7 +125,6 @@ RSpec.describe 'Merge request > User sees pipelines', :js do
before do
stub_feature_flags(ci_disallow_to_create_merge_request_pipelines_in_target_project: false)
stub_feature_flags(rearrange_pipelines_table: false)
end
it 'creates a pipeline in the parent project when user proceeds with the warning' do

View File

@ -161,51 +161,7 @@ RSpec.describe 'Pipelines', :js do
end
end
context 'when pipeline is detached merge request pipeline, with rearrange_pipelines_table feature flag turned off' do
let(:merge_request) do
create(:merge_request,
:with_detached_merge_request_pipeline,
source_project: source_project,
target_project: target_project)
end
let!(:pipeline) { merge_request.all_pipelines.first }
let(:source_project) { project }
let(:target_project) { project }
before do
stub_feature_flags(rearrange_pipelines_table: false)
visit project_pipelines_path(source_project)
end
shared_examples_for 'detached merge request pipeline' do
it 'shows pipeline information without pipeline ref', :sidekiq_might_not_need_inline do
within '.pipeline-tags' do
expect(page).to have_content(expected_detached_mr_tag)
end
within '.branch-commit' do
expect(page).to have_link(merge_request.iid,
href: project_merge_request_path(project, merge_request))
end
within '.branch-commit' do
expect(page).not_to have_link(pipeline.ref)
end
end
end
it_behaves_like 'detached merge request pipeline'
context 'when source project is a forked project' do
let(:source_project) { fork_project(project, user, repository: true) }
it_behaves_like 'detached merge request pipeline'
end
end
context 'when pipeline is detached merge request pipeline, with rearrange_pipelines_table feature flag turned on' do
context 'when pipeline is detached merge request pipeline' do
let(:merge_request) do
create(:merge_request,
:with_detached_merge_request_pipeline,
@ -218,8 +174,6 @@ RSpec.describe 'Pipelines', :js do
let(:target_project) { project }
before do
stub_feature_flags(rearrange_pipelines_table: true)
visit project_pipelines_path(source_project)
end
@ -245,52 +199,7 @@ RSpec.describe 'Pipelines', :js do
end
end
context 'when pipeline is merge request pipeline, with rearrange_pipelines_table feature flag turned off' do
let(:merge_request) do
create(:merge_request,
:with_merge_request_pipeline,
source_project: source_project,
target_project: target_project,
merge_sha: target_project.commit.sha)
end
let!(:pipeline) { merge_request.all_pipelines.first }
let(:source_project) { project }
let(:target_project) { project }
before do
stub_feature_flags(rearrange_pipelines_table: false)
visit project_pipelines_path(source_project)
end
shared_examples_for 'Correct merge request pipeline information' do
it 'does not show detached tag for the pipeline, and shows the link of the merge request, and does not show the ref of the pipeline', :sidekiq_might_not_need_inline do
within '.pipeline-tags' do
expect(page).not_to have_content(expected_detached_mr_tag)
end
within '.branch-commit' do
expect(page).to have_link(merge_request.iid,
href: project_merge_request_path(project, merge_request))
end
within '.branch-commit' do
expect(page).not_to have_link(pipeline.ref)
end
end
end
it_behaves_like 'Correct merge request pipeline information'
context 'when source project is a forked project' do
let(:source_project) { fork_project(project, user, repository: true) }
it_behaves_like 'Correct merge request pipeline information'
end
end
context 'when pipeline is merge request pipeline, with rearrange_pipelines_table feature flag turned on' do
context 'when pipeline is merge request pipeline' do
let(:merge_request) do
create(:merge_request,
:with_merge_request_pipeline,
@ -304,8 +213,6 @@ RSpec.describe 'Pipelines', :js do
let(:target_project) { project }
before do
stub_feature_flags(rearrange_pipelines_table: true)
visit project_pipelines_path(source_project)
end
@ -676,28 +583,6 @@ RSpec.describe 'Pipelines', :js do
context 'with pipeline key selection' do
before do
stub_feature_flags(rearrange_pipelines_table: false)
visit project_pipelines_path(project)
wait_for_requests
end
it 'changes the Pipeline ID column for Pipeline IID' do
page.find('[data-testid="pipeline-key-dropdown"]').click
within '.gl-new-dropdown-contents' do
dropdown_options = page.find_all '.gl-new-dropdown-item'
dropdown_options[1].click
end
expect(page.find('[data-testid="pipeline-th"]')).to have_content 'Pipeline IID'
expect(page.find('[data-testid="pipeline-url-link"]')).to have_content "##{pipeline.iid}"
end
end
context 'with pipeline key selection and rearrange_pipelines_table ff on' do
before do
stub_feature_flags(rearrange_pipelines_table: true)
visit project_pipelines_path(project)
wait_for_requests
end

View File

@ -93,5 +93,38 @@ describe('DirtySubmitForm', () => {
expect(updateDirtyInputSpy).toHaveBeenCalledTimes(range.length);
});
describe('when inputs listener is added', () => {
it('calls listener when changes are made to an input', () => {
const { form, input } = createForm();
const inputsListener = jest.fn();
const dirtySubmitForm = new DirtySubmitForm(form);
dirtySubmitForm.addInputsListener(inputsListener);
setInputValue(input, 'new value');
jest.runOnlyPendingTimers();
expect(inputsListener).toHaveBeenCalledTimes(1);
});
describe('when inputs listener is removed', () => {
it('does not call listener when changes are made to an input', () => {
const { form, input } = createForm();
const inputsListener = jest.fn();
const dirtySubmitForm = new DirtySubmitForm(form);
dirtySubmitForm.addInputsListener(inputsListener);
dirtySubmitForm.removeInputsListener(inputsListener);
setInputValue(input, 'new value');
jest.runOnlyPendingTimers();
expect(inputsListener).not.toHaveBeenCalled();
});
});
});
});
});

View File

@ -1,4 +1,4 @@
import { GlIntersectionObserver, GlSkeletonLoader } from '@gitlab/ui';
import { GlIntersectionObserver, GlSkeletonLoader, GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
@ -19,6 +19,7 @@ describe('Jobs app', () => {
let resolverSpy;
const findSkeletonLoader = () => wrapper.findComponent(GlSkeletonLoader);
const findLoadingSpinner = () => wrapper.findComponent(GlLoadingIcon);
const findJobsTable = () => wrapper.findComponent(JobsTable);
const triggerInfiniteScroll = () =>
@ -48,7 +49,29 @@ describe('Jobs app', () => {
wrapper.destroy();
});
it('displays the loading state', () => {
describe('loading spinner', () => {
beforeEach(async () => {
createComponent(resolverSpy);
await waitForPromises();
triggerInfiniteScroll();
});
it('displays loading spinner when fetching more jobs', () => {
expect(findLoadingSpinner().exists()).toBe(true);
expect(findSkeletonLoader().exists()).toBe(false);
});
it('hides loading spinner after jobs have been fetched', async () => {
await waitForPromises();
expect(findLoadingSpinner().exists()).toBe(false);
expect(findSkeletonLoader().exists()).toBe(false);
});
});
it('displays the skeleton loader', () => {
createComponent(resolverSpy);
expect(findSkeletonLoader().exists()).toBe(true);
@ -91,7 +114,7 @@ describe('Jobs app', () => {
});
});
it('does not display main loading state again after fetchMore', async () => {
it('does not display skeleton loader again after fetchMore', async () => {
createComponent(resolverSpy);
expect(findSkeletonLoader().exists()).toBe(true);

View File

@ -66,7 +66,6 @@ describe('graph component', () => {
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
describe('with data', () => {

View File

@ -1,5 +1,5 @@
import { GlButton, GlLoadingIcon } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import { GlButton, GlLoadingIcon, GlPopover } from '@gitlab/ui';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import { BV_HIDE_TOOLTIP } from '~/lib/utils/constants';
import { UPSTREAM, DOWNSTREAM } from '~/pipelines/components/graph/constants';
import LinkedPipelineComponent from '~/pipelines/components/graph/linked_pipeline.vue';
@ -9,15 +9,20 @@ import mockPipeline from './linked_pipelines_mock_data';
describe('Linked pipeline', () => {
let wrapper;
const defaultProps = {
pipeline: mockPipeline,
columnTitle: 'Downstream',
type: DOWNSTREAM,
expanded: false,
isLoading: false,
isMultiProjectVizAvailable: true,
};
const downstreamProps = {
pipeline: {
...mockPipeline,
multiproject: false,
},
columnTitle: 'Downstream',
type: DOWNSTREAM,
expanded: false,
isLoading: false,
};
const upstreamProps = {
@ -27,21 +32,29 @@ describe('Linked pipeline', () => {
};
const findButton = () => wrapper.find(GlButton);
const findDownstreamPipelineTitle = () => wrapper.find('[data-testid="downstream-title"]');
const findPipelineLabel = () => wrapper.find('[data-testid="downstream-pipeline-label"]');
const findLinkedPipeline = () => wrapper.find({ ref: 'linkedPipeline' });
const findDownstreamPipelineTitle = () => wrapper.findByTestId('downstream-title');
const findPipelineLabel = () => wrapper.findByTestId('downstream-pipeline-label');
const findLinkedPipeline = () => wrapper.findByTestId('linkedPipeline');
const findLinkedPipelineBody = () => wrapper.findByTestId('linkedPipelineBody');
const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
const findPipelineLink = () => wrapper.find('[data-testid="pipelineLink"]');
const findExpandButton = () => wrapper.find('[data-testid="expand-pipeline-button"]');
const findPipelineLink = () => wrapper.findByTestId('pipelineLink');
const findExpandButton = () => wrapper.findByTestId('expand-pipeline-button');
const findPopover = () => wrapper.find(GlPopover);
const createWrapper = (propsData, data = []) => {
wrapper = mount(LinkedPipelineComponent, {
propsData,
wrapper = mountExtended(LinkedPipelineComponent, {
propsData: {
...defaultProps,
...propsData,
},
data() {
return {
...data,
};
},
provide: {
multiProjectHelpPath: '/ci/pipelines/multi-project-pipelines',
},
});
};
@ -92,7 +105,7 @@ describe('Linked pipeline', () => {
});
it('should render the tooltip text as the title attribute', () => {
const titleAttr = findLinkedPipeline().attributes('title');
const titleAttr = findLinkedPipelineBody().attributes('title');
expect(titleAttr).toContain(mockPipeline.project.name);
expect(titleAttr).toContain(mockPipeline.status.label);
@ -168,10 +181,6 @@ describe('Linked pipeline', () => {
describe('when isLoading is true', () => {
const props = {
pipeline: mockPipeline,
columnTitle: 'Downstream',
type: DOWNSTREAM,
expanded: false,
isLoading: true,
};
@ -184,19 +193,43 @@ describe('Linked pipeline', () => {
});
});
describe('on click/hover', () => {
const props = {
pipeline: mockPipeline,
columnTitle: 'Downstream',
type: DOWNSTREAM,
expanded: false,
isLoading: false,
};
describe('when the user does not have access to the multi-project pipeline viz feature', () => {
beforeEach(() => {
const props = { isMultiProjectVizAvailable: false };
createWrapper(props);
});
it('the multi-project expand button is disabled', () => {
expect(findExpandButton().props('disabled')).toBe(true);
});
it('it adds the popover text inside the DOM', () => {
expect(findPopover().exists()).toBe(true);
expect(findPopover().text()).toContain(
'Gitlab Premium users have access to the multi-project pipeline graph to improve the visualization of these pipelines.',
);
});
});
describe('when the user has access to the multi-project pipeline viz feature', () => {
beforeEach(() => {
createWrapper();
});
it('the multi-project expand button is enabled', () => {
expect(findExpandButton().props('disabled')).toBe(false);
});
it('does not add the popover text inside the DOM', () => {
expect(findPopover().exists()).toBe(false);
});
});
describe('on click/hover', () => {
beforeEach(() => {
createWrapper();
});
it('emits `pipelineClicked` event', () => {
jest.spyOn(wrapper.vm, '$emit');
findButton().trigger('click');

View File

@ -26,6 +26,7 @@ const processedPipeline = pipelineWithUpstreamDownstream(mockPipelineResponse);
describe('Linked Pipelines Column', () => {
const defaultProps = {
columnTitle: 'Downstream',
isMultiProjectVizAvailable: true,
linkedPipelines: processedPipeline.downstream,
showLinks: false,
type: DOWNSTREAM,
@ -51,6 +52,9 @@ describe('Linked Pipelines Column', () => {
...defaultProps,
...props,
},
provide: {
multiProjectHelpPath: 'ci/pipelines/multi-project-pipeline',
},
});
};
@ -67,7 +71,6 @@ describe('Linked Pipelines Column', () => {
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
describe('it renders correctly', () => {

View File

@ -13,6 +13,15 @@ export const mockPipelineResponse = {
usesNeeds: true,
downstream: null,
upstream: null,
user: {
__typename: 'UserCore',
id: 'gid://gitlab/User/1',
namespace: {
__typename: 'Namespace',
id: 'gid://gitlab/Namespaces::UserNamespace/1',
crossProjectPipelineAvailable: true,
},
},
userPermissions: {
__typename: 'PipelinePermissions',
updatePipeline: true,
@ -780,6 +789,15 @@ export const wrappedPipelineReturn = {
id: 'gid://gitlab/Ci::Pipeline/175',
iid: '38',
complete: true,
user: {
__typename: 'UserCore',
id: 'gid://gitlab/User/1',
namespace: {
__typename: 'Namespace',
id: 'gid://gitlab/Namespaces::UserNamespace/1',
crossProjectPipelineAvailable: true,
},
},
usesNeeds: true,
userPermissions: {
__typename: 'PipelinePermissions',

View File

@ -30,14 +30,11 @@ describe('Pipeline Url Component', () => {
const defaultProps = mockPipeline(projectPath);
const createComponent = (props, rearrangePipelinesTable = false) => {
const createComponent = (props) => {
wrapper = shallowMountExtended(PipelineUrlComponent, {
propsData: { ...defaultProps, ...props },
provide: {
targetProjectFullPath: projectPath,
glFeatures: {
rearrangePipelinesTable,
},
},
});
};
@ -47,190 +44,176 @@ describe('Pipeline Url Component', () => {
wrapper = null;
});
describe('with the rearrangePipelinesTable feature flag turned off', () => {
it('should render pipeline url table cell', () => {
createComponent();
it('should render pipeline url table cell', () => {
createComponent();
expect(findTableCell().exists()).toBe(true);
expect(findTableCell().exists()).toBe(true);
});
it('should render a link the provided path and id', () => {
createComponent();
expect(findPipelineUrlLink().attributes('href')).toBe('foo');
expect(findPipelineUrlLink().text()).toBe('#1');
});
it('should not render tags when flags are not set', () => {
createComponent();
expect(findStuckTag().exists()).toBe(false);
expect(findLatestTag().exists()).toBe(false);
expect(findYamlTag().exists()).toBe(false);
expect(findAutoDevopsTag().exists()).toBe(false);
expect(findFailureTag().exists()).toBe(false);
expect(findScheduledTag().exists()).toBe(false);
expect(findForkTag().exists()).toBe(false);
expect(findTrainTag().exists()).toBe(false);
});
it('should render the stuck tag when flag is provided', () => {
const stuckPipeline = defaultProps.pipeline;
stuckPipeline.flags.stuck = true;
createComponent({
...stuckPipeline.pipeline,
});
it('should render a link the provided path and id', () => {
createComponent();
expect(findStuckTag().text()).toContain('stuck');
});
expect(findPipelineUrlLink().attributes('href')).toBe('foo');
it('should render latest tag when flag is provided', () => {
const latestPipeline = defaultProps.pipeline;
latestPipeline.flags.latest = true;
expect(findPipelineUrlLink().text()).toBe('#1');
createComponent({
...latestPipeline,
});
it('should not render tags when flags are not set', () => {
createComponent();
expect(findLatestTag().text()).toContain('latest');
});
expect(findStuckTag().exists()).toBe(false);
expect(findLatestTag().exists()).toBe(false);
expect(findYamlTag().exists()).toBe(false);
expect(findAutoDevopsTag().exists()).toBe(false);
expect(findFailureTag().exists()).toBe(false);
expect(findScheduledTag().exists()).toBe(false);
expect(findForkTag().exists()).toBe(false);
expect(findTrainTag().exists()).toBe(false);
it('should render a yaml badge when it is invalid', () => {
const yamlPipeline = defaultProps.pipeline;
yamlPipeline.flags.yaml_errors = true;
createComponent({
...yamlPipeline,
});
it('should render the stuck tag when flag is provided', () => {
const stuckPipeline = defaultProps.pipeline;
stuckPipeline.flags.stuck = true;
expect(findYamlTag().text()).toContain('yaml invalid');
});
createComponent({
...stuckPipeline.pipeline,
});
it('should render an autodevops badge when flag is provided', () => {
const autoDevopsPipeline = defaultProps.pipeline;
autoDevopsPipeline.flags.auto_devops = true;
expect(findStuckTag().text()).toContain('stuck');
createComponent({
...autoDevopsPipeline,
});
it('should render latest tag when flag is provided', () => {
const latestPipeline = defaultProps.pipeline;
latestPipeline.flags.latest = true;
expect(trimText(findAutoDevopsTag().text())).toBe('Auto DevOps');
createComponent({
...latestPipeline,
});
expect(findLatestTag().text()).toContain('latest');
});
it('should render a yaml badge when it is invalid', () => {
const yamlPipeline = defaultProps.pipeline;
yamlPipeline.flags.yaml_errors = true;
createComponent({
...yamlPipeline,
});
expect(findYamlTag().text()).toContain('yaml invalid');
});
it('should render an autodevops badge when flag is provided', () => {
const autoDevopsPipeline = defaultProps.pipeline;
autoDevopsPipeline.flags.auto_devops = true;
createComponent({
...autoDevopsPipeline,
});
expect(trimText(findAutoDevopsTag().text())).toBe('Auto DevOps');
expect(findAutoDevopsTagLink().attributes()).toMatchObject({
href: '/help/topics/autodevops/index.md',
target: '_blank',
});
});
it('should render a detached badge when flag is provided', () => {
const detachedMRPipeline = defaultProps.pipeline;
detachedMRPipeline.flags.detached_merge_request_pipeline = true;
createComponent({
...detachedMRPipeline,
});
expect(findDetachedTag().text()).toBe('merge request');
});
it('should render error badge when pipeline has a failure reason set', () => {
const failedPipeline = defaultProps.pipeline;
failedPipeline.flags.failure_reason = true;
failedPipeline.failure_reason = 'some reason';
createComponent({
...failedPipeline,
});
expect(findFailureTag().text()).toContain('error');
expect(findFailureTag().attributes('title')).toContain('some reason');
});
it('should render scheduled badge when pipeline was triggered by a schedule', () => {
const scheduledPipeline = defaultProps.pipeline;
scheduledPipeline.source = 'schedule';
createComponent({
...scheduledPipeline,
});
expect(findScheduledTag().exists()).toBe(true);
expect(findScheduledTag().text()).toContain('Scheduled');
});
it('should render the fork badge when the pipeline was run in a fork', () => {
const forkedPipeline = defaultProps.pipeline;
forkedPipeline.project.full_path = '/test/forked';
createComponent({
...forkedPipeline,
});
expect(findForkTag().exists()).toBe(true);
expect(findForkTag().text()).toBe('fork');
});
it('should render the train badge when the pipeline is a merge train pipeline', () => {
const mergeTrainPipeline = defaultProps.pipeline;
mergeTrainPipeline.flags.merge_train_pipeline = true;
createComponent({
...mergeTrainPipeline,
});
expect(findTrainTag().text()).toBe('merge train');
});
it('should not render the train badge when the pipeline is not a merge train pipeline', () => {
const mergeTrainPipeline = defaultProps.pipeline;
mergeTrainPipeline.flags.merge_train_pipeline = false;
createComponent({
...mergeTrainPipeline,
});
expect(findTrainTag().exists()).toBe(false);
});
it('should not render the commit wrapper and commit-short-sha', () => {
createComponent();
expect(findCommitTitleContainer().exists()).toBe(false);
expect(findCommitShortSha().exists()).toBe(false);
expect(findAutoDevopsTagLink().attributes()).toMatchObject({
href: '/help/topics/autodevops/index.md',
target: '_blank',
});
});
describe('with the rearrangePipelinesTable feature flag turned on', () => {
it('should render the commit title, commit reference and commit-short-sha', () => {
createComponent({}, true);
it('should render a detached badge when flag is provided', () => {
const detachedMRPipeline = defaultProps.pipeline;
detachedMRPipeline.flags.detached_merge_request_pipeline = true;
const commitWrapper = findCommitTitleContainer();
expect(findCommitTitle(commitWrapper).exists()).toBe(true);
expect(findRefName().exists()).toBe(true);
expect(findCommitShortSha().exists()).toBe(true);
createComponent({
...detachedMRPipeline,
});
it('should render commit icon tooltip', () => {
createComponent({}, true);
expect(findDetachedTag().text()).toBe('merge request');
});
expect(findCommitIcon().attributes('title')).toBe('Commit');
it('should render error badge when pipeline has a failure reason set', () => {
const failedPipeline = defaultProps.pipeline;
failedPipeline.flags.failure_reason = true;
failedPipeline.failure_reason = 'some reason';
createComponent({
...failedPipeline,
});
it.each`
pipeline | expectedTitle
${mockPipelineTag()} | ${'Tag'}
${mockPipelineBranch()} | ${'Branch'}
${mockPipeline()} | ${'Merge Request'}
`(
'should render tooltip $expectedTitle for commit icon type',
({ pipeline, expectedTitle }) => {
createComponent(pipeline, true);
expect(findFailureTag().text()).toContain('error');
expect(findFailureTag().attributes('title')).toContain('some reason');
});
expect(findCommitIconType().attributes('title')).toBe(expectedTitle);
},
);
it('should render scheduled badge when pipeline was triggered by a schedule', () => {
const scheduledPipeline = defaultProps.pipeline;
scheduledPipeline.source = 'schedule';
createComponent({
...scheduledPipeline,
});
expect(findScheduledTag().exists()).toBe(true);
expect(findScheduledTag().text()).toContain('Scheduled');
});
it('should render the fork badge when the pipeline was run in a fork', () => {
const forkedPipeline = defaultProps.pipeline;
forkedPipeline.project.full_path = '/test/forked';
createComponent({
...forkedPipeline,
});
expect(findForkTag().exists()).toBe(true);
expect(findForkTag().text()).toBe('fork');
});
it('should render the train badge when the pipeline is a merge train pipeline', () => {
const mergeTrainPipeline = defaultProps.pipeline;
mergeTrainPipeline.flags.merge_train_pipeline = true;
createComponent({
...mergeTrainPipeline,
});
expect(findTrainTag().text()).toBe('merge train');
});
it('should not render the train badge when the pipeline is not a merge train pipeline', () => {
const mergeTrainPipeline = defaultProps.pipeline;
mergeTrainPipeline.flags.merge_train_pipeline = false;
createComponent({
...mergeTrainPipeline,
});
expect(findTrainTag().exists()).toBe(false);
});
it('should render the commit title, commit reference and commit-short-sha', () => {
createComponent({}, true);
const commitWrapper = findCommitTitleContainer();
expect(findCommitTitle(commitWrapper).exists()).toBe(true);
expect(findRefName().exists()).toBe(true);
expect(findCommitShortSha().exists()).toBe(true);
});
it('should render commit icon tooltip', () => {
createComponent({}, true);
expect(findCommitIcon().attributes('title')).toBe('Commit');
});
it.each`
pipeline | expectedTitle
${mockPipelineTag()} | ${'Tag'}
${mockPipelineBranch()} | ${'Branch'}
${mockPipeline()} | ${'Merge Request'}
`('should render tooltip $expectedTitle for commit icon type', ({ pipeline, expectedTitle }) => {
createComponent(pipeline, true);
expect(findCommitIconType().attributes('title')).toBe(expectedTitle);
});
});

View File

@ -17,7 +17,6 @@ import {
import eventHub from '~/pipelines/event_hub';
import CiBadge from '~/vue_shared/components/ci_badge_link.vue';
import CommitComponent from '~/vue_shared/components/commit.vue';
jest.mock('~/pipelines/event_hub');
@ -37,18 +36,13 @@ describe('Pipelines Table', () => {
return pipelines.find((p) => p.user !== null && p.commit !== null);
};
const createComponent = (props = {}, rearrangePipelinesTable = false) => {
const createComponent = (props = {}) => {
wrapper = extendedWrapper(
mount(PipelinesTable, {
propsData: {
...defaultProps,
...props,
},
provide: {
glFeatures: {
rearrangePipelinesTable,
},
},
}),
);
};
@ -57,7 +51,6 @@ describe('Pipelines Table', () => {
const findStatusBadge = () => wrapper.findComponent(CiBadge);
const findPipelineInfo = () => wrapper.findComponent(PipelineUrl);
const findTriggerer = () => wrapper.findComponent(PipelineTriggerer);
const findCommit = () => wrapper.findComponent(CommitComponent);
const findPipelineMiniGraph = () => wrapper.findComponent(PipelineMiniGraph);
const findTimeAgo = () => wrapper.findComponent(PipelinesTimeago);
const findActions = () => wrapper.findComponent(PipelineOperations);
@ -65,10 +58,7 @@ describe('Pipelines Table', () => {
const findTableRows = () => wrapper.findAllByTestId('pipeline-table-row');
const findStatusTh = () => wrapper.findByTestId('status-th');
const findPipelineTh = () => wrapper.findByTestId('pipeline-th');
const findTriggererTh = () => wrapper.findByTestId('triggerer-th');
const findCommitTh = () => wrapper.findByTestId('commit-th');
const findStagesTh = () => wrapper.findByTestId('stages-th');
const findTimeAgoTh = () => wrapper.findByTestId('timeago-th');
const findActionsTh = () => wrapper.findByTestId('actions-th');
const findRetryBtn = () => wrapper.findByTestId('pipelines-retry-button');
const findCancelBtn = () => wrapper.findByTestId('pipelines-cancel-button');
@ -82,7 +72,7 @@ describe('Pipelines Table', () => {
wrapper = null;
});
describe('Pipelines Table with rearrangePipelinesTable feature flag turned off', () => {
describe('Pipelines Table', () => {
beforeEach(() => {
createComponent({ pipelines: [pipeline], viewType: 'root' });
});
@ -93,11 +83,8 @@ describe('Pipelines Table', () => {
it('should render table head with correct columns', () => {
expect(findStatusTh().text()).toBe('Status');
expect(findPipelineTh().text()).toBe('Pipeline ID');
expect(findTriggererTh().text()).toBe('Triggerer');
expect(findCommitTh().text()).toBe('Commit');
expect(findPipelineTh().text()).toBe('Pipeline');
expect(findStagesTh().text()).toBe('Stages');
expect(findTimeAgoTh().text()).toBe('Duration');
expect(findActionsTh().text()).toBe('Actions');
});
@ -125,27 +112,6 @@ describe('Pipelines Table', () => {
});
});
describe('triggerer cell', () => {
it('should render the pipeline triggerer', () => {
expect(findTriggerer().exists()).toBe(true);
});
});
describe('commit cell', () => {
it('should render commit information', () => {
expect(findCommit().exists()).toBe(true);
});
it('should display and link to commit', () => {
expect(findCommit().text()).toContain(pipeline.commit.short_id);
expect(findCommit().props('commitUrl')).toBe(pipeline.commit.commit_path);
});
it('should display the commit author', () => {
expect(findCommit().props('author')).toEqual(pipeline.commit.author);
});
});
describe('stages cell', () => {
it('should render a pipeline mini graph', () => {
expect(findPipelineMiniGraph().exists()).toBe(true);
@ -163,7 +129,7 @@ describe('Pipelines Table', () => {
pipeline = createMockPipeline();
pipeline.details.stages = null;
createComponent({ pipelines: [pipeline] }, true);
createComponent({ pipelines: [pipeline] });
});
it('stages are not rendered', () => {
@ -176,7 +142,7 @@ describe('Pipelines Table', () => {
});
it('when update graph dropdown is set, should update graph dropdown', () => {
createComponent({ pipelines: [pipeline], updateGraphDropdown: true }, true);
createComponent({ pipelines: [pipeline], updateGraphDropdown: true });
expect(findPipelineMiniGraph().props('updateDropdown')).toBe(true);
});
@ -207,30 +173,11 @@ describe('Pipelines Table', () => {
expect(findCancelBtn().attributes('title')).toBe(BUTTON_TOOLTIP_CANCEL);
});
});
});
describe('Pipelines Table with rearrangePipelinesTable feature flag turned on', () => {
beforeEach(() => {
createComponent({ pipelines: [pipeline], viewType: 'root' }, true);
});
it('should render table head with correct columns', () => {
expect(findStatusTh().text()).toBe('Status');
expect(findPipelineTh().text()).toBe('Pipeline');
expect(findStagesTh().text()).toBe('Stages');
expect(findActionsTh().text()).toBe('Actions');
});
describe('triggerer cell', () => {
it('should render the pipeline triggerer', () => {
expect(findTriggerer().exists()).toBe(true);
});
});
describe('commit cell', () => {
it('should not render commit information', () => {
expect(findCommit().exists()).toBe(false);
});
});
});
});

View File

@ -34,21 +34,19 @@ exports[`Issue Warning Component when noteable is locked and confidential render
<span>
<span>
This issue is
<a
<gl-link-stub
href=""
rel="noopener noreferrer"
target="_blank"
>
confidential
</a>
</gl-link-stub>
and
<a
<gl-link-stub
href=""
rel="noopener noreferrer"
target="_blank"
>
locked
</a>
</gl-link-stub>
.
</span>

View File

@ -1,4 +1,4 @@
import { GlIcon } from '@gitlab/ui';
import { GlIcon, GlSprintf } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import NoteableWarning from '~/vue_shared/components/notes/noteable_warning.vue';
@ -16,6 +16,9 @@ describe('Issue Warning Component', () => {
propsData: {
...props,
},
stubs: {
GlSprintf,
},
});
afterEach(() => {

View File

@ -0,0 +1,51 @@
import { shallowMount } from '@vue/test-utils';
import { GlBadge, GlIcon } from '@gitlab/ui';
import TierBadge from '~/vue_shared/components/tier_badge.vue';
describe('Tier badge component', () => {
let wrapper;
const createComponent = (props) =>
shallowMount(TierBadge, {
propsData: {
...props,
},
});
const findBadge = () => wrapper.findComponent(GlBadge);
const findTierText = () => findBadge().text();
const findIcon = () => wrapper.findComponent(GlIcon);
afterEach(() => {
wrapper.destroy();
});
describe('tiers name', () => {
it.each`
tier | tierText
${'free'} | ${'Free'}
${'premium'} | ${'Premium'}
${'ultimate'} | ${'Ultimate'}
`(
'shows $tierText text in the badge and the license icon when $tier prop is passed',
({ tier, tierText }) => {
wrapper = createComponent({ tier });
expect(findTierText()).toBe(tierText);
expect(findIcon().exists()).toBe(true);
expect(findIcon().props().name).toBe('license');
},
);
});
describe('badge size', () => {
const newSize = 'lg';
beforeEach(() => {
wrapper = createComponent({ tier: 'free', size: newSize });
});
it('passes down the size prop to the GlBadge component', () => {
expect(findBadge().props().size).toBe(newSize);
});
});
});

View File

@ -102,9 +102,9 @@ RSpec.describe Types::BaseEnum do
it 'sets the values defined by the declarative enum' do
set_declarative_enum
expect(enum_type.values.keys).to eq(['FOO'])
expect(enum_type.values.values.map(&:description)).to eq(['description of foo'])
expect(enum_type.values.values.map(&:value)).to eq([0])
expect(enum_type.values.keys).to contain_exactly('FOO')
expect(enum_type.values.values.map(&:description)).to contain_exactly('description of foo')
expect(enum_type.values.values.map(&:value)).to contain_exactly('foo')
end
end
end

View File

@ -0,0 +1,22 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Projects::PipelineHelper do
describe '#js_pipeline_details_data' do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:pipeline) { create(:ci_pipeline, project: project, ref: 'master', sha: project.commit.id) }
subject(:pipeline_details_data) { helper.js_pipeline_details_data(project, pipeline) }
it 'returns pipeline details data' do
expect(pipeline_details_data).to eq({
graphql_resource_etag: graphql_etag_pipeline_path(pipeline),
metrics_path: namespace_project_ci_prometheus_metrics_histograms_path(namespace_id: project.namespace, project_id: project, format: :json),
multi_project_help_path: help_page_path('ci/pipelines/multi_project_pipelines.md', anchor: 'multi-project-pipeline-visualization'),
pipeline_iid: pipeline.iid,
pipeline_project_path: project.full_path
})
end
end
end

View File

@ -168,24 +168,100 @@ RSpec.describe ContainerRegistry::Client do
expect(subject).to eq('Blob')
end
it 'follows 307 redirect for GET /v2/:name/blobs/:digest' do
stub_request(method, url)
.with(headers: blob_headers)
.to_return(status: 307, body: '', headers: { Location: 'http://redirected' })
# We should probably use hash_excluding here, but that requires an update to WebMock:
# https://github.com/bblimke/webmock/blob/master/lib/webmock/matchers/hash_excluding_matcher.rb
stub_request(:get, "http://redirected/")
.with(headers: redirect_header) do |request|
!request.headers.include?('Authorization')
context 'with a 307 redirect' do
let(:redirect_location) { 'http://redirected' }
before do
stub_request(method, url)
.with(headers: blob_headers)
.to_return(status: 307, body: '', headers: { Location: redirect_location })
# We should probably use hash_excluding here, but that requires an update to WebMock:
# https://github.com/bblimke/webmock/blob/master/lib/webmock/matchers/hash_excluding_matcher.rb
stub_request(:get, redirect_location)
.with(headers: redirect_header) do |request|
!request.headers.include?('Authorization')
end
.to_return(status: 200, body: "Successfully redirected")
end
shared_examples 'handling redirects' do
it 'follows the redirect' do
expect(Faraday::Utils).not_to receive(:escape).with('signature=')
expect_new_faraday
expect(subject).to eq('Successfully redirected')
end
.to_return(status: 200, body: "Successfully redirected")
end
expect_new_faraday(times: 2)
it_behaves_like 'handling redirects'
expect(subject).to eq('Successfully redirected')
context 'with a redirect location with params ending with =' do
let(:redirect_location) { 'http://redirect?foo=bar&test=signature=' }
it_behaves_like 'handling redirects'
context 'with container_registry_follow_redirects_middleware disabled' do
before do
stub_feature_flags(container_registry_follow_redirects_middleware: false)
end
it 'follows the redirect' do
expect(Faraday::Utils).to receive(:escape).with('foo').and_call_original
expect(Faraday::Utils).to receive(:escape).with('bar').and_call_original
expect(Faraday::Utils).to receive(:escape).with('test').and_call_original
expect(Faraday::Utils).to receive(:escape).with('signature=').and_call_original
expect_new_faraday(times: 2)
expect(subject).to eq('Successfully redirected')
end
end
end
context 'with a redirect location with params ending with %3D' do
let(:redirect_location) { 'http://redirect?foo=bar&test=signature%3D' }
it_behaves_like 'handling redirects'
context 'with container_registry_follow_redirects_middleware disabled' do
before do
stub_feature_flags(container_registry_follow_redirects_middleware: false)
end
it 'follows the redirect' do
expect(Faraday::Utils).to receive(:escape).with('foo').and_call_original
expect(Faraday::Utils).to receive(:escape).with('bar').and_call_original
expect(Faraday::Utils).to receive(:escape).with('test').and_call_original
expect(Faraday::Utils).to receive(:escape).with('signature=').and_call_original
expect_new_faraday(times: 2)
expect(subject).to eq('Successfully redirected')
end
end
end
end
it_behaves_like 'handling timeouts'
# TODO Remove this context along with the
# container_registry_follow_redirects_middleware feature flag
# See https://gitlab.com/gitlab-org/gitlab/-/issues/353291
context 'faraday blob' do
subject { client.send(:faraday_blob) }
it 'has a follow redirects middleware' do
expect(subject.builder.handlers).to include(::FaradayMiddleware::FollowRedirects)
end
context 'with container_registry_follow_redirects_middleware is disabled' do
before do
stub_feature_flags(container_registry_follow_redirects_middleware: false)
end
it 'has not a follow redirects middleware' do
expect(subject.builder.handlers).not_to include(::FaradayMiddleware::FollowRedirects)
end
end
end
end
describe '#upload_blob' do

Some files were not shown because too many files have changed in this diff Show More