Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
f76e1491c9
commit
469adbda3d
|
|
@ -21,7 +21,7 @@ import CiResourceHeaderSkeletonLoader from './ci_resource_header_skeleton_loader
|
|||
export default {
|
||||
i18n: {
|
||||
moreActionsLabel: __('More actions'),
|
||||
reportAbuse: __('Report abuse to administrator'),
|
||||
reportAbuse: __('Report abuse'),
|
||||
lastRelease: s__('CiCatalog|Released %{date}'),
|
||||
lastReleaseMissing: s__('CiCatalog|No release available'),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -319,7 +319,7 @@ export default {
|
|||
/>
|
||||
<a
|
||||
:v-once="!viewDiffsFileByFile"
|
||||
class="gl-mr-2 gl-text-decoration-none! gl-word-break-all"
|
||||
class="gl-mr-2 gl-text-decoration-none! gl-break-all"
|
||||
:href="titleLink"
|
||||
data-testid="file-title"
|
||||
@click="handleFileNameClick"
|
||||
|
|
|
|||
|
|
@ -34,6 +34,14 @@ const getMRTargetProject = () => {
|
|||
return url.searchParams.get('target_project') || '';
|
||||
};
|
||||
|
||||
const getCrossOriginExtensionHostFlagValue = (extensionsGallerySettings) => {
|
||||
return (
|
||||
extensionsGallerySettings?.enabled ||
|
||||
extensionsGallerySettings?.reason === 'opt_in_unset' ||
|
||||
extensionsGallerySettings?.reason === 'opt_in_disabled'
|
||||
);
|
||||
};
|
||||
|
||||
export const initGitlabWebIDE = async (el) => {
|
||||
// what: Pull what we need from the element. We will replace it soon.
|
||||
const {
|
||||
|
|
@ -87,6 +95,7 @@ export const initGitlabWebIDE = async (el) => {
|
|||
},
|
||||
featureFlags: {
|
||||
settingsSync: true,
|
||||
crossOriginExtensionHost: getCrossOriginExtensionHostFlagValue(extensionsGallerySettings),
|
||||
},
|
||||
editorFont,
|
||||
extensionsGallerySettings,
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ export default {
|
|||
promoteSuccessMessage: __(
|
||||
'The issue was successfully promoted to an epic. Redirecting to epic...',
|
||||
),
|
||||
reportAbuse: __('Report abuse to administrator'),
|
||||
reportAbuse: __('Report abuse'),
|
||||
referenceFetchError: __('An error occurred while fetching reference'),
|
||||
copyReferenceText: __('Copy reference'),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ export default {
|
|||
<template #left-primary>
|
||||
<div class="gl-display-flex gl-align-items-center">
|
||||
<router-link
|
||||
class="gl-text-body gl-font-weight-bold gl-word-break-all"
|
||||
class="gl-text-body gl-font-weight-bold gl-break-all"
|
||||
data-testid="name"
|
||||
:to="linkTo"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ export default {
|
|||
<template>
|
||||
<title-area :metadata-loading="tagsLoading">
|
||||
<template #title>
|
||||
<span class="gl-word-break-all" data-testid="title">
|
||||
<span class="gl-break-all" data-testid="title">
|
||||
{{ artifactDetail.digest }}
|
||||
</span>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ export default {
|
|||
>
|
||||
<gl-link
|
||||
v-if="containsWebPathLink"
|
||||
class="gl-text-body gl-min-w-0 gl-word-break-all"
|
||||
class="gl-text-body gl-min-w-0 gl-break-all"
|
||||
:class="errorPackageStyle"
|
||||
:href="packageLink"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ export default {
|
|||
<router-link
|
||||
v-if="containsWebPathLink"
|
||||
:class="errorPackageStyle"
|
||||
class="gl-text-body gl-min-w-0 gl-word-break-all"
|
||||
class="gl-text-body gl-min-w-0 gl-break-all"
|
||||
data-testid="details-link"
|
||||
:to="{ name: 'details', params: { id: packageId } }"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -789,7 +789,11 @@ export default {
|
|||
<project-setting-row
|
||||
ref="pipeline-settings"
|
||||
:label="$options.i18n.ciCdLabel"
|
||||
:help-text="s__('ProjectSettings|Build, test, and deploy your changes.')"
|
||||
:help-text="
|
||||
s__(
|
||||
'ProjectSettings|Build, test, and deploy your changes. Does not apply to project integrations.',
|
||||
)
|
||||
"
|
||||
>
|
||||
<project-feature-setting
|
||||
v-model="buildsAccessLevel"
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ export default {
|
|||
},
|
||||
inject: ['reportedUserId', 'reportedFromUrl'],
|
||||
i18n: {
|
||||
reportAbuse: s__('ReportAbuse|Report abuse to administrator'),
|
||||
reportAbuse: s__('ReportAbuse|Report abuse'),
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -286,8 +286,8 @@ export default {
|
|||
</gl-link>
|
||||
</gl-alert>
|
||||
<releases-empty-state v-if="shouldRenderEmptyState" />
|
||||
<div v-else class="gl-align-self-end gl-mb-3 gl-display-flex">
|
||||
<releases-sort :value="sort" class="gl-mr-2" @input="onSortChanged" />
|
||||
<div v-else class="gl-align-self-end gl-display-flex gl-gap-3">
|
||||
<releases-sort :value="sort" @input="onSortChanged" />
|
||||
|
||||
<div
|
||||
v-if="newReleasePath"
|
||||
|
|
@ -313,7 +313,7 @@ export default {
|
|||
:class="{ 'linked-card': releases.length > 1 && index !== releases.length - 1 }"
|
||||
/>
|
||||
|
||||
<release-skeleton-loader v-if="shouldRenderLoadingIndicator" />
|
||||
<release-skeleton-loader v-if="shouldRenderLoadingIndicator" class="gl-mt-5" />
|
||||
|
||||
<releases-pagination
|
||||
v-if="shouldRenderPagination"
|
||||
|
|
@ -331,6 +331,6 @@ export default {
|
|||
height: 17px;
|
||||
top: 100%;
|
||||
position: absolute;
|
||||
left: 32px;
|
||||
left: 23px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -59,14 +59,12 @@ export default {
|
|||
|
||||
<template>
|
||||
<div>
|
||||
<div class="card-text gl-mt-3">
|
||||
<b>{{ __('Evidence collection') }}</b>
|
||||
</div>
|
||||
<div v-for="(evidence, index) in evidences" :key="evidenceTitle(index)" class="mb-2">
|
||||
<div class="d-flex gl-align-items-center">
|
||||
<h3 class="gl-heading-5 gl-mb-2!">{{ __('Evidence collection') }}</h3>
|
||||
<div v-for="(evidence, index) in evidences" :key="evidenceTitle(index)">
|
||||
<div class="gl-display-flex gl-align-items-center">
|
||||
<gl-link
|
||||
v-gl-tooltip
|
||||
class="d-flex gl-align-items-center monospace"
|
||||
class="gl-display-flex gl-align-items-center gl-font-monospace"
|
||||
target="_blank"
|
||||
:title="__('Open evidence JSON in new tab')"
|
||||
:href="evidenceUrl(index)"
|
||||
|
|
@ -76,18 +74,18 @@ export default {
|
|||
<gl-icon name="external-link" class="gl-ml-2 gl-flex-shrink-0 gl-flex-grow-0" />
|
||||
</gl-link>
|
||||
|
||||
<expand-button class="gl-ml-4">
|
||||
<expand-button class="gl-display-flex gl-align-items-center gl-gap-2 gl-ml-4">
|
||||
<template #short>
|
||||
<span class="js-short monospace">{{ shortSha(index) }}</span>
|
||||
<span class="js-short gl-font-monospace gl-text-secondary">{{ shortSha(index) }}</span>
|
||||
</template>
|
||||
<template #expanded>
|
||||
<span class="js-expanded monospace gl-pl-2">{{ sha(index) }}</span>
|
||||
<span class="js-expanded gl-font-monospace gl-pl-2">{{ sha(index) }}</span>
|
||||
</template>
|
||||
</expand-button>
|
||||
<clipboard-button :title="__('Copy evidence SHA')" :text="sha(index)" category="tertiary" />
|
||||
</div>
|
||||
|
||||
<div class="d-flex gl-align-items-center text-muted">
|
||||
<div class="gl-display-flex gl-align-items-center gl-text-secondary">
|
||||
<gl-icon
|
||||
v-gl-tooltip
|
||||
name="clock"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
<script>
|
||||
import { GlCard } from '@gitlab/ui';
|
||||
import { isEmpty } from 'lodash';
|
||||
import SafeHtml from '~/vue_shared/directives/safe_html';
|
||||
import { scrollToElement } from '~/lib/utils/common_utils';
|
||||
|
|
@ -16,6 +17,7 @@ import ReleaseBlockMilestoneInfo from './release_block_milestone_info.vue';
|
|||
export default {
|
||||
name: 'ReleaseBlock',
|
||||
components: {
|
||||
GlCard,
|
||||
EvidenceBlock,
|
||||
ReleaseBlockAssets,
|
||||
ReleaseBlockFooter,
|
||||
|
|
@ -92,10 +94,24 @@ export default {
|
|||
};
|
||||
</script>
|
||||
<template>
|
||||
<div :id="htmlId" :class="{ 'bg-line-target-blue': isHighlighted }" class="card release-block">
|
||||
<release-block-header :release="release" />
|
||||
<div class="card-body">
|
||||
<div v-if="shouldRenderMilestoneInfo">
|
||||
<gl-card
|
||||
:id="htmlId"
|
||||
:class="{ 'bg-line-target-blue': isHighlighted }"
|
||||
class="gl-new-card"
|
||||
header-class="gl-new-card-header"
|
||||
body-class="gl-new-card-body gl-px-5 gl-py-4"
|
||||
footer-class="gl-bg-white"
|
||||
data-testid="release-block"
|
||||
>
|
||||
<template #header>
|
||||
<release-block-header :release="release" />
|
||||
</template>
|
||||
|
||||
<div class="gl-display-flex gl-flex-direction-column gl-gap-5">
|
||||
<div
|
||||
v-if="shouldRenderMilestoneInfo"
|
||||
class="gl-border-b-solid gl-border-b-1 gl-border-gray-100"
|
||||
>
|
||||
<!-- TODO: Switch open* links to opened* once fields have been updated in GraphQL -->
|
||||
<release-block-milestone-info
|
||||
:milestones="milestones"
|
||||
|
|
@ -105,27 +121,35 @@ export default {
|
|||
:merged-merge-requests-path="release._links.mergedMergeRequestsUrl"
|
||||
:closed-merge-requests-path="release._links.closedMergeRequestsUrl"
|
||||
/>
|
||||
<hr class="mb-3 mt-0" />
|
||||
</div>
|
||||
|
||||
<release-block-assets v-if="shouldRenderAssets" :assets="assets" />
|
||||
<release-block-assets
|
||||
v-if="shouldRenderAssets"
|
||||
:assets="assets"
|
||||
:class="{
|
||||
'gl-pb-5 gl-border-b-solid gl-border-b-1 gl-border-gray-100':
|
||||
hasEvidence || release.descriptionHtml,
|
||||
}"
|
||||
/>
|
||||
<evidence-block v-if="hasEvidence" :release="release" />
|
||||
|
||||
<div ref="gfm-content" class="card-text gl-mt-3">
|
||||
<div v-if="release.descriptionHtml" ref="gfm-content">
|
||||
<h3 class="gl-heading-5 gl-mb-2!">{{ __('Release notes') }}</h3>
|
||||
<div v-safe-html:[$options.safeHtmlConfig]="release.descriptionHtml" class="md"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<release-block-footer
|
||||
class="card-footer"
|
||||
:commit="release.commit"
|
||||
:commit-path="release.commitPath"
|
||||
:tag-name="release.tagName"
|
||||
:tag-path="release.tagPath"
|
||||
:author="release.author"
|
||||
:released-at="release.releasedAt"
|
||||
:created-at="release.createdAt"
|
||||
:sort="sort"
|
||||
/>
|
||||
</div>
|
||||
<template #footer>
|
||||
<release-block-footer
|
||||
:commit="release.commit"
|
||||
:commit-path="release.commitPath"
|
||||
:tag-name="release.tagName"
|
||||
:tag-path="release.tagPath"
|
||||
:author="release.author"
|
||||
:released-at="release.releasedAt"
|
||||
:created-at="release.createdAt"
|
||||
:sort="sort"
|
||||
/>
|
||||
</template>
|
||||
</gl-card>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -98,11 +98,12 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="card-text gl-mt-3">
|
||||
<div>
|
||||
<gl-button
|
||||
data-testid="accordion-button"
|
||||
variant="link"
|
||||
class="gl-font-weight-bold gl-text-black-normal!"
|
||||
class="gl-text-black-normal!"
|
||||
button-text-classes="gl-heading-5"
|
||||
@click="toggleAssetsExpansion"
|
||||
>
|
||||
<gl-icon
|
||||
|
|
|
|||
|
|
@ -85,14 +85,14 @@ export default {
|
|||
};
|
||||
</script>
|
||||
<template>
|
||||
<div class="gl-display-flex gl-gap-5">
|
||||
<div v-if="commit" class="gl-display-flex gl-align-items-center js-commit-info">
|
||||
<gl-icon ref="commitIcon" name="commit" class="gl-mr-2 gl-text-gray-700" />
|
||||
<div class="gl-display-flex gl-gap-5 gl-align-items-center gl-font-sm">
|
||||
<div v-if="commit" class="gl-display-flex gl-align-items-center gl-gap-2 js-commit-info">
|
||||
<gl-icon ref="commitIcon" name="commit" class="gl-text-secondary" />
|
||||
<div v-gl-tooltip.bottom :title="commit.title">
|
||||
<gl-link
|
||||
v-if="commitPath"
|
||||
:href="commitPath"
|
||||
class="gl-font-sm gl-font-monospace gl-mr-0 gl-text-gray-700"
|
||||
class="gl-font-monospace gl-text-secondary gl-mr-0"
|
||||
>
|
||||
{{ commit.shortId }}
|
||||
</gl-link>
|
||||
|
|
@ -100,23 +100,16 @@ export default {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="tagName" class="gl-display-flex gl-align-items-center js-tag-info">
|
||||
<gl-icon name="tag" class="gl-mr-2 gl-text-gray-700" />
|
||||
<div v-if="tagName" class="gl-display-flex gl-align-items-center gl-gap-2 js-tag-info">
|
||||
<gl-icon name="tag" class="gl-text-secondary" />
|
||||
<div v-gl-tooltip.bottom :title="__('Tag')">
|
||||
<gl-link
|
||||
v-if="tagPath"
|
||||
:href="tagPath"
|
||||
class="gl-font-sm gl-font-monospace gl-mr-0 gl-text-gray-700"
|
||||
>
|
||||
<gl-link v-if="tagPath" :href="tagPath" class="gl-font-monospace gl-mr-0 gl-text-secondary">
|
||||
{{ tagName }}
|
||||
</gl-link>
|
||||
<span v-else>{{ tagName }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="timeAt || author"
|
||||
class="gl-display-flex gl-align-items-center js-author-date-info gl-font-sm"
|
||||
>
|
||||
<div v-if="timeAt || author" class="gl-display-flex gl-align-items-center js-author-date-info">
|
||||
<span class="gl-text-secondary">{{ createdTime }} </span>
|
||||
<template v-if="timeAt">
|
||||
<span
|
||||
|
|
@ -128,7 +121,7 @@ export default {
|
|||
</span>
|
||||
</template>
|
||||
|
||||
<div v-if="author" class="gl-display-flex">
|
||||
<div v-if="author" class="gl-display-flex gl-align-items-center gl-gap-1">
|
||||
<span class="gl-text-secondary">{{ __('by') }} </span>
|
||||
<user-avatar-link
|
||||
:link-href="author.webUrl"
|
||||
|
|
|
|||
|
|
@ -48,8 +48,11 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="card-header d-flex gl-align-items-center bg-white pr-0">
|
||||
<h2 class="card-title gl-my-2 mr-auto gl-font-size-h2">
|
||||
<div class="gl-display-flex gl-align-items-center gl-justify-content-space-between gl-w-full">
|
||||
<h2
|
||||
class="gl-new-card-title gl-heading-3 gl-m-0! gl-display-flex gl-gap-3"
|
||||
data-testid="release-block-title"
|
||||
>
|
||||
<gl-link v-if="selfLink" class="gl-text-black-normal" :href="selfLink">
|
||||
{{ release.name }}
|
||||
</gl-link>
|
||||
|
|
@ -63,17 +66,17 @@ export default {
|
|||
'Private - Guest users are not allowed to view detailed release information like title and source code.',
|
||||
)
|
||||
"
|
||||
class="text-secondary gl-mb-2"
|
||||
class="gl-text-secondary"
|
||||
/>
|
||||
</template>
|
||||
<gl-badge v-if="release.upcomingRelease" variant="warning" class="align-middle">{{
|
||||
<gl-badge v-if="release.upcomingRelease" variant="warning" class="gl-align-self-center">{{
|
||||
__('Upcoming Release')
|
||||
}}</gl-badge>
|
||||
<gl-badge
|
||||
v-else-if="release.historicalRelease"
|
||||
v-gl-tooltip
|
||||
:title="$options.i18n.historicalTooltip"
|
||||
class="gl-align-middle"
|
||||
class="gl-align-self-center"
|
||||
>
|
||||
{{ $options.i18n.historical }}
|
||||
</gl-badge>
|
||||
|
|
@ -83,7 +86,7 @@ export default {
|
|||
category="primary"
|
||||
size="small"
|
||||
variant="default"
|
||||
class="gl-mr-3 js-edit-button gl-ml-3 gl-pb-3"
|
||||
class="js-edit-button"
|
||||
:href="editLink"
|
||||
>
|
||||
{{ $options.i18n.editButton }}
|
||||
|
|
|
|||
|
|
@ -132,10 +132,10 @@ export default {
|
|||
};
|
||||
</script>
|
||||
<template>
|
||||
<div class="release-block-milestone-info gl-display-flex gl-flex-wrap">
|
||||
<div class="release-block-milestone-info gl-display-flex gl-flex-wrap gl-gap-6">
|
||||
<div
|
||||
v-gl-tooltip
|
||||
class="milestone-progress-bar-container js-milestone-progress-bar-container gl-display-flex gl-flex-direction-column gl-mr-6 gl-mb-5"
|
||||
class="milestone-progress-bar-container js-milestone-progress-bar-container gl-display-flex gl-flex-direction-column"
|
||||
:title="__('Closed issues')"
|
||||
>
|
||||
<span class="gl-mb-3">{{ percentCompleteText }}</span>
|
||||
|
|
@ -143,9 +143,7 @@ export default {
|
|||
<gl-progress-bar :value="issueCounts.closed" :max="issueCounts.total" />
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="gl-display-flex gl-flex-direction-column gl-mr-6 gl-mb-5 js-milestone-list-container"
|
||||
>
|
||||
<div class="gl-display-flex gl-flex-direction-column js-milestone-list-container">
|
||||
<span class="gl-mb-2">{{ milestoneLabelText }}</span>
|
||||
<div class="gl-display-flex gl-flex-wrap gl-align-items-flex-end">
|
||||
<template v-for="(milestone, index) in milestonesToDisplay">
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ export default {
|
|||
v-safe-html:[$options.safeHtmlConfig]="commit.titleHtml"
|
||||
:href="commit.webPath"
|
||||
:class="{ 'gl-italic': !commit.message }"
|
||||
class="commit-row-message item-title gl-line-clamp-1 gl-word-break-all!"
|
||||
class="commit-row-message item-title gl-line-clamp-1 !gl-break-all"
|
||||
/>
|
||||
<gl-button
|
||||
v-if="commit.descriptionHtml"
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ export default {
|
|||
class="gl-rounded-base gl-min-w-5 gl-h-5 gl-display-inline-block gl-align-bottom gl-mr-3"
|
||||
:style="{ 'background-color': label.color }"
|
||||
></span>
|
||||
<span class="gl-reset-text-align gl-m-0 gl-p-0 label-title gl-word-break-all">{{
|
||||
<span class="gl-reset-text-align gl-m-0 gl-p-0 label-title gl-break-all">{{
|
||||
label.title
|
||||
}}</span></gl-form-checkbox
|
||||
>
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ export default {
|
|||
</gl-badge>
|
||||
</span>
|
||||
|
||||
<span class="gl-text-gray-500 gl-word-break-all">@{{ user.username }}</span>
|
||||
<span class="gl-text-gray-500 gl-break-all">@{{ user.username }}</span>
|
||||
|
||||
<span
|
||||
v-if="user.status.customized"
|
||||
|
|
|
|||
|
|
@ -13,42 +13,43 @@ import {
|
|||
import { createAlert } from '~/alert';
|
||||
import { __, s__ } from '~/locale';
|
||||
import { helpPagePath } from '~/helpers/help_page_helper';
|
||||
import inboundAddProjectCIJobTokenScopeMutation from '../graphql/mutations/inbound_add_project_ci_job_token_scope.mutation.graphql';
|
||||
import { TYPENAME_GROUP } from '~/graphql_shared/constants';
|
||||
import inboundAddGroupOrProjectCIJobTokenScope from '../graphql/mutations/inbound_add_group_or_project_ci_job_token_scope.mutation.graphql';
|
||||
import inboundRemoveProjectCIJobTokenScopeMutation from '../graphql/mutations/inbound_remove_project_ci_job_token_scope.mutation.graphql';
|
||||
import inboundRemoveGroupCIJobTokenScopeMutation from '../graphql/mutations/inbound_remove_group_ci_job_token_scope.mutation.graphql';
|
||||
import inboundUpdateCIJobTokenScopeMutation from '../graphql/mutations/inbound_update_ci_job_token_scope.mutation.graphql';
|
||||
import inboundGetCIJobTokenScopeQuery from '../graphql/queries/inbound_get_ci_job_token_scope.query.graphql';
|
||||
import inboundGetProjectsWithCIJobTokenScopeQuery from '../graphql/queries/inbound_get_projects_with_ci_job_token_scope.query.graphql';
|
||||
import TokenProjectsTable from './token_projects_table.vue';
|
||||
import inboundGetGroupsAndProjectsWithCIJobTokenScopeQuery from '../graphql/queries/inbound_get_groups_and_projects_with_ci_job_token_scope.query.graphql';
|
||||
import TokenAccessTable from './token_access_table.vue';
|
||||
|
||||
export default {
|
||||
i18n: {
|
||||
toggleLabelTitle: s__('CICD|Limit access %{italicStart}to%{italicEnd} this project'),
|
||||
toggleHelpText: s__(
|
||||
`CICD|Prevent access to this project from other project CI/CD job tokens, unless the other project is added to the allowlist. It is a security risk to disable this feature, because unauthorized projects might attempt to retrieve an active token and access the API. %{linkStart}Learn more%{linkEnd}.`,
|
||||
),
|
||||
cardHeaderTitle: s__(
|
||||
'CICD|Allow CI job tokens from the following projects to access this project',
|
||||
toggleDescription: s__(
|
||||
`CICD|Allow access to this project from authorized groups or projects by adding them to the allowlist. It is a security risk to disable this feature, because unauthorized projects might attempt to retrieve an active token and access the API. %{linkStart}Learn more%{linkEnd}.`,
|
||||
),
|
||||
cardHeaderTitle: s__('CICD|Groups and projects with access'),
|
||||
settingDisabledMessage: s__(
|
||||
'CICD|Enable feature to limit job token access, so only the projects in this list can access this project with a CI/CD job token.',
|
||||
'CICD|No access is currently allowed to this project. Enable feature to authorize access from groups or projects in the allowlist below.',
|
||||
),
|
||||
addProject: __('Add project'),
|
||||
addGroupOrProject: __('Add group or project'),
|
||||
add: __('Add'),
|
||||
cancel: __('Cancel'),
|
||||
addProjectPlaceholder: __('Paste project path (i.e. gitlab-org/gitlab)'),
|
||||
addProjectPlaceholder: __(
|
||||
'Paste group path (i.e. gitlab-org) or project path (i.e. gitlab-org/gitlab)',
|
||||
),
|
||||
projectsFetchError: __('There was a problem fetching the projects'),
|
||||
scopeFetchError: __('There was a problem fetching the job token scope value'),
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
key: 'project',
|
||||
label: __('Project with access'),
|
||||
thClass: 'gl-border-t-none!',
|
||||
key: 'fullPath',
|
||||
label: '',
|
||||
},
|
||||
{
|
||||
key: 'actions',
|
||||
label: '',
|
||||
tdClass: 'gl-text-right',
|
||||
thClass: 'gl-border-t-none!',
|
||||
},
|
||||
],
|
||||
components: {
|
||||
|
|
@ -61,7 +62,7 @@ export default {
|
|||
GlLoadingIcon,
|
||||
GlSprintf,
|
||||
GlToggle,
|
||||
TokenProjectsTable,
|
||||
TokenAccessTable,
|
||||
},
|
||||
inject: {
|
||||
fullPath: {
|
||||
|
|
@ -83,15 +84,16 @@ export default {
|
|||
createAlert({ message: this.$options.i18n.scopeFetchError });
|
||||
},
|
||||
},
|
||||
projects: {
|
||||
query: inboundGetProjectsWithCIJobTokenScopeQuery,
|
||||
groupsAndProjectsWithAccess: {
|
||||
query: inboundGetGroupsAndProjectsWithCIJobTokenScopeQuery,
|
||||
variables() {
|
||||
return {
|
||||
fullPath: this.fullPath,
|
||||
};
|
||||
},
|
||||
update({ project }) {
|
||||
return project?.ciJobTokenScope?.inboundAllowlist?.nodes ?? [];
|
||||
this.projects = project?.ciJobTokenScope?.inboundAllowlist?.nodes ?? [];
|
||||
this.groups = project?.ciJobTokenScope?.groupsAllowlist?.nodes ?? [];
|
||||
},
|
||||
error() {
|
||||
createAlert({ message: this.$options.i18n.projectsFetchError });
|
||||
|
|
@ -101,14 +103,15 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
inboundJobTokenScopeEnabled: null,
|
||||
targetProjectPath: '',
|
||||
targetPath: '',
|
||||
projects: [],
|
||||
groups: [],
|
||||
isAddFormVisible: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
isProjectPathEmpty() {
|
||||
return this.targetProjectPath === '';
|
||||
isTargetPathEmpty() {
|
||||
return this.targetPath === '';
|
||||
},
|
||||
ciJobTokenHelpPage() {
|
||||
return helpPagePath('ci/jobs/ci_job_token#allow-access-to-your-project-with-a-job-token');
|
||||
|
|
@ -139,17 +142,17 @@ export default {
|
|||
createAlert({ message: error.message });
|
||||
}
|
||||
},
|
||||
async addProject() {
|
||||
async addGroupOrProject() {
|
||||
try {
|
||||
const {
|
||||
data: {
|
||||
ciJobTokenScopeAddProject: { errors },
|
||||
ciJobTokenScopeAddGroupOrProject: { errors },
|
||||
},
|
||||
} = await this.$apollo.mutate({
|
||||
mutation: inboundAddProjectCIJobTokenScopeMutation,
|
||||
mutation: inboundAddGroupOrProjectCIJobTokenScope,
|
||||
variables: {
|
||||
projectPath: this.fullPath,
|
||||
targetProjectPath: this.targetProjectPath,
|
||||
targetPath: this.targetPath,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -159,23 +162,38 @@ export default {
|
|||
} catch (error) {
|
||||
createAlert({ message: error.message });
|
||||
} finally {
|
||||
this.clearTargetProjectPath();
|
||||
this.getProjects();
|
||||
this.clearTargetPath();
|
||||
this.getGroupsAndProjects();
|
||||
}
|
||||
},
|
||||
async removeProject(removeTargetPath) {
|
||||
async removeItem(item) {
|
||||
try {
|
||||
const {
|
||||
data: {
|
||||
ciJobTokenScopeRemoveProject: { errors },
|
||||
},
|
||||
} = await this.$apollo.mutate({
|
||||
mutation: inboundRemoveProjectCIJobTokenScopeMutation,
|
||||
variables: {
|
||||
projectPath: this.fullPath,
|
||||
targetProjectPath: removeTargetPath,
|
||||
},
|
||||
});
|
||||
let errors;
|
||||
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
if (item.__typename === TYPENAME_GROUP) {
|
||||
const {
|
||||
data: { ciJobTokenScopeRemoveGroup },
|
||||
} = await this.$apollo.mutate({
|
||||
mutation: inboundRemoveGroupCIJobTokenScopeMutation,
|
||||
variables: {
|
||||
projectPath: this.fullPath,
|
||||
targetGroupPath: item.fullPath,
|
||||
},
|
||||
});
|
||||
errors = ciJobTokenScopeRemoveGroup.errors;
|
||||
} else {
|
||||
const {
|
||||
data: { ciJobTokenScopeRemoveProject },
|
||||
} = await this.$apollo.mutate({
|
||||
mutation: inboundRemoveProjectCIJobTokenScopeMutation,
|
||||
variables: {
|
||||
projectPath: this.fullPath,
|
||||
targetProjectPath: item.fullPath,
|
||||
},
|
||||
});
|
||||
errors = ciJobTokenScopeRemoveProject.errors;
|
||||
}
|
||||
|
||||
if (errors.length) {
|
||||
throw new Error(errors[0]);
|
||||
|
|
@ -183,15 +201,15 @@ export default {
|
|||
} catch (error) {
|
||||
createAlert({ message: error.message });
|
||||
} finally {
|
||||
this.getProjects();
|
||||
this.getGroupsAndProjects();
|
||||
}
|
||||
},
|
||||
clearTargetProjectPath() {
|
||||
this.targetProjectPath = '';
|
||||
clearTargetPath() {
|
||||
this.targetPath = '';
|
||||
this.isAddFormVisible = false;
|
||||
},
|
||||
getProjects() {
|
||||
this.$apollo.queries.projects.refetch();
|
||||
getGroupsAndProjects() {
|
||||
this.$apollo.queries.groupsAndProjectsWithAccess.refetch();
|
||||
},
|
||||
showAddForm() {
|
||||
this.isAddFormVisible = true;
|
||||
|
|
@ -206,6 +224,7 @@ export default {
|
|||
<gl-toggle
|
||||
v-model="inboundJobTokenScopeEnabled"
|
||||
:label="$options.i18n.toggleLabelTitle"
|
||||
class="gl-mt-5"
|
||||
@change="updateCIJobTokenScope"
|
||||
>
|
||||
<template #label>
|
||||
|
|
@ -215,8 +234,8 @@ export default {
|
|||
</template>
|
||||
</gl-sprintf>
|
||||
</template>
|
||||
<template #help>
|
||||
<gl-sprintf :message="$options.i18n.toggleHelpText">
|
||||
<template #description>
|
||||
<gl-sprintf :message="$options.i18n.toggleDescription" class="gl-text-secondary">
|
||||
<template #link="{ content }">
|
||||
<gl-link :href="ciJobTokenHelpPage" class="inline-link" target="_blank">{{
|
||||
content
|
||||
|
|
@ -226,15 +245,29 @@ export default {
|
|||
</template>
|
||||
</gl-toggle>
|
||||
|
||||
<gl-alert
|
||||
v-if="!inboundJobTokenScopeEnabled"
|
||||
variant="warning"
|
||||
class="gl-mt-6"
|
||||
:dismissible="false"
|
||||
:show-icon="false"
|
||||
>
|
||||
{{ $options.i18n.settingDisabledMessage }}
|
||||
</gl-alert>
|
||||
|
||||
<div>
|
||||
<gl-card
|
||||
class="gl-new-card"
|
||||
header-class="gl-new-card-header"
|
||||
header-class="gl-new-card-header gl-border-bottom-0"
|
||||
body-class="gl-new-card-body gl-px-0"
|
||||
>
|
||||
<template #header>
|
||||
<div class="gl-new-card-title-wrapper">
|
||||
<h5 class="gl-new-card-title">{{ $options.i18n.cardHeaderTitle }}</h5>
|
||||
<span class="gl-new-card-count">
|
||||
<gl-icon name="group" class="gl-mr-2" />
|
||||
{{ groups.length }}
|
||||
</span>
|
||||
<span class="gl-new-card-count">
|
||||
<gl-icon name="project" class="gl-mr-2" />
|
||||
{{ projects.length }}
|
||||
|
|
@ -246,46 +279,44 @@ export default {
|
|||
size="small"
|
||||
data-testid="toggle-form-btn"
|
||||
@click="showAddForm"
|
||||
>{{ $options.i18n.addProject }}</gl-button
|
||||
>{{ $options.i18n.addGroupOrProject }}</gl-button
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div v-if="isAddFormVisible" class="gl-new-card-add-form gl-m-3">
|
||||
<h4 class="gl-mt-0">{{ $options.i18n.addProject }}</h4>
|
||||
<h4 class="gl-mt-0">{{ $options.i18n.addGroupOrProject }}</h4>
|
||||
<gl-form-input
|
||||
v-model="targetProjectPath"
|
||||
v-model="targetPath"
|
||||
:placeholder="$options.i18n.addProjectPlaceholder"
|
||||
/>
|
||||
<div class="gl-display-flex gl-mt-5">
|
||||
<gl-button
|
||||
variant="confirm"
|
||||
:disabled="isProjectPathEmpty"
|
||||
:disabled="isTargetPathEmpty"
|
||||
class="gl-mr-3"
|
||||
data-testid="add-project-btn"
|
||||
@click="addProject"
|
||||
@click="addGroupOrProject"
|
||||
>
|
||||
{{ $options.i18n.addProject }}
|
||||
{{ $options.i18n.add }}
|
||||
</gl-button>
|
||||
<gl-button @click="clearTargetProjectPath">{{ $options.i18n.cancel }}</gl-button>
|
||||
<gl-button @click="clearTargetPath">{{ $options.i18n.cancel }}</gl-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<token-projects-table
|
||||
:projects="projects"
|
||||
<token-access-table
|
||||
:is-group="true"
|
||||
:items="groups"
|
||||
:table-fields="$options.fields"
|
||||
@removeProject="removeProject"
|
||||
@removeItem="removeItem"
|
||||
/>
|
||||
|
||||
<token-access-table
|
||||
:items="projects"
|
||||
:table-fields="$options.fields"
|
||||
@removeItem="removeItem"
|
||||
/>
|
||||
</gl-card>
|
||||
<gl-alert
|
||||
v-if="!inboundJobTokenScopeEnabled"
|
||||
class="gl-mb-3"
|
||||
variant="warning"
|
||||
:dismissible="false"
|
||||
:show-icon="false"
|
||||
>
|
||||
{{ $options.i18n.settingDisabledMessage }}
|
||||
</gl-alert>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import removeProjectCIJobTokenScopeMutation from '../graphql/mutations/remove_pr
|
|||
import updateCIJobTokenScopeMutation from '../graphql/mutations/update_ci_job_token_scope.mutation.graphql';
|
||||
import getCIJobTokenScopeQuery from '../graphql/queries/get_ci_job_token_scope.query.graphql';
|
||||
import getProjectsWithCIJobTokenScopeQuery from '../graphql/queries/get_projects_with_ci_job_token_scope.query.graphql';
|
||||
import TokenProjectsTable from './token_projects_table.vue';
|
||||
import TokenAccessTable from './token_access_table.vue';
|
||||
|
||||
// Note: This component will be removed in 17.0, as the outbound access token is getting deprecated
|
||||
export default {
|
||||
|
|
@ -48,15 +48,13 @@ export default {
|
|||
}),
|
||||
fields: [
|
||||
{
|
||||
key: 'project',
|
||||
key: 'fullPath',
|
||||
label: __('Project that can be accessed'),
|
||||
thClass: 'gl-border-t-none!',
|
||||
},
|
||||
{
|
||||
key: 'actions',
|
||||
label: '',
|
||||
tdClass: 'gl-text-right',
|
||||
thClass: 'gl-border-t-none!',
|
||||
},
|
||||
],
|
||||
components: {
|
||||
|
|
@ -68,7 +66,7 @@ export default {
|
|||
GlLoadingIcon,
|
||||
GlSprintf,
|
||||
GlToggle,
|
||||
TokenProjectsTable,
|
||||
TokenAccessTable,
|
||||
},
|
||||
mixins: [glFeatureFlagMixin()],
|
||||
inject: {
|
||||
|
|
@ -174,7 +172,7 @@ export default {
|
|||
this.getProjects();
|
||||
}
|
||||
},
|
||||
async removeProject(removeTargetPath) {
|
||||
async removeProject(project) {
|
||||
try {
|
||||
const {
|
||||
data: {
|
||||
|
|
@ -185,7 +183,7 @@ export default {
|
|||
variables: {
|
||||
input: {
|
||||
projectPath: this.fullPath,
|
||||
targetProjectPath: removeTargetPath,
|
||||
targetProjectPath: project.fullPath,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
@ -282,10 +280,10 @@ export default {
|
|||
<gl-button size="small" disabled>{{ $options.i18n.addProject }}</gl-button>
|
||||
</div>
|
||||
</template>
|
||||
<token-projects-table
|
||||
:projects="projects"
|
||||
<token-access-table
|
||||
:items="projects"
|
||||
:table-fields="$options.fields"
|
||||
@removeProject="removeProject"
|
||||
@removeItem="removeProject"
|
||||
/>
|
||||
</gl-card>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
<script>
|
||||
import { GlButton, GlTableLite } from '@gitlab/ui';
|
||||
import { sprintf, s__ } from '~/locale';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GlButton,
|
||||
GlTableLite,
|
||||
},
|
||||
inject: {
|
||||
fullPath: {
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
props: {
|
||||
isGroup: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
items: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
tableFields: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
emptyText() {
|
||||
return sprintf(s__('CI/CD|No %{itemType}s have been added to the scope'), {
|
||||
itemType: this.itemType,
|
||||
});
|
||||
},
|
||||
itemType() {
|
||||
return this.isGroup ? 'group' : 'project';
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<gl-table-lite
|
||||
:items="items"
|
||||
:fields="tableFields"
|
||||
:tbody-tr-attr="{ 'data-testid': `${itemType}s-token-table-row` }"
|
||||
:empty-text="emptyText"
|
||||
show-empty
|
||||
stacked="sm"
|
||||
thead-class="gl-display-none"
|
||||
fixed
|
||||
>
|
||||
<template #cell(fullPath)="{ item }">
|
||||
<span :data-testid="`token-access-${itemType}-name`">{{ item.fullPath }}</span>
|
||||
</template>
|
||||
|
||||
<template #cell(actions)="{ item }">
|
||||
<gl-button
|
||||
v-if="item.fullPath !== fullPath"
|
||||
category="primary"
|
||||
icon="remove"
|
||||
:aria-label="__('Remove access')"
|
||||
@click="$emit('removeItem', item)"
|
||||
/>
|
||||
</template>
|
||||
</gl-table-lite>
|
||||
</template>
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
<script>
|
||||
import { GlButton, GlTable } from '@gitlab/ui';
|
||||
import { s__ } from '~/locale';
|
||||
|
||||
export default {
|
||||
i18n: {
|
||||
emptyText: s__('CI/CD|No projects have been added to the scope'),
|
||||
},
|
||||
components: {
|
||||
GlButton,
|
||||
GlTable,
|
||||
},
|
||||
inject: {
|
||||
fullPath: {
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
props: {
|
||||
projects: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
tableFields: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
removeProject(project) {
|
||||
this.$emit('removeProject', project);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<gl-table
|
||||
:items="projects"
|
||||
:fields="tableFields"
|
||||
:tbody-tr-attr="{ 'data-testid': 'projects-token-table-row' }"
|
||||
:empty-text="$options.i18n.emptyText"
|
||||
show-empty
|
||||
stacked="sm"
|
||||
fixed
|
||||
>
|
||||
<template #table-colgroup="{ fields }">
|
||||
<col v-for="field in fields" :key="field.key" :class="field.columnClass" />
|
||||
</template>
|
||||
|
||||
<template #cell(project)="{ item }">
|
||||
<span data-testid="token-access-project-name">{{ item.fullPath }}</span>
|
||||
</template>
|
||||
|
||||
<template #cell(actions)="{ item }">
|
||||
<gl-button
|
||||
v-if="item.fullPath !== fullPath"
|
||||
category="primary"
|
||||
variant="danger"
|
||||
icon="remove"
|
||||
:aria-label="__('Remove access')"
|
||||
@click="removeProject(item.fullPath)"
|
||||
/>
|
||||
</template>
|
||||
</gl-table>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
mutation inboundAddGroupOrProjectCIJobTokenScope($projectPath: ID!, $targetPath: ID!) {
|
||||
ciJobTokenScopeAddGroupOrProject(input: { projectPath: $projectPath, targetPath: $targetPath }) {
|
||||
errors
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
mutation inboundAddProjectCIJobTokenScope($projectPath: ID!, $targetProjectPath: ID!) {
|
||||
ciJobTokenScopeAddProject(
|
||||
input: { projectPath: $projectPath, targetProjectPath: $targetProjectPath, direction: INBOUND }
|
||||
) {
|
||||
errors
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
mutation inboundRemoveGroupCIJobTokenScope($projectPath: ID!, $targetGroupPath: ID!) {
|
||||
ciJobTokenScopeRemoveGroup(
|
||||
input: { projectPath: $projectPath, targetGroupPath: $targetGroupPath }
|
||||
) {
|
||||
errors
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +1,18 @@
|
|||
query inboundGetProjectsWithCIJobTokenScope($fullPath: ID!) {
|
||||
query inboundGetGroupsAndProjectsWithCIJobTokenScope($fullPath: ID!) {
|
||||
project(fullPath: $fullPath) {
|
||||
id
|
||||
ciJobTokenScope {
|
||||
groupsAllowlist {
|
||||
nodes {
|
||||
id
|
||||
name
|
||||
fullPath
|
||||
}
|
||||
}
|
||||
inboundAllowlist {
|
||||
nodes {
|
||||
id
|
||||
name
|
||||
namespace {
|
||||
id
|
||||
fullPath
|
||||
}
|
||||
fullPath
|
||||
}
|
||||
}
|
||||
|
|
@ -76,7 +76,7 @@ export default {
|
|||
userId: s__('UserProfile|Copy user ID: %{id}'),
|
||||
userIdCopied: s__('UserProfile|User ID copied to clipboard'),
|
||||
rssSubscribe: s__('UserProfile|Subscribe'),
|
||||
reportToAdmin: s__('ReportAbuse|Report abuse to administrator'),
|
||||
reportToAdmin: s__('ReportAbuse|Report abuse'),
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ export default {
|
|||
|
||||
<template>
|
||||
<div
|
||||
class="gl-display-flex gl-align-items-top gl-font-monospace gl-font-sm gl-word-break-all"
|
||||
class="gl-display-flex gl-align-items-top gl-font-monospace gl-font-sm gl-break-all"
|
||||
:class="[padding, borderClass]"
|
||||
>
|
||||
<div v-if="icon" class="gl-w-5 gl-mr-4">
|
||||
|
|
|
|||
|
|
@ -265,10 +265,7 @@ export default {
|
|||
<span class="gl-sr-only">{{ issuable.title }}</span>
|
||||
</gl-form-checkbox>
|
||||
<div class="issuable-main-info">
|
||||
<div
|
||||
data-testid="issuable-title"
|
||||
class="issue-title title gl-display-flex gl-align-items-center"
|
||||
>
|
||||
<div data-testid="issuable-title" class="issue-title title gl-font-size-0">
|
||||
<work-item-type-icon
|
||||
v-if="showWorkItemTypeIcon"
|
||||
class="gl-mr-2"
|
||||
|
|
@ -281,6 +278,7 @@ export default {
|
|||
name="eye-slash"
|
||||
:title="__('Confidential')"
|
||||
:aria-label="__('Confidential')"
|
||||
class="gl-mr-2"
|
||||
/>
|
||||
<gl-icon
|
||||
v-if="issuable.hidden"
|
||||
|
|
@ -290,7 +288,7 @@ export default {
|
|||
:aria-label="__('Hidden')"
|
||||
/>
|
||||
<gl-link
|
||||
class="issue-title-text"
|
||||
class="issue-title-text gl-font-base"
|
||||
dir="auto"
|
||||
:href="issuableLinkHref"
|
||||
data-testid="issuable-title-link"
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ export default {
|
|||
copyLinkText: __('Copy link'),
|
||||
assignUserText: __('Assign to commenting user'),
|
||||
unassignUserText: __('Unassign from commenting user'),
|
||||
reportAbuseText: __('Report abuse to administrator'),
|
||||
reportAbuseText: __('Report abuse'),
|
||||
},
|
||||
components: {
|
||||
EmojiPicker: () => import('~/emoji/components/picker.vue'),
|
||||
|
|
|
|||
|
|
@ -42,8 +42,8 @@ class Projects::BranchesController < Projects::ApplicationController
|
|||
render status: :service_unavailable
|
||||
end
|
||||
format.json do
|
||||
branches = BranchesFinder.new(@repository, params).execute
|
||||
branches = Kaminari.paginate_array(branches).page(params[:page])
|
||||
branches = BranchesFinder.new(@repository, branches_params).execute
|
||||
branches = Kaminari.paginate_array(branches).page(branches_params[:page])
|
||||
render json: branches.map(&:name)
|
||||
end
|
||||
end
|
||||
|
|
@ -135,7 +135,7 @@ class Projects::BranchesController < Projects::ApplicationController
|
|||
private
|
||||
|
||||
def sort_param
|
||||
sort = params[:sort].presence
|
||||
sort = branches_params[:sort].presence
|
||||
|
||||
unless sort.in?(supported_sort_options)
|
||||
flash.now[:alert] = _("Unsupported sort value.")
|
||||
|
|
@ -191,7 +191,7 @@ class Projects::BranchesController < Projects::ApplicationController
|
|||
|
||||
def redirect_for_legacy_index_sort_or_search
|
||||
# Normalize a legacy URL with redirect
|
||||
if request.format != :json && !params[:state].presence && [:sort, :search, :page].any? { |key| params[key].presence }
|
||||
if request.format != :json && !branches_params[:state].presence && [:sort, :search, :page].any? { |key| branches_params[key].presence }
|
||||
redirect_to project_branches_filtered_path(@project, state: 'all'), notice: _('Update your bookmarked URLs as filtered/sorted branches URL has been changed.')
|
||||
end
|
||||
end
|
||||
|
|
@ -200,7 +200,7 @@ class Projects::BranchesController < Projects::ApplicationController
|
|||
return fetch_branches_for_overview if @mode == 'overview'
|
||||
|
||||
@branches, @prev_path, @next_path =
|
||||
Projects::BranchesByModeService.new(@project, params.merge(sort: @sort, mode: @mode)).execute
|
||||
Projects::BranchesByModeService.new(@project, branches_params.merge(sort: @sort, mode: @mode)).execute
|
||||
end
|
||||
|
||||
def fetch_merge_requests_for_branches
|
||||
|
|
@ -227,7 +227,7 @@ class Projects::BranchesController < Projects::ApplicationController
|
|||
end
|
||||
|
||||
def fetch_mode
|
||||
state = params[:state].presence
|
||||
state = branches_params[:state].presence
|
||||
|
||||
return 'overview' unless state
|
||||
|
||||
|
|
@ -243,4 +243,8 @@ class Projects::BranchesController < Projects::ApplicationController
|
|||
|
||||
confidential_issue_project
|
||||
end
|
||||
|
||||
def branches_params
|
||||
params.permit(:page, :state, :sort, :search, :page_token, :offset)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ class Projects::NotesController < Projects::ApplicationController
|
|||
include NotesHelper
|
||||
include ToggleAwardEmoji
|
||||
|
||||
before_action :disable_query_limiting, only: [:create, :update]
|
||||
before_action :disable_query_limiting, only: [:create, :update, :index]
|
||||
before_action :authorize_read_note!
|
||||
before_action :authorize_create_note!, only: [:create]
|
||||
before_action :authorize_resolve_note!, only: [:resolve, :unresolve]
|
||||
|
|
@ -118,6 +118,8 @@ class Projects::NotesController < Projects::ApplicationController
|
|||
end
|
||||
|
||||
def disable_query_limiting
|
||||
# Using a single disable! Call to not repeat this code, but there are different issues created for each action
|
||||
# index: https://gitlab.com/gitlab-org/gitlab/-/issues/460923
|
||||
Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab/-/issues/20800')
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,10 +4,11 @@ module Issues
|
|||
class ConfidentialityFilter < Issuables::BaseFilter
|
||||
CONFIDENTIAL_ACCESS_LEVEL = Gitlab::Access::REPORTER
|
||||
|
||||
def initialize(current_user:, parent:, assignee_filter:, **kwargs)
|
||||
def initialize(current_user:, parent:, assignee_filter:, related_groups: nil, **kwargs)
|
||||
@current_user = current_user
|
||||
@parent = parent
|
||||
@assignee_filter = assignee_filter
|
||||
@related_groups = related_groups
|
||||
|
||||
super(**kwargs)
|
||||
end
|
||||
|
|
@ -24,7 +25,7 @@ module Issues
|
|||
issues.confidential_only.merge(
|
||||
issues.authored(@current_user)
|
||||
.or(issues.assigned_to(@current_user))
|
||||
.or(access_to_project_exists(issues))
|
||||
.or(access_to_parent_exists(issues))
|
||||
)
|
||||
).allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/422045')
|
||||
end
|
||||
|
|
@ -41,13 +42,23 @@ module Issues
|
|||
@assignee_filter.includes_user?(@current_user)
|
||||
end
|
||||
|
||||
def access_to_project_exists(issues)
|
||||
issues.where_exists(
|
||||
def access_to_parent_exists(issues)
|
||||
access_to_project_level_issue_exists = issues.where_exists(
|
||||
@current_user.authorizations_for_projects(
|
||||
min_access_level: CONFIDENTIAL_ACCESS_LEVEL,
|
||||
related_project_column: 'issues.project_id'
|
||||
)
|
||||
)
|
||||
|
||||
return access_to_project_level_issue_exists if @related_groups.nil?
|
||||
|
||||
access_to_project_level_issue_exists.project_level.or(
|
||||
issues.group_level.in_namespaces(
|
||||
Group.id_in(
|
||||
Group.groups_user_can(@related_groups, @current_user, :read_confidential_issues, same_root: true)
|
||||
)
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -67,16 +67,6 @@ class IssuesFinder < IssuableFinder
|
|||
super.with_projects_matching_search_data
|
||||
end
|
||||
|
||||
def group_namespaces
|
||||
return if params[:project_id] || params[:projects]
|
||||
|
||||
Group.id_in(params.group).select(:id)
|
||||
end
|
||||
|
||||
def project_namespaces
|
||||
params.projects.select(:project_namespace_id)
|
||||
end
|
||||
|
||||
def by_confidential(items)
|
||||
Issues::ConfidentialityFilter.new(
|
||||
current_user: current_user,
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
# WorkItems instead of Issues
|
||||
module WorkItems
|
||||
class WorkItemsFinder < IssuesFinder
|
||||
include Gitlab::Utils::StrongMemoize
|
||||
|
||||
def klass
|
||||
WorkItem
|
||||
end
|
||||
|
|
@ -47,12 +49,27 @@ module WorkItems
|
|||
super
|
||||
end
|
||||
|
||||
override :by_confidential
|
||||
def by_confidential(items)
|
||||
return super unless include_namespace_level_work_items?
|
||||
|
||||
Issues::ConfidentialityFilter.new(
|
||||
current_user: current_user,
|
||||
params: original_params,
|
||||
parent: root_ancestor_group,
|
||||
assignee_filter: assignee_filter,
|
||||
related_groups: related_groups
|
||||
).filter(items)
|
||||
end
|
||||
|
||||
override :by_parent
|
||||
def by_parent(items)
|
||||
return super unless include_namespace_level_work_items?
|
||||
|
||||
relations = [group_namespaces, project_namespaces].compact
|
||||
|
||||
return items.none if relations.empty?
|
||||
|
||||
namespaces = if relations.one?
|
||||
relations.first
|
||||
else
|
||||
|
|
@ -62,8 +79,68 @@ module WorkItems
|
|||
items.in_namespaces(namespaces)
|
||||
end
|
||||
|
||||
def group_namespaces
|
||||
return if params[:project_id] || params[:projects]
|
||||
|
||||
related_groups_with_access.select(:id)
|
||||
end
|
||||
|
||||
def related_groups_with_access
|
||||
# If the user is not signed in, we just return public groups
|
||||
return related_groups.public_to_user unless current_user
|
||||
|
||||
# If the user is an admin or a member of the root group, they will have read access to all
|
||||
# work items in the subgroups so we can skip the expensive permissions check
|
||||
if Ability.allowed?(current_user, :read_all_resources) || root_ancestor_group.member?(current_user)
|
||||
return related_groups
|
||||
end
|
||||
|
||||
Group.id_in(
|
||||
Group.groups_user_can(related_groups, current_user, :read_work_item, same_root: true)
|
||||
)
|
||||
end
|
||||
|
||||
def related_groups
|
||||
if include_ancestors? && include_descendants?
|
||||
params.group.self_and_hierarchy
|
||||
elsif include_ancestors?
|
||||
params.group.self_and_ancestors
|
||||
elsif include_descendants?
|
||||
params.group.self_and_descendants
|
||||
else
|
||||
Group.id_in(params.group.id)
|
||||
end
|
||||
end
|
||||
strong_memoize_attr :related_groups
|
||||
|
||||
def root_ancestor_group
|
||||
include_ancestors? ? params.group.root_ancestor : params.group
|
||||
end
|
||||
|
||||
def project_namespaces
|
||||
return unless include_descendants?
|
||||
|
||||
projects = Project.in_namespace(params.group.self_and_descendant_ids)
|
||||
projects = projects.id_in(params[:projects]) if params[:projects]
|
||||
|
||||
projects
|
||||
.public_or_visible_to_user(current_user, ProjectFeature.required_minimum_access_level(klass.base_class))
|
||||
.with_feature_available_for_user(klass.base_class, current_user)
|
||||
.select(:project_namespace_id)
|
||||
end
|
||||
|
||||
def include_namespace_level_work_items?
|
||||
params.group? && Feature.enabled?(:namespace_level_work_items, params.group)
|
||||
end
|
||||
|
||||
def include_descendants?
|
||||
params.fetch(:include_descendants, false)
|
||||
end
|
||||
strong_memoize_attr :include_descendants?
|
||||
|
||||
def include_ancestors?
|
||||
params.fetch(:include_ancestors, false)
|
||||
end
|
||||
strong_memoize_attr :include_ancestors?
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Mutations
|
||||
module Ci
|
||||
module Runner
|
||||
module Cache
|
||||
class Clear < BaseMutation
|
||||
graphql_name 'RunnerCacheClear'
|
||||
|
||||
authorize :admin_pipeline
|
||||
|
||||
argument :project_id, ::Types::GlobalIDType[Project],
|
||||
required: true,
|
||||
description: 'Global ID of the project that will have its runner cache cleared.'
|
||||
|
||||
def resolve(project_id:)
|
||||
project = authorized_find!(id: project_id)
|
||||
|
||||
ResetProjectCacheService.new(project, current_user).execute
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -4,6 +4,16 @@ module Resolvers
|
|||
module Namespaces
|
||||
# rubocop:disable Graphql/ResolverType -- inherited from Resolvers::WorkItemsResolver
|
||||
class WorkItemsResolver < ::Resolvers::WorkItemsResolver
|
||||
argument :include_ancestors, GraphQL::Types::Boolean,
|
||||
required: false,
|
||||
default_value: false,
|
||||
description: 'Include work items from ancestor groups.'
|
||||
|
||||
argument :include_descendants, GraphQL::Types::Boolean,
|
||||
required: false,
|
||||
default_value: false,
|
||||
description: 'Include work items from descendant groups and projects.'
|
||||
|
||||
def ready?(**args)
|
||||
return false if Feature.disabled?(:namespace_level_work_items, resource_parent)
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@ module Types
|
|||
description: 'Components belonging to the catalog resource.',
|
||||
alpha: { milestone: '16.7' }
|
||||
|
||||
# TODO: Turn this into a proper markup_field, which will require some refactoring.
|
||||
# https://gitlab.com/gitlab-org/gitlab/-/issues/460462
|
||||
field :readme_html, GraphQL::Types::String, null: true, calls_gitaly: true,
|
||||
description: 'GitLab Flavored Markdown rendering of README.md. This field ' \
|
||||
'can only be resolved for one version in any single request.',
|
||||
|
|
@ -51,10 +53,8 @@ module Types
|
|||
end
|
||||
|
||||
def readme_html
|
||||
return unless Ability.allowed?(current_user, :read_code, object.project)
|
||||
|
||||
markdown_context = context.to_h.dup.merge(project: object.project)
|
||||
::MarkupHelper.markdown(object.readme&.data, markdown_context)
|
||||
ctx = context.to_h.dup.merge(project: object.project)
|
||||
::MarkupHelper.markdown(object.readme.data, ctx, { requested_path: object.readme.path })
|
||||
end
|
||||
end
|
||||
# rubocop: enable Graphql/AuthorizeTypes
|
||||
|
|
|
|||
|
|
@ -171,6 +171,7 @@ module Types
|
|||
mount_mutation Mutations::Ci::PipelineTrigger::Update, alpha: { milestone: '16.3' }
|
||||
mount_mutation Mutations::Ci::ProjectCiCdSettingsUpdate
|
||||
mount_mutation Mutations::Ci::Runner::BulkDelete, alpha: { milestone: '15.3' }
|
||||
mount_mutation Mutations::Ci::Runner::Cache::Clear
|
||||
mount_mutation Mutations::Ci::Runner::Create, alpha: { milestone: '15.10' }
|
||||
mount_mutation Mutations::Ci::Runner::Delete
|
||||
mount_mutation Mutations::Ci::Runner::Update
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ module Types
|
|||
end
|
||||
|
||||
permission_field :can_merge, calls_gitaly: true
|
||||
permission_field :can_approve
|
||||
permission_field :can_approve, calls_gitaly: true
|
||||
|
||||
def can_merge
|
||||
object.can_be_merged_by?(context[:current_user])
|
||||
|
|
|
|||
|
|
@ -83,13 +83,14 @@ module MarkupHelper
|
|||
render_links(text)
|
||||
end
|
||||
|
||||
def markdown(text, context = {})
|
||||
def markdown(text, context = {}, postprocess = {})
|
||||
return '' unless text.present?
|
||||
|
||||
context[:project] ||= @project
|
||||
context[:group] ||= @group
|
||||
|
||||
html = Markup::RenderingService.new(text, context: context, postprocess_context: postprocess_context).execute
|
||||
html = Markup::RenderingService.new(text, context: context,
|
||||
postprocess_context: postprocess_context.merge!(postprocess)).execute
|
||||
|
||||
Hamlit::RailsHelpers.preserve(html)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1160,23 +1160,7 @@ module Ci
|
|||
end
|
||||
|
||||
def job_jwt_variables
|
||||
if Feature.enabled?(:remove_shared_jwts) || id_tokens?
|
||||
id_tokens_variables
|
||||
else
|
||||
predefined_jwt_variables
|
||||
end
|
||||
end
|
||||
|
||||
def predefined_jwt_variables
|
||||
Gitlab::Ci::Variables::Collection.new.tap do |variables|
|
||||
jwt = Gitlab::Ci::Jwt.for_build(self)
|
||||
jwt_v2 = Gitlab::Ci::JwtV2.for_build(self)
|
||||
variables.append(key: 'CI_JOB_JWT', value: jwt, public: false, masked: true)
|
||||
variables.append(key: 'CI_JOB_JWT_V1', value: jwt, public: false, masked: true)
|
||||
variables.append(key: 'CI_JOB_JWT_V2', value: jwt_v2, public: false, masked: true)
|
||||
rescue OpenSSL::PKey::RSAError, Gitlab::Ci::Jwt::NoSigningKeyError => e
|
||||
Gitlab::ErrorTracking.track_exception(e)
|
||||
end
|
||||
id_tokens_variables
|
||||
end
|
||||
|
||||
def id_tokens_variables
|
||||
|
|
|
|||
|
|
@ -177,12 +177,12 @@ class CommitCollection
|
|||
def committer_emails_for(commits, include_author_when_signed: false)
|
||||
commit_author_change_enabled = ::Feature.enabled?(:web_ui_commit_author_change, project)
|
||||
|
||||
if commit_author_change_enabled
|
||||
if include_author_when_signed && commit_author_change_enabled
|
||||
commits.each(&:signature) # preload signatures
|
||||
end
|
||||
|
||||
commits.filter_map do |commit|
|
||||
if commit_author_change_enabled && commit.signature&.verified_system? && include_author_when_signed
|
||||
if include_author_when_signed && commit_author_change_enabled && commit.signature&.verified_system?
|
||||
commit.author_email
|
||||
else
|
||||
commit.committer_email
|
||||
|
|
|
|||
|
|
@ -124,6 +124,9 @@ class Issue < ApplicationRecord
|
|||
|
||||
pg_full_text_searchable columns: [{ name: 'title', weight: 'A' }, { name: 'description', weight: 'B' }]
|
||||
|
||||
scope :project_level, -> { where.not(project_id: nil) }
|
||||
scope :group_level, -> { where(project_id: nil) }
|
||||
|
||||
scope :in_namespaces, ->(namespaces) { where(namespace: namespaces) }
|
||||
scope :in_projects, ->(project_ids) { where(project_id: project_ids) }
|
||||
scope :not_in_projects, ->(project_ids) { where.not(project_id: project_ids) }
|
||||
|
|
|
|||
|
|
@ -176,6 +176,7 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
|
|||
enable :read_custom_emoji
|
||||
enable :read_counts
|
||||
enable :read_issue
|
||||
enable :read_work_item
|
||||
enable :read_namespace
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
.js-table-contents
|
||||
= blob_icon blob.mode, blob.name
|
||||
|
||||
%strong.file-title-name.gl-word-break-all{ data: { testid: 'file-name-content' } }
|
||||
%strong.file-title-name.gl-break-all{ data: { testid: 'file-name-content' } }
|
||||
= blob.name
|
||||
|
||||
= copy_file_path_button(blob.path)
|
||||
|
|
|
|||
|
|
@ -17,13 +17,13 @@
|
|||
|
||||
- if diff_file.renamed_file?
|
||||
- old_path, new_path = mark_inline_diffs(diff_file.old_path, diff_file.new_path)
|
||||
%strong.file-title-name.has-tooltip.gl-word-break-all{ data: { title: diff_file.old_path, container: 'body' } }
|
||||
%strong.file-title-name.has-tooltip.gl-break-all{ data: { title: diff_file.old_path, container: 'body' } }
|
||||
= old_path
|
||||
→
|
||||
%strong.file-title-name.has-tooltip.gl-word-break-all{ data: { title: diff_file.new_path, container: 'body' } }
|
||||
%strong.file-title-name.has-tooltip.gl-break-all{ data: { title: diff_file.new_path, container: 'body' } }
|
||||
= new_path
|
||||
- else
|
||||
%strong.file-title-name.has-tooltip.gl-word-break-all{ data: { title: diff_file.file_path, container: 'body', testid: 'file-name-content' } }
|
||||
%strong.file-title-name.has-tooltip.gl-break-all{ data: { title: diff_file.file_path, container: 'body', testid: 'file-name-content' } }
|
||||
= diff_file.file_path
|
||||
|
||||
- if diff_file.deleted_file?
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
.well-segment
|
||||
.gl-justify-content-left.gl-display-flex.gl-align-items-center
|
||||
= render Pajamas::AvatarComponent.new(current_user, size: 24, avatar_options: { data: { qa_selector: 'user_avatar_content' }, title: current_user.username })
|
||||
.gl-pl-4.gl-word-break-all
|
||||
.gl-pl-4.gl-break-all
|
||||
%span= _('Signed in as %{username}') % { username: '@' + current_user.username }
|
||||
= gitlab_ui_form_for @user, url: user_settings_password_path, method: :post do |f|
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,11 @@ module Gitlab
|
|||
|
||||
importer.execute
|
||||
|
||||
ImportUsersWorker.perform_async(project.id)
|
||||
if Feature.enabled?(:bitbucket_server_convert_mentions_to_users, project.creator)
|
||||
ImportUsersWorker.perform_async(project.id)
|
||||
else
|
||||
ImportPullRequestsWorker.perform_async(project.id)
|
||||
end
|
||||
end
|
||||
|
||||
def importer_class
|
||||
|
|
|
|||
|
|
@ -5,5 +5,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/146878
|
|||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/448342
|
||||
milestone: '16.10'
|
||||
group: group::source code
|
||||
type: gitlab_com_derisk
|
||||
default_enabled: false
|
||||
type: beta
|
||||
default_enabled: true
|
||||
|
|
@ -5,5 +5,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/148889
|
|||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/455288
|
||||
milestone: '16.11'
|
||||
group: group::source code
|
||||
type: gitlab_com_derisk
|
||||
default_enabled: false
|
||||
type: beta
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
name: bitbucket_server_convert_mentions_to_users
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/139097
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/434453
|
||||
milestone: '16.7'
|
||||
type: development
|
||||
group: group::import and integrate
|
||||
default_enabled: false
|
||||
|
|
@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350460
|
|||
milestone: '13.8'
|
||||
type: development
|
||||
group: group::respond
|
||||
default_enabled: false
|
||||
default_enabled: true
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
---
|
||||
name: deprecate_unified_approval_rules
|
||||
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/388191
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/150182
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/457258
|
||||
milestone: '17.0'
|
||||
group: group::environments
|
||||
type: gitlab_com_derisk
|
||||
default_enabled: false
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
---
|
||||
name: remove_shared_jwts
|
||||
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/423106
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/148106
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/452294
|
||||
milestone: '16.11'
|
||||
group: group::pipeline security
|
||||
type: gitlab_com_derisk
|
||||
default_enabled: false
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
- title: "Breaking change to the Maven repository group permissions"
|
||||
announcement_milestone: "16.6"
|
||||
removal_milestone: "17.0"
|
||||
removal_milestone: "18.0"
|
||||
breaking_change: true
|
||||
reporter: trizzi
|
||||
stage: Package
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
The Maven repository exposes an API endpoint at the group level that allows Maven clients to download files from a specific package. The package finder first locates the package within the group, and then finds the file within the package.
|
||||
However, there is a limitation that affects duplicate package names hosted in different projects. The Maven package finder always returns the most recent package, but the "most recent" filter depends on user permissions. It is possible for a user with different permissions in different projects to download the wrong Maven package.
|
||||
|
||||
In GitLab 17.0, the package finder logic will be fixed so that the "most recent" package is the last updated name and version of a package in a group. User permissions will be checked after the most recent package is found.
|
||||
In GitLab 18.0, the package finder logic will be fixed so that the "most recent" package is the last updated name and version of a package in a group. User permissions will be checked after the most recent package is found.
|
||||
After the change, download requests for users without correct permissions will be rejected. If your workflow depends on the current bugged behavior, this fix will introduce a breaking change.
|
||||
|
||||
The change will be introduced in GitLab 16.6 behind a feature flag. If you are interested in enabling the feature flag for your group, leave a comment in [issue 393933](https://gitlab.com/gitlab-org/gitlab/-/issues/393933).
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
- title: "Dependency Proxy: Access tokens to have additional scope checks"
|
||||
announcement_milestone: "16.7"
|
||||
removal_milestone: "17.0"
|
||||
removal_milestone: "18.0"
|
||||
breaking_change: true
|
||||
reporter: trizzi
|
||||
stage: Package
|
||||
|
|
@ -8,6 +8,6 @@
|
|||
body: |
|
||||
When using the Dependency Proxy for containers with a group access token or personal access token, `docker login` and `docker pull` requests with insufficient scopes for Dependency Proxy are not rejected.
|
||||
|
||||
GitLab 17.0 adds checks for group or personal access tokens authenticating with the dependency proxy for containers. This is a breaking change, because tokens without the required scopes will fail.
|
||||
GitLab 18.0 adds checks for group or personal access tokens authenticating with the dependency proxy for containers. This is a breaking change, because tokens without the required scopes will fail.
|
||||
|
||||
To help avoid being impacted by this breaking change, create new access tokens with the [required scopes](https://docs.gitlab.com/ee/user/packages/dependency_proxy/#authenticate-with-the-dependency-proxy), and update your workflow variables and scripts with those new tokens.
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ description: Used to replicate storage attachments migration paths on Geo second
|
|||
from regular to hashed storage.
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/3544
|
||||
milestone: '10.3'
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/151938
|
||||
removed_in_milestone: '17.0'
|
||||
gitlab_schema: gitlab_main_cell
|
||||
allow_cross_joins:
|
||||
- gitlab_main_clusterwide
|
||||
|
|
@ -8,6 +8,8 @@ description: Used to replicate repository migration paths on Geo secondaries fro
|
|||
regular to hashed storage.
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/3066
|
||||
milestone: '10.2'
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/151938
|
||||
removed_in_milestone: '17.0'
|
||||
gitlab_schema: gitlab_main_cell
|
||||
allow_cross_joins:
|
||||
- gitlab_main_clusterwide
|
||||
|
|
@ -7,6 +7,8 @@ feature_categories:
|
|||
description: Geo event for when a repository gets created, belongs to geo_event_log.
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/f3eacf881659b7af97b7c7ba3289237ec6cdc1cb
|
||||
milestone: '10.0'
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/151938
|
||||
removed_in_milestone: '17.0'
|
||||
gitlab_schema: gitlab_main_cell
|
||||
allow_cross_joins:
|
||||
- gitlab_main_clusterwide
|
||||
|
|
@ -7,6 +7,8 @@ feature_categories:
|
|||
description: Geo event for when a repository gets deleted, belongs to geo_event_log.
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/04c3da24ac5975b140cf2e6a7e33414543f148f5
|
||||
milestone: '9.4'
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/151938
|
||||
removed_in_milestone: '17.0'
|
||||
gitlab_schema: gitlab_main_cell
|
||||
allow_cross_joins:
|
||||
- gitlab_main_clusterwide
|
||||
|
|
@ -7,6 +7,8 @@ feature_categories:
|
|||
description: Geo event for when a repository gets renamed, belongs to geo_event_log.
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/6e5fa040d1c689fad4e110dd10be8ddba61ea7ef
|
||||
milestone: '9.4'
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/151938
|
||||
removed_in_milestone: '17.0'
|
||||
gitlab_schema: gitlab_main_cell
|
||||
allow_cross_joins:
|
||||
- gitlab_main_clusterwide
|
||||
|
|
@ -8,6 +8,8 @@ description: Geo event for when a repository gets updated (content changed), bel
|
|||
to geo_event_log.
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/71cc57b1e4b7721c93107357517235a18f7ba8e2
|
||||
milestone: '9.3'
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/151938
|
||||
removed_in_milestone: '17.0'
|
||||
gitlab_schema: gitlab_main_cell
|
||||
allow_cross_joins:
|
||||
- gitlab_main_clusterwide
|
||||
|
|
@ -8,6 +8,8 @@ description: Geo event for when a project gets reverified on the primary, belong
|
|||
to geo_event_log.
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/7394
|
||||
milestone: '11.4'
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/151938
|
||||
removed_in_milestone: '17.0'
|
||||
gitlab_schema: gitlab_main_cell
|
||||
allow_cross_joins:
|
||||
- gitlab_main_clusterwide
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RemoveForeignKeyGeoHashedStorageMigratedEvents < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.0'
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
FROM_TABLE = :geo_hashed_storage_migrated_events
|
||||
TO_TABLE = :projects
|
||||
|
||||
def up
|
||||
with_lock_retries do
|
||||
remove_foreign_key(
|
||||
FROM_TABLE,
|
||||
TO_TABLE,
|
||||
column: :project_id,
|
||||
if_exists: true
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
add_concurrent_foreign_key(
|
||||
FROM_TABLE,
|
||||
TO_TABLE,
|
||||
name: :fk_rails_687ed7d7c5,
|
||||
column: :project_id,
|
||||
on_delete: :cascade
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class DropTableGeoHashedStorageMigratedEvents < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.0'
|
||||
|
||||
def up
|
||||
drop_table :geo_hashed_storage_migrated_events
|
||||
end
|
||||
|
||||
def down
|
||||
create_table :geo_hashed_storage_migrated_events do |t|
|
||||
t.integer :project_id, index: { name: 'index_geo_hashed_storage_migrated_events_on_project_id' }, null: false
|
||||
t.text :repository_storage_name, null: false
|
||||
t.text :old_disk_path, null: false
|
||||
t.text :new_disk_path, null: false
|
||||
t.text :old_wiki_disk_path, null: false
|
||||
t.text :new_wiki_disk_path, null: false
|
||||
t.integer :old_storage_version, limit: 2
|
||||
t.integer :new_storage_version, limit: 2, null: false
|
||||
t.text :old_design_disk_path
|
||||
t.text :new_design_disk_path
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RemoveForeignKeyGeoHashedStorageAttachmentsEvents < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.0'
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
FROM_TABLE = :geo_hashed_storage_attachments_events
|
||||
TO_TABLE = :projects
|
||||
|
||||
def up
|
||||
with_lock_retries do
|
||||
remove_foreign_key(
|
||||
FROM_TABLE,
|
||||
TO_TABLE,
|
||||
column: :project_id,
|
||||
if_exists: true
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
add_concurrent_foreign_key(
|
||||
FROM_TABLE,
|
||||
TO_TABLE,
|
||||
name: :fk_rails_d496b088e9,
|
||||
column: :project_id,
|
||||
on_delete: :cascade
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class DropTableGeoHashedStorageAttachementsEvents < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.0'
|
||||
|
||||
def up
|
||||
drop_table :geo_hashed_storage_attachments_events
|
||||
end
|
||||
|
||||
def down
|
||||
create_table :geo_hashed_storage_attachments_events do |t|
|
||||
t.integer :project_id, index: { name: 'index_geo_hashed_storage_attachments_events_on_project_id' }, null: false
|
||||
t.text :old_attachments_path, null: false
|
||||
t.text :new_attachments_path, null: false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RemoveForeignKeyGeoRepositoryUpdatedEvents < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.0'
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
FROM_TABLE = :geo_repository_updated_events
|
||||
TO_TABLE = :projects
|
||||
|
||||
def up
|
||||
with_lock_retries do
|
||||
remove_foreign_key(
|
||||
FROM_TABLE,
|
||||
TO_TABLE,
|
||||
column: :project_id,
|
||||
if_exists: true
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
add_concurrent_foreign_key(
|
||||
FROM_TABLE,
|
||||
TO_TABLE,
|
||||
name: :fk_rails_2b70854c08,
|
||||
column: :project_id,
|
||||
on_delete: :cascade
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class DropTableGeoRepositoryUpdatedEvents < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.0'
|
||||
|
||||
def up
|
||||
drop_table :geo_repository_updated_events
|
||||
end
|
||||
|
||||
def down
|
||||
create_table :geo_repository_updated_events do |t|
|
||||
t.integer :branches_affected, null: false
|
||||
t.integer :tags_affected, null: false
|
||||
t.integer :project_id, index: { name: 'index_geo_repository_updated_events_on_project_id' }, null: false
|
||||
t.integer :source, limit: 2, index: { name: 'index_geo_repository_updated_events_on_source' }, null: false
|
||||
t.boolean :new_branch, default: false, null: false
|
||||
t.boolean :remove_branch, default: false, null: false
|
||||
t.text :ref
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RemoveForeignKeyGeoRepositoryRenamedEvents < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.0'
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
FROM_TABLE = :geo_repository_renamed_events
|
||||
TO_TABLE = :projects
|
||||
|
||||
def up
|
||||
with_lock_retries do
|
||||
remove_foreign_key(
|
||||
FROM_TABLE,
|
||||
TO_TABLE,
|
||||
column: :project_id,
|
||||
if_exists: true
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
add_concurrent_foreign_key(
|
||||
FROM_TABLE,
|
||||
TO_TABLE,
|
||||
name: :fk_rails_4e6524febb,
|
||||
column: :project_id,
|
||||
on_delete: :cascade
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class DropTableGeoRepositoryRenamedEvents < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.0'
|
||||
|
||||
def up
|
||||
drop_table :geo_repository_renamed_events
|
||||
end
|
||||
|
||||
def down
|
||||
create_table :geo_repository_renamed_events do |t|
|
||||
t.integer :project_id, index: { name: 'index_geo_repository_renamed_events_on_project_id' }, null: false
|
||||
t.text :repository_storage_name, null: false
|
||||
t.text :old_path_with_namespace, null: false
|
||||
t.text :new_path_with_namespace, null: false
|
||||
t.text :old_wiki_path_with_namespace, null: false
|
||||
t.text :new_wiki_path_with_namespace, null: false
|
||||
t.text :old_path, null: false
|
||||
t.text :new_path, null: false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RemoveForeignKeyGeoRepositoryCreatedEvents < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.0'
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
FROM_TABLE = :geo_repository_created_events
|
||||
TO_TABLE = :projects
|
||||
|
||||
def up
|
||||
with_lock_retries do
|
||||
remove_foreign_key(
|
||||
FROM_TABLE,
|
||||
TO_TABLE,
|
||||
column: :project_id,
|
||||
if_exists: true
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
add_concurrent_foreign_key(
|
||||
FROM_TABLE,
|
||||
TO_TABLE,
|
||||
name: :fk_rails_1f49e46a61,
|
||||
column: :project_id,
|
||||
on_delete: :cascade
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class DropTableGeoRepositoryCreatedEvents < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.0'
|
||||
|
||||
def up
|
||||
drop_table :geo_repository_created_events
|
||||
end
|
||||
|
||||
def down
|
||||
create_table :geo_repository_created_events do |t|
|
||||
t.integer :project_id, index: { name: 'index_geo_repository_created_events_on_project_id' }, null: false
|
||||
t.text :repository_storage_name, null: false
|
||||
t.text :repo_path, null: false
|
||||
t.text :wiki_path
|
||||
t.text :project_name, null: false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class DropTableGeoRepositoryDeletedEvents < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.0'
|
||||
|
||||
def up
|
||||
drop_table :geo_repository_deleted_events
|
||||
end
|
||||
|
||||
def down
|
||||
create_table :geo_repository_deleted_events do |t|
|
||||
t.integer :project_id, index: { name: 'index_geo_repository_deleted_events_on_project_id' }, null: false
|
||||
t.text :repository_storage_name, null: false
|
||||
t.text :deleted_path, null: false
|
||||
t.text :deleted_wiki_path
|
||||
t.text :deleted_project_name, null: false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RemoveForeignKeyGeoResetChecksumEvents < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.0'
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
FROM_TABLE = :geo_reset_checksum_events
|
||||
TO_TABLE = :projects
|
||||
|
||||
def up
|
||||
with_lock_retries do
|
||||
remove_foreign_key(
|
||||
FROM_TABLE,
|
||||
TO_TABLE,
|
||||
column: :project_id,
|
||||
if_exists: true
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
add_concurrent_foreign_key(
|
||||
FROM_TABLE,
|
||||
TO_TABLE,
|
||||
name: :fk_rails_910a06f12b,
|
||||
column: :project_id,
|
||||
on_delete: :cascade
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class DropTableGeoResetChecksumEvents < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.0'
|
||||
|
||||
def up
|
||||
drop_table :geo_reset_checksum_events
|
||||
end
|
||||
|
||||
def down
|
||||
create_table :geo_reset_checksum_events do |t|
|
||||
t.integer :project_id, index: { name: 'index_geo_reset_checksum_events_on_project_id' }, null: false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddIndexMembersOnLowerInviteEmail < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.0'
|
||||
|
||||
INDEX_NAME = 'index_members_on_lower_invite_email'
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
add_concurrent_index :members, '(lower(invite_email))', name: INDEX_NAME
|
||||
end
|
||||
|
||||
def down
|
||||
remove_concurrent_index_by_name :members, INDEX_NAME
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
58549bf920eb048c92b8faeeb1c09aabb99bfc6000366eef283bc3f04d15a1a4
|
||||
|
|
@ -0,0 +1 @@
|
|||
d3e1f2dfccc5d329d677a2163d5a44df5c5bd575ee8c2ae678609de6d5eef942
|
||||
|
|
@ -0,0 +1 @@
|
|||
7674c725ec40ca8f35f3fa34d2c0004d93e60d082143c7d95648d727ba1c1633
|
||||
|
|
@ -0,0 +1 @@
|
|||
4438ab576df6ec912cf25576c52a096a0a625e8b5aee5a087f5d7db59504d164
|
||||
|
|
@ -0,0 +1 @@
|
|||
9aa10a6889d0d25a080895406fd4a1d0182fe0ce258b435970fc48cfc3cd98cb
|
||||
|
|
@ -0,0 +1 @@
|
|||
60e54814c34eaff5a4a002152be76b9c5fad5db0058d2fd1eb1ce8f80bcbac68
|
||||
|
|
@ -0,0 +1 @@
|
|||
e8da0d1411165e4c37380cf6f5b3f1e6814889b4c5c7236235ea40ef198cafda
|
||||
|
|
@ -0,0 +1 @@
|
|||
312533b34332d08f8bbf10430224996a7a33e16303b5352f4347943133349123
|
||||
|
|
@ -0,0 +1 @@
|
|||
ca5f6d8e698550c3f3711cbcc2b52f4c17236ad065bf2b4abb703e9fff658770
|
||||
|
|
@ -0,0 +1 @@
|
|||
d07a24c6ebe58b72d8d2dc95e9f4f00347ff35add81ad13bec8c40497f599f8b
|
||||
|
|
@ -0,0 +1 @@
|
|||
824e428c16fde2be4c72dd1d426ec3dc1e8e10f6c72018df26a7eea6ab6eb26c
|
||||
|
|
@ -0,0 +1 @@
|
|||
dabe889047ccac9b5b354f83bd8f910936aca26a968fe79fb1cdcab0fd618dd2
|
||||
|
|
@ -0,0 +1 @@
|
|||
aafee50b23b182e7f8674086accdb7239e31c709bcc810d7a5fd88f455ea758b
|
||||
|
|
@ -0,0 +1 @@
|
|||
2879df8b5e17741acdafa450706f7d93901e183c96a148136b9bc39d1d8a6833
|
||||
201
db/structure.sql
201
db/structure.sql
|
|
@ -9249,45 +9249,6 @@ CREATE SEQUENCE geo_events_id_seq
|
|||
|
||||
ALTER SEQUENCE geo_events_id_seq OWNED BY geo_events.id;
|
||||
|
||||
CREATE TABLE geo_hashed_storage_attachments_events (
|
||||
id bigint NOT NULL,
|
||||
project_id integer NOT NULL,
|
||||
old_attachments_path text NOT NULL,
|
||||
new_attachments_path text NOT NULL
|
||||
);
|
||||
|
||||
CREATE SEQUENCE geo_hashed_storage_attachments_events_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
ALTER SEQUENCE geo_hashed_storage_attachments_events_id_seq OWNED BY geo_hashed_storage_attachments_events.id;
|
||||
|
||||
CREATE TABLE geo_hashed_storage_migrated_events (
|
||||
id bigint NOT NULL,
|
||||
project_id integer NOT NULL,
|
||||
repository_storage_name text NOT NULL,
|
||||
old_disk_path text NOT NULL,
|
||||
new_disk_path text NOT NULL,
|
||||
old_wiki_disk_path text NOT NULL,
|
||||
new_wiki_disk_path text NOT NULL,
|
||||
old_storage_version smallint,
|
||||
new_storage_version smallint NOT NULL,
|
||||
old_design_disk_path text,
|
||||
new_design_disk_path text
|
||||
);
|
||||
|
||||
CREATE SEQUENCE geo_hashed_storage_migrated_events_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
ALTER SEQUENCE geo_hashed_storage_migrated_events_id_seq OWNED BY geo_hashed_storage_migrated_events.id;
|
||||
|
||||
CREATE TABLE geo_node_namespace_links (
|
||||
id integer NOT NULL,
|
||||
geo_node_id integer NOT NULL,
|
||||
|
|
@ -9383,97 +9344,6 @@ CREATE SEQUENCE geo_repositories_changed_events_id_seq
|
|||
|
||||
ALTER SEQUENCE geo_repositories_changed_events_id_seq OWNED BY geo_repositories_changed_events.id;
|
||||
|
||||
CREATE TABLE geo_repository_created_events (
|
||||
id bigint NOT NULL,
|
||||
project_id integer NOT NULL,
|
||||
repository_storage_name text NOT NULL,
|
||||
repo_path text NOT NULL,
|
||||
wiki_path text,
|
||||
project_name text NOT NULL
|
||||
);
|
||||
|
||||
CREATE SEQUENCE geo_repository_created_events_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
ALTER SEQUENCE geo_repository_created_events_id_seq OWNED BY geo_repository_created_events.id;
|
||||
|
||||
CREATE TABLE geo_repository_deleted_events (
|
||||
id bigint NOT NULL,
|
||||
project_id integer NOT NULL,
|
||||
repository_storage_name text NOT NULL,
|
||||
deleted_path text NOT NULL,
|
||||
deleted_wiki_path text,
|
||||
deleted_project_name text NOT NULL
|
||||
);
|
||||
|
||||
CREATE SEQUENCE geo_repository_deleted_events_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
ALTER SEQUENCE geo_repository_deleted_events_id_seq OWNED BY geo_repository_deleted_events.id;
|
||||
|
||||
CREATE TABLE geo_repository_renamed_events (
|
||||
id bigint NOT NULL,
|
||||
project_id integer NOT NULL,
|
||||
repository_storage_name text NOT NULL,
|
||||
old_path_with_namespace text NOT NULL,
|
||||
new_path_with_namespace text NOT NULL,
|
||||
old_wiki_path_with_namespace text NOT NULL,
|
||||
new_wiki_path_with_namespace text NOT NULL,
|
||||
old_path text NOT NULL,
|
||||
new_path text NOT NULL
|
||||
);
|
||||
|
||||
CREATE SEQUENCE geo_repository_renamed_events_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
ALTER SEQUENCE geo_repository_renamed_events_id_seq OWNED BY geo_repository_renamed_events.id;
|
||||
|
||||
CREATE TABLE geo_repository_updated_events (
|
||||
id bigint NOT NULL,
|
||||
branches_affected integer NOT NULL,
|
||||
tags_affected integer NOT NULL,
|
||||
project_id integer NOT NULL,
|
||||
source smallint NOT NULL,
|
||||
new_branch boolean DEFAULT false NOT NULL,
|
||||
remove_branch boolean DEFAULT false NOT NULL,
|
||||
ref text
|
||||
);
|
||||
|
||||
CREATE SEQUENCE geo_repository_updated_events_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
ALTER SEQUENCE geo_repository_updated_events_id_seq OWNED BY geo_repository_updated_events.id;
|
||||
|
||||
CREATE TABLE geo_reset_checksum_events (
|
||||
id bigint NOT NULL,
|
||||
project_id integer NOT NULL
|
||||
);
|
||||
|
||||
CREATE SEQUENCE geo_reset_checksum_events_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
ALTER SEQUENCE geo_reset_checksum_events_id_seq OWNED BY geo_reset_checksum_events.id;
|
||||
|
||||
CREATE TABLE ghost_user_migrations (
|
||||
id bigint NOT NULL,
|
||||
user_id bigint NOT NULL,
|
||||
|
|
@ -19400,10 +19270,6 @@ ALTER TABLE ONLY geo_event_log ALTER COLUMN id SET DEFAULT nextval('geo_event_lo
|
|||
|
||||
ALTER TABLE ONLY geo_events ALTER COLUMN id SET DEFAULT nextval('geo_events_id_seq'::regclass);
|
||||
|
||||
ALTER TABLE ONLY geo_hashed_storage_attachments_events ALTER COLUMN id SET DEFAULT nextval('geo_hashed_storage_attachments_events_id_seq'::regclass);
|
||||
|
||||
ALTER TABLE ONLY geo_hashed_storage_migrated_events ALTER COLUMN id SET DEFAULT nextval('geo_hashed_storage_migrated_events_id_seq'::regclass);
|
||||
|
||||
ALTER TABLE ONLY geo_node_namespace_links ALTER COLUMN id SET DEFAULT nextval('geo_node_namespace_links_id_seq'::regclass);
|
||||
|
||||
ALTER TABLE ONLY geo_node_statuses ALTER COLUMN id SET DEFAULT nextval('geo_node_statuses_id_seq'::regclass);
|
||||
|
|
@ -19412,16 +19278,6 @@ ALTER TABLE ONLY geo_nodes ALTER COLUMN id SET DEFAULT nextval('geo_nodes_id_seq
|
|||
|
||||
ALTER TABLE ONLY geo_repositories_changed_events ALTER COLUMN id SET DEFAULT nextval('geo_repositories_changed_events_id_seq'::regclass);
|
||||
|
||||
ALTER TABLE ONLY geo_repository_created_events ALTER COLUMN id SET DEFAULT nextval('geo_repository_created_events_id_seq'::regclass);
|
||||
|
||||
ALTER TABLE ONLY geo_repository_deleted_events ALTER COLUMN id SET DEFAULT nextval('geo_repository_deleted_events_id_seq'::regclass);
|
||||
|
||||
ALTER TABLE ONLY geo_repository_renamed_events ALTER COLUMN id SET DEFAULT nextval('geo_repository_renamed_events_id_seq'::regclass);
|
||||
|
||||
ALTER TABLE ONLY geo_repository_updated_events ALTER COLUMN id SET DEFAULT nextval('geo_repository_updated_events_id_seq'::regclass);
|
||||
|
||||
ALTER TABLE ONLY geo_reset_checksum_events ALTER COLUMN id SET DEFAULT nextval('geo_reset_checksum_events_id_seq'::regclass);
|
||||
|
||||
ALTER TABLE ONLY ghost_user_migrations ALTER COLUMN id SET DEFAULT nextval('ghost_user_migrations_id_seq'::regclass);
|
||||
|
||||
ALTER TABLE ONLY gitlab_subscription_histories ALTER COLUMN id SET DEFAULT nextval('gitlab_subscription_histories_id_seq'::regclass);
|
||||
|
|
@ -21519,12 +21375,6 @@ ALTER TABLE ONLY geo_event_log
|
|||
ALTER TABLE ONLY geo_events
|
||||
ADD CONSTRAINT geo_events_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY geo_hashed_storage_attachments_events
|
||||
ADD CONSTRAINT geo_hashed_storage_attachments_events_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY geo_hashed_storage_migrated_events
|
||||
ADD CONSTRAINT geo_hashed_storage_migrated_events_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY geo_node_namespace_links
|
||||
ADD CONSTRAINT geo_node_namespace_links_pkey PRIMARY KEY (id);
|
||||
|
||||
|
|
@ -21537,21 +21387,6 @@ ALTER TABLE ONLY geo_nodes
|
|||
ALTER TABLE ONLY geo_repositories_changed_events
|
||||
ADD CONSTRAINT geo_repositories_changed_events_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY geo_repository_created_events
|
||||
ADD CONSTRAINT geo_repository_created_events_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY geo_repository_deleted_events
|
||||
ADD CONSTRAINT geo_repository_deleted_events_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY geo_repository_renamed_events
|
||||
ADD CONSTRAINT geo_repository_renamed_events_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY geo_repository_updated_events
|
||||
ADD CONSTRAINT geo_repository_updated_events_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY geo_reset_checksum_events
|
||||
ADD CONSTRAINT geo_reset_checksum_events_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY ghost_user_migrations
|
||||
ADD CONSTRAINT ghost_user_migrations_pkey PRIMARY KEY (id);
|
||||
|
||||
|
|
@ -25681,10 +25516,6 @@ CREATE INDEX index_geo_event_log_on_geo_event_id ON geo_event_log USING btree (g
|
|||
|
||||
CREATE INDEX index_geo_event_log_on_repositories_changed_event_id ON geo_event_log USING btree (repositories_changed_event_id) WHERE (repositories_changed_event_id IS NOT NULL);
|
||||
|
||||
CREATE INDEX index_geo_hashed_storage_attachments_events_on_project_id ON geo_hashed_storage_attachments_events USING btree (project_id);
|
||||
|
||||
CREATE INDEX index_geo_hashed_storage_migrated_events_on_project_id ON geo_hashed_storage_migrated_events USING btree (project_id);
|
||||
|
||||
CREATE INDEX index_geo_node_namespace_links_on_geo_node_id ON geo_node_namespace_links USING btree (geo_node_id);
|
||||
|
||||
CREATE UNIQUE INDEX index_geo_node_namespace_links_on_geo_node_id_and_namespace_id ON geo_node_namespace_links USING btree (geo_node_id, namespace_id);
|
||||
|
|
@ -25701,18 +25532,6 @@ CREATE INDEX index_geo_nodes_on_primary ON geo_nodes USING btree ("primary");
|
|||
|
||||
CREATE INDEX index_geo_repositories_changed_events_on_geo_node_id ON geo_repositories_changed_events USING btree (geo_node_id);
|
||||
|
||||
CREATE INDEX index_geo_repository_created_events_on_project_id ON geo_repository_created_events USING btree (project_id);
|
||||
|
||||
CREATE INDEX index_geo_repository_deleted_events_on_project_id ON geo_repository_deleted_events USING btree (project_id);
|
||||
|
||||
CREATE INDEX index_geo_repository_renamed_events_on_project_id ON geo_repository_renamed_events USING btree (project_id);
|
||||
|
||||
CREATE INDEX index_geo_repository_updated_events_on_project_id ON geo_repository_updated_events USING btree (project_id);
|
||||
|
||||
CREATE INDEX index_geo_repository_updated_events_on_source ON geo_repository_updated_events USING btree (source);
|
||||
|
||||
CREATE INDEX index_geo_reset_checksum_events_on_project_id ON geo_reset_checksum_events USING btree (project_id);
|
||||
|
||||
CREATE INDEX index_ghost_user_migrations_on_consume_after_id ON ghost_user_migrations USING btree (consume_after, id);
|
||||
|
||||
CREATE UNIQUE INDEX index_ghost_user_migrations_on_user_id ON ghost_user_migrations USING btree (user_id);
|
||||
|
|
@ -26183,6 +26002,8 @@ CREATE INDEX index_members_on_invite_email ON members USING btree (invite_email)
|
|||
|
||||
CREATE UNIQUE INDEX index_members_on_invite_token ON members USING btree (invite_token);
|
||||
|
||||
CREATE INDEX index_members_on_lower_invite_email ON members USING btree (lower((invite_email)::text));
|
||||
|
||||
CREATE INDEX index_members_on_member_namespace_id_compound ON members USING btree (member_namespace_id, type, requested_at, id);
|
||||
|
||||
CREATE INDEX index_members_on_member_role_id ON members USING btree (member_role_id);
|
||||
|
|
@ -31439,9 +31260,6 @@ ALTER TABLE ONLY packages_tags
|
|||
ALTER TABLE ONLY boards_epic_board_positions
|
||||
ADD CONSTRAINT fk_rails_1ecfd9f2de FOREIGN KEY (epic_id) REFERENCES epics(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY geo_repository_created_events
|
||||
ADD CONSTRAINT fk_rails_1f49e46a61 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY external_status_checks
|
||||
ADD CONSTRAINT fk_rails_1f5a8aa809 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
|
||||
|
||||
|
|
@ -31538,9 +31356,6 @@ ALTER TABLE ONLY dependency_proxy_image_ttl_group_policies
|
|||
ALTER TABLE ONLY group_group_links
|
||||
ADD CONSTRAINT fk_rails_2b2353ca49 FOREIGN KEY (shared_with_group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY geo_repository_updated_events
|
||||
ADD CONSTRAINT fk_rails_2b70854c08 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY packages_debian_group_component_files
|
||||
ADD CONSTRAINT fk_rails_2b8992dd83 FOREIGN KEY (architecture_id) REFERENCES packages_debian_group_architectures(id) ON DELETE RESTRICT;
|
||||
|
||||
|
|
@ -31772,9 +31587,6 @@ ALTER TABLE ONLY snippet_user_mentions
|
|||
ALTER TABLE ONLY protected_environment_approval_rules
|
||||
ADD CONSTRAINT fk_rails_4e554f96f5 FOREIGN KEY (protected_environment_id) REFERENCES protected_environments(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY geo_repository_renamed_events
|
||||
ADD CONSTRAINT fk_rails_4e6524febb FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY aws_roles
|
||||
ADD CONSTRAINT fk_rails_4ed56f4720 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||||
|
||||
|
|
@ -31994,9 +31806,6 @@ ALTER TABLE ONLY vulnerability_findings_remediations
|
|||
ALTER TABLE ONLY resource_iteration_events
|
||||
ADD CONSTRAINT fk_rails_6830c13ac1 FOREIGN KEY (merge_request_id) REFERENCES merge_requests(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY geo_hashed_storage_migrated_events
|
||||
ADD CONSTRAINT fk_rails_687ed7d7c5 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY plan_limits
|
||||
ADD CONSTRAINT fk_rails_69f8b6184f FOREIGN KEY (plan_id) REFERENCES plans(id) ON DELETE CASCADE;
|
||||
|
||||
|
|
@ -32282,9 +32091,6 @@ ALTER TABLE ONLY approval_project_rules_groups
|
|||
ALTER TABLE ONLY vulnerability_occurrences
|
||||
ADD CONSTRAINT fk_rails_90fed4faba FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY geo_reset_checksum_events
|
||||
ADD CONSTRAINT fk_rails_910a06f12b FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY project_error_tracking_settings
|
||||
ADD CONSTRAINT fk_rails_910a2b8bd9 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
|
||||
|
||||
|
|
@ -32771,9 +32577,6 @@ ALTER TABLE ONLY alert_management_alert_assignees
|
|||
ALTER TABLE ONLY packages_terraform_module_metadata
|
||||
ADD CONSTRAINT fk_rails_d48f21a84b FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE SET NULL;
|
||||
|
||||
ALTER TABLE ONLY geo_hashed_storage_attachments_events
|
||||
ADD CONSTRAINT fk_rails_d496b088e9 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE p_ci_job_annotations
|
||||
ADD CONSTRAINT fk_rails_d4d0c0fa0f FOREIGN KEY (partition_id, job_id) REFERENCES p_ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
|
||||
|
|
|
|||
|
|
@ -7599,6 +7599,24 @@ Input type: `RepositionImageDiffNoteInput`
|
|||
| <a id="mutationrepositionimagediffnoteerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
|
||||
| <a id="mutationrepositionimagediffnotenote"></a>`note` | [`Note`](#note) | Note after mutation. |
|
||||
|
||||
### `Mutation.runnerCacheClear`
|
||||
|
||||
Input type: `RunnerCacheClearInput`
|
||||
|
||||
#### Arguments
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="mutationrunnercacheclearclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
|
||||
| <a id="mutationrunnercacheclearprojectid"></a>`projectId` | [`ProjectID!`](#projectid) | Global ID of the project that will have its runner cache cleared. |
|
||||
|
||||
#### Fields
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="mutationrunnercacheclearclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
|
||||
| <a id="mutationrunnercacheclearerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
|
||||
|
||||
### `Mutation.runnerCreate`
|
||||
|
||||
DETAILS:
|
||||
|
|
@ -22263,6 +22281,8 @@ Returns [`WorkItemStateCountsType`](#workitemstatecountstype).
|
|||
| <a id="groupworkitemstatecountsiid"></a>`iid` | [`String`](#string) | IID of the work item. For example, "1". |
|
||||
| <a id="groupworkitemstatecountsiids"></a>`iids` | [`[String!]`](#string) | List of IIDs of work items. For example, `["1", "2"]`. |
|
||||
| <a id="groupworkitemstatecountsin"></a>`in` | [`[IssuableSearchableField!]`](#issuablesearchablefield) | Specify the fields to perform the search in. Defaults to `[TITLE, DESCRIPTION]`. Requires the `search` argument.'. |
|
||||
| <a id="groupworkitemstatecountsincludeancestors"></a>`includeAncestors` | [`Boolean`](#boolean) | Include work items from ancestor groups. |
|
||||
| <a id="groupworkitemstatecountsincludedescendants"></a>`includeDescendants` | [`Boolean`](#boolean) | Include work items from descendant groups and projects. |
|
||||
| <a id="groupworkitemstatecountsrequirementlegacywidget"></a>`requirementLegacyWidget` **{warning-solid}** | [`RequirementLegacyFilterInput`](#requirementlegacyfilterinput) | **Deprecated** in GitLab 15.9. Use work item IID filter instead. |
|
||||
| <a id="groupworkitemstatecountssearch"></a>`search` | [`String`](#string) | Search query for title or description. |
|
||||
| <a id="groupworkitemstatecountssort"></a>`sort` | [`WorkItemSort`](#workitemsort) | Sort work items by criteria. |
|
||||
|
|
@ -22308,6 +22328,8 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="groupworkitemsiid"></a>`iid` | [`String`](#string) | IID of the work item. For example, "1". |
|
||||
| <a id="groupworkitemsiids"></a>`iids` | [`[String!]`](#string) | List of IIDs of work items. For example, `["1", "2"]`. |
|
||||
| <a id="groupworkitemsin"></a>`in` | [`[IssuableSearchableField!]`](#issuablesearchablefield) | Specify the fields to perform the search in. Defaults to `[TITLE, DESCRIPTION]`. Requires the `search` argument.'. |
|
||||
| <a id="groupworkitemsincludeancestors"></a>`includeAncestors` | [`Boolean`](#boolean) | Include work items from ancestor groups. |
|
||||
| <a id="groupworkitemsincludedescendants"></a>`includeDescendants` | [`Boolean`](#boolean) | Include work items from descendant groups and projects. |
|
||||
| <a id="groupworkitemsrequirementlegacywidget"></a>`requirementLegacyWidget` **{warning-solid}** | [`RequirementLegacyFilterInput`](#requirementlegacyfilterinput) | **Deprecated** in GitLab 15.9. Use work item IID filter instead. |
|
||||
| <a id="groupworkitemssearch"></a>`search` | [`String`](#string) | Search query for title or description. |
|
||||
| <a id="groupworkitemssort"></a>`sort` | [`WorkItemSort`](#workitemsort) | Sort work items by criteria. |
|
||||
|
|
|
|||
|
|
@ -110,6 +110,26 @@ We've deprecated the use of `ref` and `sha` in API calls to `GET /projects/:id/c
|
|||
|
||||
<div class="deprecation breaking-change" data-milestone="18.0">
|
||||
|
||||
### Breaking change to the Maven repository group permissions
|
||||
|
||||
<div class="deprecation-notes">
|
||||
- Announced in GitLab <span class="milestone">16.6</span>
|
||||
- Removal in GitLab <span class="milestone">18.0</span> ([breaking change](https://docs.gitlab.com/ee/update/terminology.html#breaking-change))
|
||||
- To discuss this change or learn more, see the [deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/393933).
|
||||
</div>
|
||||
|
||||
The Maven repository exposes an API endpoint at the group level that allows Maven clients to download files from a specific package. The package finder first locates the package within the group, and then finds the file within the package.
|
||||
However, there is a limitation that affects duplicate package names hosted in different projects. The Maven package finder always returns the most recent package, but the "most recent" filter depends on user permissions. It is possible for a user with different permissions in different projects to download the wrong Maven package.
|
||||
|
||||
In GitLab 18.0, the package finder logic will be fixed so that the "most recent" package is the last updated name and version of a package in a group. User permissions will be checked after the most recent package is found.
|
||||
After the change, download requests for users without correct permissions will be rejected. If your workflow depends on the current bugged behavior, this fix will introduce a breaking change.
|
||||
|
||||
The change will be introduced in GitLab 16.6 behind a feature flag. If you are interested in enabling the feature flag for your group, leave a comment in [issue 393933](https://gitlab.com/gitlab-org/gitlab/-/issues/393933).
|
||||
|
||||
</div>
|
||||
|
||||
<div class="deprecation breaking-change" data-milestone="18.0">
|
||||
|
||||
### Default CI/CD job token (`CI_JOB_TOKEN`) scope changed
|
||||
|
||||
<div class="deprecation-notes">
|
||||
|
|
@ -134,6 +154,24 @@ In 16.3, the names of these settings were changed to clarify their meanings: the
|
|||
|
||||
<div class="deprecation breaking-change" data-milestone="18.0">
|
||||
|
||||
### Dependency Proxy: Access tokens to have additional scope checks
|
||||
|
||||
<div class="deprecation-notes">
|
||||
- Announced in GitLab <span class="milestone">16.7</span>
|
||||
- Removal in GitLab <span class="milestone">18.0</span> ([breaking change](https://docs.gitlab.com/ee/update/terminology.html#breaking-change))
|
||||
- To discuss this change or learn more, see the [deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/431386).
|
||||
</div>
|
||||
|
||||
When using the Dependency Proxy for containers with a group access token or personal access token, `docker login` and `docker pull` requests with insufficient scopes for Dependency Proxy are not rejected.
|
||||
|
||||
GitLab 18.0 adds checks for group or personal access tokens authenticating with the dependency proxy for containers. This is a breaking change, because tokens without the required scopes will fail.
|
||||
|
||||
To help avoid being impacted by this breaking change, create new access tokens with the [required scopes](https://docs.gitlab.com/ee/user/packages/dependency_proxy/#authenticate-with-the-dependency-proxy), and update your workflow variables and scripts with those new tokens.
|
||||
|
||||
</div>
|
||||
|
||||
<div class="deprecation breaking-change" data-milestone="18.0">
|
||||
|
||||
### Deprecate License Scanning CI/CD artifact report type
|
||||
|
||||
<div class="deprecation-notes">
|
||||
|
|
@ -708,26 +746,6 @@ can change `## Step - 1` to `## Step 1` to ensure in-page links continue to work
|
|||
|
||||
<div class="deprecation breaking-change" data-milestone="17.0">
|
||||
|
||||
### Breaking change to the Maven repository group permissions
|
||||
|
||||
<div class="deprecation-notes">
|
||||
- Announced in GitLab <span class="milestone">16.6</span>
|
||||
- Removal in GitLab <span class="milestone">17.0</span> ([breaking change](https://docs.gitlab.com/ee/update/terminology.html#breaking-change))
|
||||
- To discuss this change or learn more, see the [deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/393933).
|
||||
</div>
|
||||
|
||||
The Maven repository exposes an API endpoint at the group level that allows Maven clients to download files from a specific package. The package finder first locates the package within the group, and then finds the file within the package.
|
||||
However, there is a limitation that affects duplicate package names hosted in different projects. The Maven package finder always returns the most recent package, but the "most recent" filter depends on user permissions. It is possible for a user with different permissions in different projects to download the wrong Maven package.
|
||||
|
||||
In GitLab 17.0, the package finder logic will be fixed so that the "most recent" package is the last updated name and version of a package in a group. User permissions will be checked after the most recent package is found.
|
||||
After the change, download requests for users without correct permissions will be rejected. If your workflow depends on the current bugged behavior, this fix will introduce a breaking change.
|
||||
|
||||
The change will be introduced in GitLab 16.6 behind a feature flag. If you are interested in enabling the feature flag for your group, leave a comment in [issue 393933](https://gitlab.com/gitlab-org/gitlab/-/issues/393933).
|
||||
|
||||
</div>
|
||||
|
||||
<div class="deprecation breaking-change" data-milestone="17.0">
|
||||
|
||||
### CiRunner.projects default sort is changing to `id_desc`
|
||||
|
||||
<div class="deprecation-notes">
|
||||
|
|
@ -794,24 +812,6 @@ These three variables will be removed in GitLab 17.0.
|
|||
|
||||
<div class="deprecation breaking-change" data-milestone="17.0">
|
||||
|
||||
### Dependency Proxy: Access tokens to have additional scope checks
|
||||
|
||||
<div class="deprecation-notes">
|
||||
- Announced in GitLab <span class="milestone">16.7</span>
|
||||
- Removal in GitLab <span class="milestone">17.0</span> ([breaking change](https://docs.gitlab.com/ee/update/terminology.html#breaking-change))
|
||||
- To discuss this change or learn more, see the [deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/431386).
|
||||
</div>
|
||||
|
||||
When using the Dependency Proxy for containers with a group access token or personal access token, `docker login` and `docker pull` requests with insufficient scopes for Dependency Proxy are not rejected.
|
||||
|
||||
GitLab 17.0 adds checks for group or personal access tokens authenticating with the dependency proxy for containers. This is a breaking change, because tokens without the required scopes will fail.
|
||||
|
||||
To help avoid being impacted by this breaking change, create new access tokens with the [required scopes](https://docs.gitlab.com/ee/user/packages/dependency_proxy/#authenticate-with-the-dependency-proxy), and update your workflow variables and scripts with those new tokens.
|
||||
|
||||
</div>
|
||||
|
||||
<div class="deprecation breaking-change" data-milestone="17.0">
|
||||
|
||||
### Dependency Scanning incorrect SBOM metadata properties
|
||||
|
||||
<div class="deprecation-notes">
|
||||
|
|
|
|||
|
|
@ -0,0 +1,176 @@
|
|||
---
|
||||
stage: AI-powered
|
||||
group: AI Model Validation
|
||||
description: AI-powered features and functionality.
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# GitLab Duo Experiments
|
||||
|
||||
The following GitLab Duo features are in the
|
||||
[Experiment](../policy/experiment-beta-support.md#experiment) phase.
|
||||
|
||||
## Explain code in the Web UI with Code explanation
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Freely available for Premium and Ultimate for a limited time. In the future, will require Premium or Ultimate with [GitLab Duo Pro](../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com
|
||||
**Status:** Experiment
|
||||
|
||||
> - Introduced in GitLab 15.11 as an [Experiment](../policy/experiment-beta-support.md#experiment) on GitLab.com.
|
||||
|
||||
To use this feature:
|
||||
|
||||
- The parent group of the project must:
|
||||
- Enable the [experiment and beta features setting](group/manage.md#enable-experiment-and-beta-features).
|
||||
- You must:
|
||||
- Belong to at least one group with the [experiment and beta features setting](group/manage.md#enable-experiment-and-beta-features) enabled.
|
||||
- Have sufficient permissions to view the project.
|
||||
|
||||
GitLab can help you get up to speed faster if you:
|
||||
|
||||
- Spend a lot of time trying to understand pieces of code that others have created, or
|
||||
- Struggle to understand code written in a language that you are not familiar with.
|
||||
|
||||
By using a large language model, GitLab can explain the code in natural language.
|
||||
|
||||
To explain your code:
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your project.
|
||||
1. Select any file in your project that contains code.
|
||||
1. On the file, select the lines that you want to have explained.
|
||||
1. On the left side, select the question mark (**{question}**). You might have to scroll to the first line of your selection to view it. This sends the selected code, together with a prompt, to provide an explanation to the large language model.
|
||||
1. A drawer is displayed on the right side of the page. Wait a moment for the explanation to be generated.
|
||||
1. Provide feedback about how satisfied you are with the explanation, so we can improve the results.
|
||||
|
||||
You can also have code explained in the context of a merge request. To explain
|
||||
code in a merge request:
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your project.
|
||||
1. Select **Code > Merge requests**, then select your merge request.
|
||||
1. On the secondary menu, select **Changes**.
|
||||
1. On the file you would like explained, select the three dots (**{ellipsis_v}**) and select **View File @ $SHA**.
|
||||
|
||||
A separate browser tab opens and shows the full file with the latest changes.
|
||||
|
||||
1. On the new tab, select the lines that you want to have explained.
|
||||
1. On the left side, select the question mark (**{question}**). You might have to scroll to the first line of your selection to view it. This sends the selected code, together with a prompt, to provide an explanation to the large language model.
|
||||
1. A drawer is displayed on the right side of the page. Wait a moment for the explanation to be generated.
|
||||
1. Provide feedback about how satisfied you are with the explanation, so we can improve the results.
|
||||
|
||||

|
||||
|
||||
We cannot guarantee that the large language model produces results that are correct. Use the explanation with caution.
|
||||
|
||||
## Summarize issue discussions with Discussion summary
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Freely available for Ultimate for a limited time. In the future, will require Ultimate with [GitLab Duo Enterprise](../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com
|
||||
**Status:** Experiment
|
||||
|
||||
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/10344) in GitLab 16.0 as an [Experiment](../policy/experiment-beta-support.md#experiment).
|
||||
|
||||
To use this feature:
|
||||
|
||||
- The parent group of the issue must:
|
||||
- Enable the [experiment and beta features setting](group/manage.md#enable-experiment-and-beta-features).
|
||||
- You must:
|
||||
- Belong to at least one group with the [experiment and beta features setting](group/manage.md#enable-experiment-and-beta-features) enabled.
|
||||
- Have sufficient permissions to view the issue.
|
||||
|
||||
You can generate a summary of discussions on an issue:
|
||||
|
||||
1. In an issue, scroll to the **Activity** section.
|
||||
1. Select **View summary**.
|
||||
|
||||
The comments in the issue are summarized in as many as 10 list items.
|
||||
The summary is displayed only for you.
|
||||
|
||||
Provide feedback on this experimental feature in [issue 407779](https://gitlab.com/gitlab-org/gitlab/-/issues/407779).
|
||||
|
||||
**Data usage**: When you use this feature, the text of all comments on the issue are sent to the large
|
||||
language model referenced above.
|
||||
|
||||
## Forecast deployment frequency with Value stream forecasting
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Freely available for Ultimate for a limited time. In the future, will require Ultimate with [GitLab Duo Enterprise](../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
**Status:** Experiment
|
||||
|
||||
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/10228) in GitLab 16.2 as an [Experiment](../policy/experiment-beta-support.md#experiment).
|
||||
|
||||
To use this feature:
|
||||
|
||||
- The parent group of the project must:
|
||||
- Enable the [experiment and beta features setting](group/manage.md#enable-experiment-and-beta-features).
|
||||
- You must:
|
||||
- Belong to at least one group with the [experiment and beta features setting](group/manage.md#enable-experiment-and-beta-features) enabled.
|
||||
- Have sufficient permissions to view the CI/CD analytics.
|
||||
|
||||
In CI/CD Analytics, you can view a forecast of deployment frequency:
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your project.
|
||||
1. Select **Analyze > CI/CD analytics**.
|
||||
1. Select the **Deployment frequency** tab.
|
||||
1. Turn on the **Show forecast** toggle.
|
||||
1. On the confirmation dialog, select **Accept testing terms**.
|
||||
|
||||
The forecast is displayed as a dotted line on the chart. Data is forecasted for a duration that is half of the selected date range.
|
||||
For example, if you select a 30-day range, a forecast for the following 15 days is displayed.
|
||||
|
||||

|
||||
|
||||
Provide feedback on this experimental feature in [issue 416833](https://gitlab.com/gitlab-org/gitlab/-/issues/416833).
|
||||
|
||||
## Root cause analysis
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Freely available for Ultimate for a limited time. In the future, will require Ultimate with [GitLab Duo Enterprise](../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com
|
||||
**Status:** Experiment
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/123692) in GitLab 16.2 as an [Experiment](../policy/experiment-beta-support.md#experiment).
|
||||
|
||||
To use this feature:
|
||||
|
||||
- The parent group of the project must:
|
||||
- Enable the [experiment and beta features setting](group/manage.md#enable-experiment-and-beta-features).
|
||||
- You must:
|
||||
- Belong to at least one group with the [experiment and beta features setting](group/manage.md#enable-experiment-and-beta-features) enabled.
|
||||
- Have sufficient permissions to view the CI/CD job.
|
||||
|
||||
When the feature is available, the "Root cause analysis" button will appears on
|
||||
a failed CI/CD job. Selecting this button generates an analysis regarding the
|
||||
reason for the failure.
|
||||
|
||||
## Summarize an issue with Issue description generation
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Freely available for Ultimate for a limited time. In the future, will require Ultimate with [GitLab Duo Enterprise](../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com
|
||||
**Status:** Experiment
|
||||
|
||||
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/10762) in GitLab 16.3 as an [Experiment](../policy/experiment-beta-support.md#experiment).
|
||||
|
||||
To use this feature:
|
||||
|
||||
- The parent group of the project must:
|
||||
- Enable the [experiment and beta features setting](group/manage.md#enable-experiment-and-beta-features).
|
||||
- You must:
|
||||
- Belong to at least one group with the [experiment and beta features setting](group/manage.md#enable-experiment-and-beta-features) enabled.
|
||||
- Have sufficient permissions to view the issue.
|
||||
|
||||
You can generate the description for an issue from a short summary.
|
||||
|
||||
1. Create a new issue.
|
||||
1. Above the **Description** field, select **AI actions > Generate issue description**.
|
||||
1. Write a short description and select **Submit**.
|
||||
|
||||
The issue description is replaced with AI-generated text.
|
||||
|
||||
Provide feedback on this experimental feature in [issue 409844](https://gitlab.com/gitlab-org/gitlab/-/issues/409844).
|
||||
|
||||
**Data usage**: When you use this feature, the text you enter is sent to the large
|
||||
language model referenced above.
|
||||
|
|
@ -13,7 +13,9 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
GitLab Duo is a set of AI-assisted features across the GitLab DevSecOps platform. These features aim to help increase velocity and solve key pain points across the software development lifecycle. GitLab Duo features are accessible through the [IDE extension](../editor_extensions/index.md) and the GitLab UI. Some of the features are also accessible through [GitLab Duo Chat](gitlab_duo_chat.md), which is available in both interfaces.
|
||||
|
||||
Some features are still in development. View details about [support for each status](../policy/experiment-beta-support.md#experiment) (Experiment, Beta, Generally Available). Learn more about how to [enable GitLab Duo features](ai_features_enable.md).
|
||||
Some features are still in development. [View features in the Experiment phase](ai_experiments.md).
|
||||
|
||||
Learn more about how to [turn GitLab Duo features on and off](ai_features_enable.md).
|
||||
|
||||
GitLab is [transparent](https://handbook.gitlab.com/handbook/values/#transparency). As GitLab Duo features mature, the documentation will be updated to clearly state how and where you can access these capabilities.
|
||||
|
||||
|
|
@ -22,8 +24,8 @@ GitLab is [transparent](https://handbook.gitlab.com/handbook/values/#transparenc
|
|||
| Helps you write code more efficiently by showing code suggestions as you type.<br><br><i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [Watch overview](https://www.youtube.com/watch?v=hCAyCTacdAQ) | [Code Suggestions](project/repository/code_suggestions/index.md) | **Tier:** Premium and Ultimate with [GitLab Duo Pro](../subscriptions/subscription-add-ons.md)<br>**Offering:** GitLab.com, Self-managed, GitLab Dedicated <br>**Status:** Generally Available |
|
||||
| Processes and generates text and code in a conversational manner. Helps you quickly identify useful information in large volumes of text in issues, epics, code, and GitLab documentation. | [Chat](gitlab_duo_chat.md) | **Tier:** Freely available for Premium and Ultimate for a limited time<br>**Offering:** GitLab.com, Self-managed, GitLab Dedicated <br>**Status:** Generally Available |
|
||||
| Helps you discover or recall Git commands when and where you need them. | [Git suggestions](../editor_extensions/gitlab_cli/index.md#gitlab-duo-commands) | **Tier:** Freely available for Ultimate for a limited time<br>In the future, will require Ultimate with [GitLab Duo Enterprise](../subscriptions/subscription-add-ons.md)<br>**Offering:** GitLab.com<br>**Status:** Experiment |
|
||||
| Assists with quickly getting everyone up to speed on lengthy conversations to help ensure you are all on the same page. <br><br><i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [Watch overview](https://www.youtube.com/watch?v=IcdxLfTIUgc) | [Discussion summary](#summarize-issue-discussions-with-discussion-summary) | **Tier:** Freely available for Ultimate for a limited time<br>In the future, will require [GitLab Duo Enterprise](../subscriptions/subscription-add-ons.md)<br>**Offering:** GitLab.com <br>**Status:** Experiment |
|
||||
| Generates issue descriptions. | [Issue description generation](#summarize-an-issue-with-issue-description-generation) | **Tier:** Freely available for Ultimate for a limited time<br>In the future, will require Ultimate with [GitLab Duo Enterprise](../subscriptions/subscription-add-ons.md)<br>**Offering:** GitLab.com <br>**Status:** Experiment |
|
||||
| Assists with quickly getting everyone up to speed on lengthy conversations to help ensure you are all on the same page. <br><br><i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [Watch overview](https://www.youtube.com/watch?v=IcdxLfTIUgc) | [Discussion summary](ai_experiments.md#summarize-issue-discussions-with-discussion-summary) | **Tier:** Freely available for Ultimate for a limited time<br>In the future, will require [GitLab Duo Enterprise](../subscriptions/subscription-add-ons.md)<br>**Offering:** GitLab.com <br>**Status:** Experiment |
|
||||
| Generates issue descriptions. | [Issue description generation](ai_experiments.md#summarize-an-issue-with-issue-description-generation) | **Tier:** Freely available for Ultimate for a limited time<br>In the future, will require Ultimate with [GitLab Duo Enterprise](../subscriptions/subscription-add-ons.md)<br>**Offering:** GitLab.com <br>**Status:** Experiment |
|
||||
| Automates repetitive tasks and helps catch bugs early. <br><br><i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [Watch overview](https://www.youtube.com/watch?v=g6MS1JsRWgs) | [Test generation](gitlab_duo_chat.md#write-tests-in-the-ide) | **Tier:** Freely available for Premium and Ultimate for a limited time<br>In the future, will require Premium or Ultimate with [GitLab Duo Pro](../subscriptions/subscription-add-ons.md)<br>**Offering:** GitLab.com, Self-managed, GitLab Dedicated <br>**Status:** Beta |
|
||||
| Generates a description for the merge request based on the contents of the template. | [Merge request template population](project/merge_requests/ai_in_merge_requests.md#fill-in-merge-request-templates) | **Tier:** Freely available for Ultimate for a limited time<br>In the future, will require Ultimate with [GitLab Duo Enterprise](../subscriptions/subscription-add-ons.md)<br>**Offering:** GitLab.com<br>**Status:** Experiment |
|
||||
| Assists in creating faster and higher-quality reviews by automatically suggesting reviewers for your merge request. <br><br><i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [Watch overview](https://www.youtube.com/watch?v=ivwZQgh4Rxw) | [Suggested Reviewers](project/merge_requests/reviews/index.md#gitlab-duo-suggested-reviewers) | **Tier:** Ultimate <br>**Offering:** GitLab.com<br>**Status:** Generally Available |
|
||||
|
|
@ -31,192 +33,22 @@ GitLab is [transparent](https://handbook.gitlab.com/handbook/values/#transparenc
|
|||
| Helps ease merge request handoff between authors and reviewers and help reviewers efficiently understand suggestions. | [Code review summary](project/merge_requests/ai_in_merge_requests.md#summarize-my-merge-request-review) | **Tier:** Freely available for Ultimate for a limited time<br>In the future, will require Ultimate with [GitLab Duo Enterprise](../subscriptions/subscription-add-ons.md)<br>**Offering:** GitLab.com <br>**Status:** Experiment |
|
||||
| Helps you remediate vulnerabilities more efficiently, boost your skills, and write more secure code. <br><br><i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [Watch overview](https://www.youtube.com/watch?v=6sDf73QOav8) | [Vulnerability explanation](application_security/vulnerabilities/index.md#explaining-a-vulnerability) | **Tier:** Freely available for Ultimate for a limited time<br>In the future, will require Ultimate with [GitLab Duo Enterprise](../subscriptions/subscription-add-ons.md) <br>**Offering:** GitLab.com <br>**Status:** Beta |
|
||||
| Generates a merge request containing the changes required to mitigate a vulnerability. | [Vulnerability resolution](application_security/vulnerabilities/index.md#vulnerability-resolution) | **Tier:** Freely available for Ultimate for a limited time<br>In the future, will require Ultimate with [GitLab Duo Enterprise](../subscriptions/subscription-add-ons.md)<br>**Offering:** GitLab.com <br>**Status:** Experiment |
|
||||
| Helps you understand code by explaining it in English language. <br><br><i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [Watch overview](https://www.youtube.com/watch?v=1izKaLmmaCA) | [Code explanation](#explain-code-in-the-web-ui-with-code-explanation) | **Tier:** Freely available for Premium and Ultimate for a limited time<br>In the future, will require Premium or Ultimate with [GitLab Duo Pro](../subscriptions/subscription-add-ons.md) <br>**Offering:** GitLab.com <br>**Status:** Experiment |
|
||||
| Assists you in determining the root cause for a pipeline failure and failed CI/CD build. | [Root cause analysis](#root-cause-analysis) | **Tier:** Freely available for Ultimate for a limited time<br>In the future, will require Ultimate with [GitLab Duo Enterprise](../subscriptions/subscription-add-ons.md)<br>**Offering:** GitLab.com <br>**Status:** Experiment |
|
||||
| Assists you with predicting productivity metrics and identifying anomalies across your software development lifecycle. | [Value stream forecasting](#forecast-deployment-frequency-with-value-stream-forecasting) | **Tier:** Freely available for Ultimate for a limited time<br>In the future, will require Ultimate with [GitLab Duo Enterprise](../subscriptions/subscription-add-ons.md) <br>**Offering:** GitLab.com, Self-managed, GitLab Dedicated <br>**Status:** Experiment |
|
||||
| Helps you understand code by explaining it in English language. <br><br><i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [Watch overview](https://www.youtube.com/watch?v=1izKaLmmaCA) | [Code explanation](ai_experiments.md#explain-code-in-the-web-ui-with-code-explanation) | **Tier:** Freely available for Premium and Ultimate for a limited time<br>In the future, will require Premium or Ultimate with [GitLab Duo Pro](../subscriptions/subscription-add-ons.md) <br>**Offering:** GitLab.com <br>**Status:** Experiment |
|
||||
| Assists you in determining the root cause for a pipeline failure and failed CI/CD build. | [Root cause analysis](ai_experiments.md#root-cause-analysis) | **Tier:** Freely available for Ultimate for a limited time<br>In the future, will require Ultimate with [GitLab Duo Enterprise](../subscriptions/subscription-add-ons.md)<br>**Offering:** GitLab.com <br>**Status:** Experiment |
|
||||
| Assists you with predicting productivity metrics and identifying anomalies across your software development lifecycle. | [Value stream forecasting](ai_experiments.md#forecast-deployment-frequency-with-value-stream-forecasting) | **Tier:** Freely available for Ultimate for a limited time<br>In the future, will require Ultimate with [GitLab Duo Enterprise](../subscriptions/subscription-add-ons.md) <br>**Offering:** GitLab.com, Self-managed, GitLab Dedicated <br>**Status:** Experiment |
|
||||
| Processes and responds to your questions about your application's usage data. | [Product Analytics](analytics/analytics_dashboards.md#generate-a-custom-visualization-with-gitlab-duo) | **Tier:** Freely available for Ultimate for a limited time<br>In the future, will require Ultimate with [GitLab Duo Enterprise](../subscriptions/subscription-add-ons.md) <br>**Offering:** GitLab.com <br>**Status:** Experiment |
|
||||
|
||||
## Disable GitLab Duo features for specific groups or projects or an entire instance
|
||||
|
||||
Disable GitLab Duo features by [following these instructions](ai_features_enable.md).
|
||||
|
||||
## Experimental AI features and how to use them
|
||||
|
||||
The following subsections describe GitLab Duo features that are in the
|
||||
Experiment phase.
|
||||
|
||||
### Explain code in the Web UI with Code explanation
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Freely available for Premium and Ultimate for a limited time. In the future, will require Premium or Ultimate with [GitLab Duo Pro](../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com
|
||||
**Status:** Experiment
|
||||
|
||||
> - Introduced in GitLab 15.11 as an [Experiment](../policy/experiment-beta-support.md#experiment) on GitLab.com.
|
||||
|
||||
To use this feature:
|
||||
|
||||
- The parent group of the project must:
|
||||
- Enable the [experiment and beta features setting](group/manage.md#enable-experiment-and-beta-features).
|
||||
- You must:
|
||||
- Belong to at least one group with the [experiment and beta features setting](group/manage.md#enable-experiment-and-beta-features) enabled.
|
||||
- Have sufficient permissions to view the project.
|
||||
|
||||
GitLab can help you get up to speed faster if you:
|
||||
|
||||
- Spend a lot of time trying to understand pieces of code that others have created, or
|
||||
- Struggle to understand code written in a language that you are not familiar with.
|
||||
|
||||
By using a large language model, GitLab can explain the code in natural language.
|
||||
|
||||
To explain your code:
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your project.
|
||||
1. Select any file in your project that contains code.
|
||||
1. On the file, select the lines that you want to have explained.
|
||||
1. On the left side, select the question mark (**{question}**). You might have to scroll to the first line of your selection to view it. This sends the selected code, together with a prompt, to provide an explanation to the large language model.
|
||||
1. A drawer is displayed on the right side of the page. Wait a moment for the explanation to be generated.
|
||||
1. Provide feedback about how satisfied you are with the explanation, so we can improve the results.
|
||||
|
||||
You can also have code explained in the context of a merge request. To explain
|
||||
code in a merge request:
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your project.
|
||||
1. Select **Code > Merge requests**, then select your merge request.
|
||||
1. On the secondary menu, select **Changes**.
|
||||
1. On the file you would like explained, select the three dots (**{ellipsis_v}**) and select **View File @ $SHA**.
|
||||
|
||||
A separate browser tab opens and shows the full file with the latest changes.
|
||||
|
||||
1. On the new tab, select the lines that you want to have explained.
|
||||
1. On the left side, select the question mark (**{question}**). You might have to scroll to the first line of your selection to view it. This sends the selected code, together with a prompt, to provide an explanation to the large language model.
|
||||
1. A drawer is displayed on the right side of the page. Wait a moment for the explanation to be generated.
|
||||
1. Provide feedback about how satisfied you are with the explanation, so we can improve the results.
|
||||
|
||||

|
||||
|
||||
We cannot guarantee that the large language model produces results that are correct. Use the explanation with caution.
|
||||
|
||||
### Summarize issue discussions with Discussion summary
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Freely available for Ultimate for a limited time. In the future, will require Ultimate with [GitLab Duo Enterprise](../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com
|
||||
**Status:** Experiment
|
||||
|
||||
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/10344) in GitLab 16.0 as an [Experiment](../policy/experiment-beta-support.md#experiment).
|
||||
|
||||
To use this feature:
|
||||
|
||||
- The parent group of the issue must:
|
||||
- Enable the [experiment and beta features setting](group/manage.md#enable-experiment-and-beta-features).
|
||||
- You must:
|
||||
- Belong to at least one group with the [experiment and beta features setting](group/manage.md#enable-experiment-and-beta-features) enabled.
|
||||
- Have sufficient permissions to view the issue.
|
||||
|
||||
You can generate a summary of discussions on an issue:
|
||||
|
||||
1. In an issue, scroll to the **Activity** section.
|
||||
1. Select **View summary**.
|
||||
|
||||
The comments in the issue are summarized in as many as 10 list items.
|
||||
The summary is displayed only for you.
|
||||
|
||||
Provide feedback on this experimental feature in [issue 407779](https://gitlab.com/gitlab-org/gitlab/-/issues/407779).
|
||||
|
||||
**Data usage**: When you use this feature, the text of all comments on the issue are sent to the large
|
||||
language model referenced above.
|
||||
|
||||
### Forecast deployment frequency with Value stream forecasting
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Freely available for Ultimate for a limited time. In the future, will require Ultimate with [GitLab Duo Enterprise](../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
**Status:** Experiment
|
||||
|
||||
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/10228) in GitLab 16.2 as an [Experiment](../policy/experiment-beta-support.md#experiment).
|
||||
|
||||
To use this feature:
|
||||
|
||||
- The parent group of the project must:
|
||||
- Enable the [experiment and beta features setting](group/manage.md#enable-experiment-and-beta-features).
|
||||
- You must:
|
||||
- Belong to at least one group with the [experiment and beta features setting](group/manage.md#enable-experiment-and-beta-features) enabled.
|
||||
- Have sufficient permissions to view the CI/CD analytics.
|
||||
|
||||
In CI/CD Analytics, you can view a forecast of deployment frequency:
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your project.
|
||||
1. Select **Analyze > CI/CD analytics**.
|
||||
1. Select the **Deployment frequency** tab.
|
||||
1. Turn on the **Show forecast** toggle.
|
||||
1. On the confirmation dialog, select **Accept testing terms**.
|
||||
|
||||
The forecast is displayed as a dotted line on the chart. Data is forecasted for a duration that is half of the selected date range.
|
||||
For example, if you select a 30-day range, a forecast for the following 15 days is displayed.
|
||||
|
||||

|
||||
|
||||
Provide feedback on this experimental feature in [issue 416833](https://gitlab.com/gitlab-org/gitlab/-/issues/416833).
|
||||
|
||||
### Root cause analysis
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Freely available for Ultimate for a limited time. In the future, will require Ultimate with [GitLab Duo Enterprise](../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com
|
||||
**Status:** Experiment
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/123692) in GitLab 16.2 as an [Experiment](../policy/experiment-beta-support.md#experiment).
|
||||
|
||||
To use this feature:
|
||||
|
||||
- The parent group of the project must:
|
||||
- Enable the [experiment and beta features setting](group/manage.md#enable-experiment-and-beta-features).
|
||||
- You must:
|
||||
- Belong to at least one group with the [experiment and beta features setting](group/manage.md#enable-experiment-and-beta-features) enabled.
|
||||
- Have sufficient permissions to view the CI/CD job.
|
||||
|
||||
When the feature is available, the "Root cause analysis" button will appears on
|
||||
a failed CI/CD job. Selecting this button generates an analysis regarding the
|
||||
reason for the failure.
|
||||
|
||||
### Summarize an issue with Issue description generation
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Freely available for Ultimate for a limited time. In the future, will require Ultimate with [GitLab Duo Enterprise](../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com
|
||||
**Status:** Experiment
|
||||
|
||||
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/10762) in GitLab 16.3 as an [Experiment](../policy/experiment-beta-support.md#experiment).
|
||||
|
||||
To use this feature:
|
||||
|
||||
- The parent group of the project must:
|
||||
- Enable the [experiment and beta features setting](group/manage.md#enable-experiment-and-beta-features).
|
||||
- You must:
|
||||
- Belong to at least one group with the [experiment and beta features setting](group/manage.md#enable-experiment-and-beta-features) enabled.
|
||||
- Have sufficient permissions to view the issue.
|
||||
|
||||
You can generate the description for an issue from a short summary.
|
||||
|
||||
1. Create a new issue.
|
||||
1. Above the **Description** field, select **AI actions > Generate issue description**.
|
||||
1. Write a short description and select **Submit**.
|
||||
|
||||
The issue description is replaced with AI-generated text.
|
||||
|
||||
Provide feedback on this experimental feature in [issue 409844](https://gitlab.com/gitlab-org/gitlab/-/issues/409844).
|
||||
|
||||
**Data usage**: When you use this feature, the text you enter is sent to the large
|
||||
language model referenced above.
|
||||
|
||||
## Language models
|
||||
|
||||
| Feature | Large Language Model |
|
||||
|---|---|
|
||||
| [Git suggestions](https://gitlab.com/gitlab-org/gitlab/-/issues/409636) | Vertex AI Codey [`codechat-bison`](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/code-chat) |
|
||||
| [Discussion summary](#summarize-issue-discussions-with-discussion-summary) |Anthropic [`Claude-2.1`](https://docs.anthropic.com/claude/docs/models-overview#model-comparison) |
|
||||
| [Issue description generation](#summarize-an-issue-with-issue-description-generation) | Anthropic [`Claude-2.1`](https://docs.anthropic.com/claude/docs/models-overview#model-comparison) |
|
||||
| [Discussion summary](ai_experiments.md#summarize-issue-discussions-with-discussion-summary) |Anthropic [`Claude-2.1`](https://docs.anthropic.com/claude/docs/models-overview#model-comparison) |
|
||||
| [Issue description generation](ai_experiments.md#summarize-an-issue-with-issue-description-generation) | Anthropic [`Claude-2.1`](https://docs.anthropic.com/claude/docs/models-overview#model-comparison) |
|
||||
| [Code Suggestions](project/repository/code_suggestions/index.md) | For Code Completion: Vertex AI Codey [`code-gecko`](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/code-completion) For Code Generation: Anthropic [`Claude-3-Sonnet`](https://docs.anthropic.com/claude/docs/models-overview) |
|
||||
| [Test generation](gitlab_duo_chat.md#write-tests-in-the-ide) | Anthropic [`Claude-2.1`](https://docs.anthropic.com/claude/docs/models-overview#model-comparison) |
|
||||
| [Merge request template population](project/merge_requests/ai_in_merge_requests.md#fill-in-merge-request-templates) | Vertex AI Codey [`text-bison`](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/text) |
|
||||
|
|
@ -225,10 +57,10 @@ language model referenced above.
|
|||
| [Code review summary](project/merge_requests/ai_in_merge_requests.md#summarize-my-merge-request-review) | Vertex AI Codey [`text-bison`](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/text) |
|
||||
| [Vulnerability explanation](application_security/vulnerabilities/index.md#explaining-a-vulnerability) | Vertex AI Codey [`text-bison`](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/text) Anthropic [`Claude-2.1`](https://docs.anthropic.com/claude/docs/models-overview#model-comparison) if degraded performance |
|
||||
| [Vulnerability resolution](application_security/vulnerabilities/index.md#explaining-a-vulnerability) | Vertex AI Codey [`code-bison`](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/code-generation) |
|
||||
| [Code explanation](#explain-code-in-the-web-ui-with-code-explanation) | Vertex AI Codey [`codechat-bison`](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/code-chat) |
|
||||
| [Code explanation](ai_experiments.md#explain-code-in-the-web-ui-with-code-explanation) | Vertex AI Codey [`codechat-bison`](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/code-chat) |
|
||||
| [GitLab Duo Chat](gitlab_duo_chat.md) | Anthropic [`Claude-2.1`](https://docs.anthropic.com/claude/docs/models-overview#model-comparison) Vertex AI Codey [`textembedding-gecko`](https://cloud.google.com/vertex-ai/generative-ai/docs/embeddings/get-text-embeddings) |
|
||||
| [Root cause analysis](#root-cause-analysis) | Vertex AI Codey [`text-bison`](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/text) |
|
||||
| [Value stream forecasting](#forecast-deployment-frequency-with-value-stream-forecasting) | Statistical forecasting |
|
||||
| [Root cause analysis](ai_experiments.md#root-cause-analysis) | Vertex AI Codey [`text-bison`](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/text) |
|
||||
| [Value stream forecasting](ai_experiments.md#forecast-deployment-frequency-with-value-stream-forecasting) | Statistical forecasting |
|
||||
| [Product analytics](analytics/analytics_dashboards.md#generate-a-custom-visualization-with-gitlab-duo) | Vertex AI Codey [`codechat-bison`](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/code-chat) |
|
||||
|
||||
## Data usage
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ You can also ask to explain specific job errors by copy-pasting the error messag
|
|||
|
||||
- `Please explain this CI/CD job error message in the context of a Go project: build.sh: line 14: go command not found`
|
||||
|
||||
Alternatively, you can use [root cause analysis in CI/CD](ai_features.md#root-cause-analysis).
|
||||
Alternatively, you can use [root cause analysis in CI/CD](ai_experiments.md#root-cause-analysis).
|
||||
|
||||
For more practical examples, see the [GitLab Duo examples](gitlab_duo_examples.md).
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue