Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
73e15fde38
commit
698fe342b9
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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>
|
|
@ -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"
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}`);
|
||||
|
|
|
@ -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.")
|
||||
}}
|
||||
|
|
|
@ -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>
|
|
@ -5,6 +5,8 @@ class Admin::CohortsController < Admin::ApplicationController
|
|||
|
||||
feature_category :devops_reports
|
||||
|
||||
urgency :low
|
||||
|
||||
def index
|
||||
@cohorts = load_cohorts
|
||||
track_cohorts_visit
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -7,6 +7,8 @@ class Admin::UsageTrendsController < Admin::ApplicationController
|
|||
|
||||
feature_category :devops_reports
|
||||
|
||||
urgency :low
|
||||
|
||||
def index
|
||||
end
|
||||
end
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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? }
|
||||
|
|
|
@ -47,6 +47,15 @@ query getPipelineDetails($projectPath: ID!, $iid: ID!) {
|
|||
id
|
||||
iid
|
||||
complete
|
||||
user {
|
||||
__typename
|
||||
id
|
||||
namespace {
|
||||
__typename
|
||||
id
|
||||
crossProjectPipelineAvailable
|
||||
}
|
||||
}
|
||||
usesNeeds
|
||||
userPermissions {
|
||||
updatePipeline
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1 @@
|
|||
688232dde01ea4e8574dca73459094264bde405d799ecaf1a5867adb72576b98
|
|
@ -0,0 +1 @@
|
|||
84346c2f608792f259ab91dbc2c8aac8397a2997f890f8e077aad809276bb7cd
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 |
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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."
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -66,7 +66,6 @@ describe('graph component', () => {
|
|||
|
||||
afterEach(() => {
|
||||
wrapper.destroy();
|
||||
wrapper = null;
|
||||
});
|
||||
|
||||
describe('with data', () => {
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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', () => {
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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(() => {
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
Loading…
Reference in New Issue