Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
41740d257d
commit
4160a09e2d
|
|
@ -1 +1 @@
|
|||
eaf93c0f64c8098eb1c08113ba3d86ae71191847
|
||||
de06391c38b27ccaa4e86b653d463dfcacb180a1
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ PATH
|
|||
gitlab-active-context (0.0.1)
|
||||
activesupport
|
||||
connection_pool
|
||||
elasticsearch
|
||||
pg
|
||||
zeitwerk
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ PATH
|
|||
gitlab-active-context (0.0.1)
|
||||
activesupport
|
||||
connection_pool
|
||||
elasticsearch
|
||||
pg
|
||||
zeitwerk
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ export default {
|
|||
<div
|
||||
v-for="stage in stages"
|
||||
:key="stage.id"
|
||||
class="pipeline-mini-graph-stage-container dropdown gl-mr-2 gl-inline-flex gl-align-middle"
|
||||
class="pipeline-mini-graph-stage-container dropdown gl-my-1 gl-mr-2 gl-inline-flex gl-align-middle"
|
||||
>
|
||||
<pipeline-stage-dropdown
|
||||
:stage="stage"
|
||||
|
|
|
|||
|
|
@ -1,19 +1,17 @@
|
|||
<!-- eslint-disable vue/multi-word-component-names -->
|
||||
<script>
|
||||
import {
|
||||
GlBadge,
|
||||
GlIcon,
|
||||
GlLink,
|
||||
GlLoadingIcon,
|
||||
GlBadge,
|
||||
GlSprintf,
|
||||
GlTooltipDirective as GlTooltip,
|
||||
GlTruncate,
|
||||
} from '@gitlab/ui';
|
||||
import { __, s__ } from '~/locale';
|
||||
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
|
||||
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
|
||||
import { createAlert } from '~/alert';
|
||||
import deploymentDetails from '../graphql/queries/deployment_details.query.graphql';
|
||||
import TimelineEntryItem from '~/vue_shared/components/notes/timeline_entry_item.vue';
|
||||
import { localeDateFormat } from '~/lib/utils/datetime/locale_dateformat';
|
||||
import DeploymentStatusLink from './deployment_status_link.vue';
|
||||
import Commit from './commit.vue';
|
||||
|
||||
|
|
@ -23,17 +21,15 @@ export default {
|
|||
Commit,
|
||||
DeploymentStatusLink,
|
||||
GlBadge,
|
||||
GlSprintf,
|
||||
GlIcon,
|
||||
GlLink,
|
||||
GlSprintf,
|
||||
GlTruncate,
|
||||
GlLoadingIcon,
|
||||
TimeAgoTooltip,
|
||||
TimelineEntryItem,
|
||||
},
|
||||
directives: {
|
||||
GlTooltip,
|
||||
},
|
||||
inject: ['projectPath'],
|
||||
props: {
|
||||
deployment: {
|
||||
type: Object,
|
||||
|
|
@ -44,31 +40,37 @@ export default {
|
|||
default: false,
|
||||
required: false,
|
||||
},
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
required: false,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
status() {
|
||||
return this.deployment?.status;
|
||||
},
|
||||
iid() {
|
||||
return this.deployment?.iid;
|
||||
},
|
||||
isTag() {
|
||||
return this.deployment?.tag;
|
||||
},
|
||||
shortSha() {
|
||||
return this.commit?.shortId;
|
||||
},
|
||||
timeStamp() {
|
||||
return this.deployment?.deployedAt ? __('Deployed %{timeago}') : __('Created %{timeago}');
|
||||
triggeredText() {
|
||||
if (this.user && this.displayTime) {
|
||||
return s__('Deployment|Triggered by %{username} on %{time}');
|
||||
}
|
||||
if (this.user && !this.displayTime) {
|
||||
return s__('Deployment|Triggered by %{username}');
|
||||
}
|
||||
if (this.displayTime && !this.user) {
|
||||
return s__('Deployment|Triggered on %{time}');
|
||||
}
|
||||
return '';
|
||||
},
|
||||
displayTimeAgo() {
|
||||
deploymentTime() {
|
||||
return this.deployment?.deployedAt || this.deployment?.createdAt;
|
||||
},
|
||||
displayTime() {
|
||||
if (!this.deploymentTime) return null;
|
||||
const dateTime = new Date(this.deploymentTime);
|
||||
return localeDateFormat.asDateTimeFull.format(dateTime);
|
||||
},
|
||||
createdAt() {
|
||||
return this.deployment?.createdAt;
|
||||
},
|
||||
|
|
@ -90,12 +92,6 @@ export default {
|
|||
deployable() {
|
||||
return this.deployment?.deployable;
|
||||
},
|
||||
jobName() {
|
||||
return this.deployable?.name;
|
||||
},
|
||||
jobPath() {
|
||||
return this.deployable?.buildPath;
|
||||
},
|
||||
ref() {
|
||||
return this.deployment?.ref;
|
||||
},
|
||||
|
|
@ -108,192 +104,82 @@ export default {
|
|||
needsApproval() {
|
||||
return this.deployment.pendingApprovalCount > 0;
|
||||
},
|
||||
hasTags() {
|
||||
return this.tags?.length > 0;
|
||||
},
|
||||
displayTags() {
|
||||
return this.tags?.slice(0, 5);
|
||||
},
|
||||
},
|
||||
apollo: {
|
||||
// eslint-disable-next-line @gitlab/vue-no-undef-apollo-properties
|
||||
tags: {
|
||||
query: deploymentDetails,
|
||||
variables() {
|
||||
return {
|
||||
projectPath: this.projectPath,
|
||||
iid: this.deployment.iid,
|
||||
};
|
||||
},
|
||||
update(data) {
|
||||
return data?.project?.deployment?.tags;
|
||||
},
|
||||
error(error) {
|
||||
createAlert({
|
||||
message: this.$options.i18n.LOAD_ERROR_MESSAGE,
|
||||
captureError: true,
|
||||
error,
|
||||
});
|
||||
},
|
||||
skip() {
|
||||
return !this.visible;
|
||||
},
|
||||
},
|
||||
},
|
||||
i18n: {
|
||||
latestBadge: s__('Deployment|Latest Deployed'),
|
||||
deploymentId: s__('Deployment|Deployment ID'),
|
||||
copyButton: __('Copy commit SHA'),
|
||||
commitSha: __('Commit SHA'),
|
||||
triggerer: s__('Deployment|Triggerer'),
|
||||
needsApproval: s__('Deployment|Needs Approval'),
|
||||
job: __('Job'),
|
||||
api: __('API'),
|
||||
branch: __('Branch'),
|
||||
tags: __('Tags'),
|
||||
tag: s__('Deployment|Tag'),
|
||||
},
|
||||
headerClasses: [
|
||||
'gl-flex',
|
||||
'gl-items-start',
|
||||
'md:gl-items-center',
|
||||
'gl-justify-between',
|
||||
'gl-pr-6',
|
||||
],
|
||||
headerDetailsClasses: [
|
||||
'gl-flex',
|
||||
'gl-flex-col',
|
||||
'md:gl-flex-row',
|
||||
'gl-items-start',
|
||||
'md:gl-items-center',
|
||||
'gl-text-sm',
|
||||
'gl-text-gray-700',
|
||||
],
|
||||
deploymentStatusClasses: [
|
||||
'gl-flex',
|
||||
'gl-gap-x-3',
|
||||
'gl-mr-0',
|
||||
'md:gl-mr-5',
|
||||
'gl-mb-3',
|
||||
'md:gl-mb-0',
|
||||
],
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<div :class="$options.headerClasses">
|
||||
<div :class="$options.headerDetailsClasses">
|
||||
<div :class="$options.deploymentStatusClasses">
|
||||
<deployment-status-link
|
||||
v-if="status"
|
||||
:deployment="deployment"
|
||||
:deployment-job="deployable"
|
||||
:status="status"
|
||||
/>
|
||||
<gl-badge v-if="needsApproval" variant="warning">
|
||||
{{ $options.i18n.needsApproval }}
|
||||
</gl-badge>
|
||||
<gl-badge v-if="latest" variant="info">{{ $options.i18n.latestBadge }}</gl-badge>
|
||||
</div>
|
||||
<div class="gl-flex gl-items-center gl-gap-x-5">
|
||||
<div
|
||||
v-if="iid"
|
||||
v-gl-tooltip
|
||||
class="gl-flex"
|
||||
:title="$options.i18n.deploymentId"
|
||||
:aria-label="$options.i18n.deploymentId"
|
||||
>
|
||||
<gl-icon ref="deployment-iid-icon" name="deployments" />
|
||||
<span class="gl-ml-2">#{{ iid }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="shortSha"
|
||||
data-testid="deployment-commit-sha"
|
||||
class="gl-flex gl-items-center gl-font-monospace"
|
||||
>
|
||||
<gl-icon ref="deployment-commit-icon" name="commit" class="gl-mr-2" />
|
||||
<gl-link v-gl-tooltip :title="$options.i18n.commitSha" :href="commitPath">
|
||||
{{ shortSha }}
|
||||
</gl-link>
|
||||
<clipboard-button
|
||||
:text="shortSha"
|
||||
category="tertiary"
|
||||
:title="$options.i18n.copyButton"
|
||||
size="small"
|
||||
/>
|
||||
</div>
|
||||
<time-ago-tooltip
|
||||
v-if="displayTimeAgo"
|
||||
:time="displayTimeAgo"
|
||||
class="gl-flex"
|
||||
data-testid="deployment-timestamp"
|
||||
>
|
||||
<template #default="{ timeAgo }">
|
||||
<gl-icon name="calendar" class="gl-mr-2" />
|
||||
<span class="gl-mr-2 gl-whitespace-nowrap">
|
||||
<gl-sprintf :message="timeStamp">
|
||||
<template #timeago>{{ timeAgo }}</template>
|
||||
</gl-sprintf>
|
||||
</span>
|
||||
</template>
|
||||
</time-ago-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<commit v-if="commit" :commit="commit" class="gl-mt-3" />
|
||||
<div class="gl-mt-3"><slot name="approval"></slot></div>
|
||||
<div class="gl-mt-5 gl-flex gl-flex-col gl-pr-4 md:gl-flex-row md:gl-items-center md:gl-pr-0">
|
||||
<div v-if="user" class="gl-flex gl-flex-col md:gl-max-w-3/20">
|
||||
<span class="gl-text-subtle">{{ $options.i18n.triggerer }}</span>
|
||||
<gl-link :href="userPath" class="gl-mt-3 gl-font-monospace">
|
||||
<gl-truncate :text="username" with-tooltip />
|
||||
</gl-link>
|
||||
</div>
|
||||
<div class="gl-mt-4 gl-flex gl-flex-col md:gl-mt-0 md:gl-max-w-3/20 md:gl-pl-7">
|
||||
<span class="gl-text-subtle" :class="{ 'gl-ml-3': !deployable }">
|
||||
{{ $options.i18n.job }}
|
||||
</span>
|
||||
<gl-link v-if="jobPath" :href="jobPath" class="gl-mt-3 gl-font-monospace">
|
||||
<gl-truncate :text="jobName" with-tooltip position="middle" />
|
||||
</gl-link>
|
||||
<span v-else-if="jobName" class="gl-mt-3 gl-font-monospace">
|
||||
<gl-truncate :text="jobName" with-tooltip position="middle" />
|
||||
</span>
|
||||
<gl-badge v-else class="gl-mt-3 gl-font-monospace" variant="info">
|
||||
{{ $options.i18n.api }}
|
||||
</gl-badge>
|
||||
</div>
|
||||
<div
|
||||
v-if="ref && !isTag"
|
||||
class="gl-mt-4 gl-flex gl-flex-col md:gl-mt-0 md:gl-max-w-3/20 md:gl-pl-7"
|
||||
>
|
||||
<span class="gl-text-subtle">{{ $options.i18n.branch }}</span>
|
||||
<gl-link :href="refPath" class="gl-mt-3 gl-font-monospace">
|
||||
<gl-truncate :text="refName" with-tooltip />
|
||||
</gl-link>
|
||||
</div>
|
||||
<div
|
||||
v-if="hasTags || $apollo.queries.tags.loading"
|
||||
class="gl-mt-4 gl-flex gl-flex-col md:gl-mt-0 md:gl-max-w-3/20 md:gl-pl-7"
|
||||
>
|
||||
<span class="gl-text-subtle">{{ $options.i18n.tags }}</span>
|
||||
<gl-loading-icon
|
||||
v-if="$apollo.queries.tags.loading"
|
||||
class="gl-mt-3 gl-font-monospace"
|
||||
size="sm"
|
||||
inline
|
||||
<timeline-entry-item class="system-note gl-relative">
|
||||
<div
|
||||
class="system-note-dot gl-relative gl-float-left gl-ml-4 gl-mt-3 gl-h-3 gl-w-3 gl-rounded-full gl-border-2 gl-border-solid gl-border-subtle gl-bg-gray-900"
|
||||
></div>
|
||||
<div class="gl-ml-7">
|
||||
<div class="gl-flex gl-flex-wrap gl-items-center gl-gap-3">
|
||||
<deployment-status-link
|
||||
v-if="status"
|
||||
:deployment="deployment"
|
||||
:deployment-job="deployable"
|
||||
:status="status"
|
||||
/>
|
||||
<div v-if="hasTags" class="gl-flex gl-flex-row">
|
||||
<gl-link
|
||||
v-for="(tag, ndx) in displayTags"
|
||||
:key="tag.name"
|
||||
:href="tag.path"
|
||||
class="gl-mr-3 gl-mt-3 gl-font-monospace"
|
||||
>
|
||||
{{ tag.name }}<span v-if="ndx + 1 < tags.length">, </span>
|
||||
<gl-badge v-if="needsApproval" variant="warning">
|
||||
{{ $options.i18n.needsApproval }}
|
||||
</gl-badge>
|
||||
<gl-badge v-if="latest" variant="info">{{ $options.i18n.latestBadge }}</gl-badge>
|
||||
</div>
|
||||
<div class="gl-flex gl-flex-wrap gl-items-center gl-gap-x-3">
|
||||
<commit v-if="commit" :commit="commit" />
|
||||
<div
|
||||
v-if="shortSha"
|
||||
data-testid="deployment-commit-sha"
|
||||
class="gl-flex gl-items-center gl-font-monospace"
|
||||
>
|
||||
<gl-icon ref="deployment-commit-icon" name="commit" class="gl-mr-2" />
|
||||
<gl-link v-gl-tooltip :title="$options.i18n.commitSha" :href="commitPath">
|
||||
{{ shortSha }}
|
||||
</gl-link>
|
||||
<clipboard-button
|
||||
:text="shortSha"
|
||||
category="tertiary"
|
||||
:title="$options.i18n.copyButton"
|
||||
size="small"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-if="isTag"
|
||||
data-testid="deployment-tag"
|
||||
class="gl-flex gl-items-center gl-font-monospace"
|
||||
>
|
||||
<gl-icon ref="deployment-tag-icon" name="tag" class="gl-mr-2" />
|
||||
<gl-link v-gl-tooltip :title="$options.i18n.tag" :href="refPath">
|
||||
{{ refName }}
|
||||
</gl-link>
|
||||
<div v-if="tags.length > 5" class="gl-mr-3 gl-mt-3 gl-font-monospace">...</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="triggeredText" class="gl-flex gl-flex-wrap gl-items-center gl-gap-x-2">
|
||||
<gl-sprintf :message="triggeredText">
|
||||
<template #username>
|
||||
<gl-link :href="userPath" data-testid="deployment-triggerer">
|
||||
<gl-truncate :text="username" with-tooltip />
|
||||
</gl-link>
|
||||
</template>
|
||||
<template #time>
|
||||
<span
|
||||
v-gl-tooltip
|
||||
class="gl-truncate-end gl-mr-2 gl-whitespace-nowrap"
|
||||
data-testid="deployment-timestamp"
|
||||
:title="displayTime"
|
||||
>
|
||||
{{ displayTime }}
|
||||
</span>
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</timeline-entry-item>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -55,5 +55,5 @@ export default {
|
|||
};
|
||||
</script>
|
||||
<template>
|
||||
<ci-icon v-if="status" :status="statusObject" show-status-text />
|
||||
<ci-icon v-if="status" :status="statusObject" show-status-text class="!gl-border-0" />
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ export default {
|
|||
:aria-label="title"
|
||||
:items="actionItems"
|
||||
icon="play"
|
||||
size="small"
|
||||
text-sr-only
|
||||
right
|
||||
data-container="body"
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ export default {
|
|||
:aria-label="$options.i18n.title"
|
||||
:href="externalUrl"
|
||||
is-unsafe-link
|
||||
size="small"
|
||||
class="external-url"
|
||||
target="_blank"
|
||||
icon="external-link"
|
||||
|
|
|
|||
|
|
@ -102,10 +102,7 @@ export default {
|
|||
};
|
||||
</script>
|
||||
<template>
|
||||
<div
|
||||
:class="{ 'gl-pb-5': !visible }"
|
||||
class="gl-border-1 gl-border-default gl-pt-3 gl-border-b-solid"
|
||||
>
|
||||
<div :class="{ 'gl-border-b gl-pb-5': !visible }" class="gl-pt-3">
|
||||
<div class="gl-flex gl-w-full gl-items-center gl-px-3">
|
||||
<gl-button
|
||||
class="gl-mr-4"
|
||||
|
|
@ -126,13 +123,12 @@ export default {
|
|||
v-for="(environment, index) in environments"
|
||||
:key="environment.name"
|
||||
:environment="environment"
|
||||
:class="{ 'gl-mt-5': isFirstEnvironment(index) }"
|
||||
class="gl-border-1 gl-border-default gl-pt-3 gl-border-t-solid"
|
||||
:class="{ '!gl-border-t !gl-mt-5': isFirstEnvironment(index) }"
|
||||
in-folder
|
||||
/>
|
||||
<div
|
||||
v-if="isMessageShowing"
|
||||
class="gl-border-1 gl-border-default gl-bg-gray-10 gl-py-5 gl-text-center gl-border-t-solid"
|
||||
class="gl-border-b gl-bg-gray-10 gl-py-3 gl-text-center"
|
||||
data-testid="environment-folder-message-element"
|
||||
>
|
||||
<gl-sprintf :message="$options.i18n.message">
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@ export default {
|
|||
},
|
||||
i18n: {
|
||||
title: s__('Environments|Stop environment'),
|
||||
stop: s__('Environments|Stop'),
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
@ -82,11 +81,10 @@ export default {
|
|||
:loading="isLoading || isEnvironmentStopping"
|
||||
:title="$options.i18n.title"
|
||||
:aria-label="$options.i18n.title"
|
||||
size="small"
|
||||
icon="stop"
|
||||
category="secondary"
|
||||
variant="danger"
|
||||
@click="onClick"
|
||||
>
|
||||
{{ $options.i18n.stop }}
|
||||
</gl-button>
|
||||
/>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -87,6 +87,9 @@ export default {
|
|||
active: __('Active'),
|
||||
stopped: __('Stopped'),
|
||||
searchPlaceholder: s__('Environments|Search by environment name'),
|
||||
name: s__('Environments|Name'),
|
||||
deployments: s__('Environments|Deployments'),
|
||||
actions: s__('Environments|Actions'),
|
||||
},
|
||||
modalId: 'enable-review-app-info',
|
||||
stopStaleEnvsModalId: 'stop-stale-environments-modal',
|
||||
|
|
@ -318,17 +321,24 @@ export default {
|
|||
/></template>
|
||||
<environments-app-skeleton-loader v-if="loading" />
|
||||
<template v-else-if="showContent">
|
||||
<div
|
||||
v-if="!showEmptyState"
|
||||
class="gl-border-t gl-border-b gl-hidden lg:gl-flex"
|
||||
data-testid="environments-table-header"
|
||||
>
|
||||
<div class="gl-w-1/5 gl-p-4 gl-font-bold">{{ $options.i18n.name }}</div>
|
||||
<div class="gl-w-3/5 gl-p-4 gl-font-bold">{{ $options.i18n.deployments }}</div>
|
||||
<div class="gl-p-4 gl-font-bold">{{ $options.i18n.actions }}</div>
|
||||
</div>
|
||||
<environment-folder
|
||||
v-for="folder in folders"
|
||||
:key="folder.name"
|
||||
class="gl-mb-3"
|
||||
:scope="scope"
|
||||
:search="search"
|
||||
:nested-environment="folder" />
|
||||
<environment-item
|
||||
v-for="environment in environments"
|
||||
:key="environment.name"
|
||||
class="gl-mb-3 gl-border-1 gl-border-default gl-border-b-solid"
|
||||
:environment="environment.latest"
|
||||
@change="refetchEnvironments"
|
||||
/></template>
|
||||
|
|
|
|||
|
|
@ -1,17 +1,14 @@
|
|||
<script>
|
||||
import {
|
||||
GlBadge,
|
||||
GlButton,
|
||||
GlCollapse,
|
||||
GlDisclosureDropdown,
|
||||
GlLink,
|
||||
GlSprintf,
|
||||
GlTooltipDirective as GlTooltip,
|
||||
} from '@gitlab/ui';
|
||||
import { __, s__ } from '~/locale';
|
||||
import { s__ } from '~/locale';
|
||||
import { truncate } from '~/lib/utils/text_utility';
|
||||
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
|
||||
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||
import isLastDeployment from '../graphql/queries/is_last_deployment.query.graphql';
|
||||
import ExternalUrl from './environment_external_url.vue';
|
||||
import Actions from './environment_actions.vue';
|
||||
|
|
@ -26,9 +23,7 @@ import DeployBoardWrapper from './deploy_board_wrapper.vue';
|
|||
export default {
|
||||
components: {
|
||||
GlDisclosureDropdown,
|
||||
GlCollapse,
|
||||
GlBadge,
|
||||
GlButton,
|
||||
GlLink,
|
||||
GlSprintf,
|
||||
Actions,
|
||||
|
|
@ -42,14 +37,11 @@ export default {
|
|||
TimeAgoTooltip,
|
||||
Delete,
|
||||
EnvironmentAlert: () => import('ee_component/environments/components/environment_alert.vue'),
|
||||
EnvironmentApproval: () =>
|
||||
import('ee_component/environments/components/environment_approval.vue'),
|
||||
},
|
||||
directives: {
|
||||
GlTooltip,
|
||||
},
|
||||
mixins: [glFeatureFlagsMixin()],
|
||||
inject: ['helpPagePath', 'projectPath'],
|
||||
inject: ['helpPagePath'],
|
||||
props: {
|
||||
environment: {
|
||||
required: true,
|
||||
|
|
@ -71,38 +63,36 @@ export default {
|
|||
},
|
||||
},
|
||||
i18n: {
|
||||
collapse: __('Collapse'),
|
||||
expand: __('Expand'),
|
||||
emptyState: s__(
|
||||
'Environments|There are no deployments for this environment yet. %{linkStart}Learn more about setting up deployments.%{linkEnd}',
|
||||
),
|
||||
autoStopIn: s__('Environment|Auto stop %{time}'),
|
||||
tierTooltip: s__('Environment|Deployment tier'),
|
||||
},
|
||||
data() {
|
||||
return { visible: false };
|
||||
name: s__('Environments|Name'),
|
||||
deployments: s__('Environments|Deployments'),
|
||||
actions: s__('Environments|Actions'),
|
||||
},
|
||||
computed: {
|
||||
icon() {
|
||||
return this.visible ? 'chevron-lg-down' : 'chevron-lg-right';
|
||||
},
|
||||
externalUrl() {
|
||||
return this.environment.externalUrl;
|
||||
},
|
||||
name() {
|
||||
return this.inFolder ? this.environment.nameWithoutType : this.environment.name;
|
||||
},
|
||||
label() {
|
||||
return this.visible ? this.$options.i18n.collapse : this.$options.i18n.expand;
|
||||
deployments() {
|
||||
return [this.upcomingDeployment, this.lastDeployment].filter(Boolean);
|
||||
},
|
||||
lastDeployment() {
|
||||
return this.environment?.lastDeployment;
|
||||
},
|
||||
upcomingDeployment() {
|
||||
return this.environment?.upcomingDeployment;
|
||||
if (!this.environment?.upcomingDeployment) {
|
||||
return null;
|
||||
}
|
||||
return { ...this.environment?.upcomingDeployment, isUpcoming: true };
|
||||
},
|
||||
hasDeployment() {
|
||||
return Boolean(this.environment?.upcomingDeployment || this.environment?.lastDeployment);
|
||||
return Boolean(this.deployments.length);
|
||||
},
|
||||
tier() {
|
||||
return this.lastDeployment?.tierInYaml;
|
||||
|
|
@ -144,9 +134,6 @@ export default {
|
|||
|
||||
return now < autoStopDate;
|
||||
},
|
||||
upcomingDeploymentIid() {
|
||||
return this.environment.upcomingDeployment?.iid.toString() || '';
|
||||
},
|
||||
autoStopPath() {
|
||||
return this.environment?.cancelAutoStopPath ?? '';
|
||||
},
|
||||
|
|
@ -163,71 +150,73 @@ export default {
|
|||
return this.environment?.rolloutStatus;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
toggleEnvironmentCollapse() {
|
||||
this.visible = !this.visible;
|
||||
},
|
||||
},
|
||||
deploymentClasses: [
|
||||
'gl-border-default',
|
||||
'gl-border-t-solid',
|
||||
'gl-border-1',
|
||||
'gl-py-5',
|
||||
'md:gl-pl-7',
|
||||
'gl-bg-gray-10',
|
||||
],
|
||||
deployBoardClasses: [
|
||||
'gl-border-default',
|
||||
'gl-border-t-solid',
|
||||
'gl-border-1',
|
||||
'gl-py-4',
|
||||
'md:gl-pl-7',
|
||||
'gl-bg-gray-10',
|
||||
],
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<div class="gl-flex gl-items-center gl-justify-between gl-px-3 gl-pb-5 gl-pt-3">
|
||||
<div :class="{ 'gl-ml-7': inFolder }" class="gl-mr-4 gl-flex gl-min-w-0 gl-items-center">
|
||||
<gl-button
|
||||
class="gl-mr-4 gl-min-w-fit"
|
||||
:icon="icon"
|
||||
:aria-label="label"
|
||||
size="small"
|
||||
category="secondary"
|
||||
@click="toggleEnvironmentCollapse"
|
||||
/>
|
||||
<gl-link
|
||||
v-gl-tooltip
|
||||
:href="environment.environmentPath"
|
||||
class="gl-truncate"
|
||||
:class="{ 'gl-font-bold': visible }"
|
||||
:title="name"
|
||||
>
|
||||
{{ displayName }}
|
||||
</gl-link>
|
||||
<gl-badge
|
||||
v-if="tier"
|
||||
v-gl-tooltip
|
||||
:title="$options.i18n.tierTooltip"
|
||||
class="gl-ml-3 gl-font-monospace"
|
||||
>{{ tier }}</gl-badge
|
||||
>
|
||||
<div
|
||||
class="gl-border gl-mt-4 gl-flex gl-flex-col lg:gl-mt-0 lg:gl-flex-row lg:gl-border-x-0 lg:gl-border-t-0"
|
||||
>
|
||||
<div
|
||||
class="gl-border-b gl-flex gl-shrink-0 gl-items-baseline gl-p-4 lg:gl-w-1/5 lg:gl-border-b-0"
|
||||
>
|
||||
<strong class="gl-block gl-w-1/3 gl-flex-shrink-0 gl-pr-4 md:gl-w-1/4 lg:gl-hidden">{{
|
||||
$options.i18n.name
|
||||
}}</strong>
|
||||
<gl-link v-gl-tooltip :href="environment.environmentPath" class="gl-truncate" :title="name">
|
||||
{{ displayName }}
|
||||
</gl-link>
|
||||
<gl-badge
|
||||
v-if="tier"
|
||||
v-gl-tooltip
|
||||
:title="$options.i18n.tierTooltip"
|
||||
class="gl-ml-3 gl-font-monospace"
|
||||
>{{ tier }}</gl-badge
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
class="issuable-discussion gl-border-b gl-flex gl-shrink-0 gl-flex-wrap gl-py-4 lg:gl-w-3/5 lg:gl-flex-col lg:gl-border-b-0"
|
||||
>
|
||||
<template v-if="hasDeployment">
|
||||
<strong class="gl-block gl-w-1/3 gl-flex-shrink-0 gl-px-4 md:gl-w-1/4 lg:gl-hidden">{{
|
||||
$options.i18n.deployments
|
||||
}}</strong>
|
||||
<ul class="main-notes-list timeline gl-relative -gl-ml-4 gl-w-2/3 lg:gl-w-full">
|
||||
<deployment
|
||||
v-for="deployment of deployments"
|
||||
:key="deployment.id"
|
||||
:data-testid="
|
||||
deployment.isUpcoming ? 'upcoming-deployment-content' : 'latest-deployment-content'
|
||||
"
|
||||
:deployment="deployment"
|
||||
:latest="deployment.isLast"
|
||||
class="[&:nth-child(2)]:gl-mt-4"
|
||||
/>
|
||||
</ul>
|
||||
</template>
|
||||
<div v-else class="gl-px-4 gl-align-middle" data-testid="deployments-empty-state">
|
||||
<gl-sprintf :message="$options.i18n.emptyState">
|
||||
<template #link="{ content }">
|
||||
<gl-link :href="helpPagePath">{{ content }}</gl-link>
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
</div>
|
||||
<div class="gl-flex gl-items-center">
|
||||
<p
|
||||
v-if="canShowAutoStopDate"
|
||||
class="gl-mb-0 gl-mr-5 gl-text-sm gl-text-subtle"
|
||||
data-testid="auto-stop-time"
|
||||
>
|
||||
<gl-sprintf :message="$options.i18n.autoStopIn">
|
||||
<template #time>
|
||||
<time-ago-tooltip :time="environment.autoStopAt" css-class="gl-font-bold" />
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
</p>
|
||||
<div class="btn-group table-action-buttons" role="group">
|
||||
<div v-if="rolloutStatus" class="gl-w-full">
|
||||
<deploy-board-wrapper
|
||||
:rollout-status="rolloutStatus"
|
||||
:environment="environment"
|
||||
class="gl-mt-4 gl-pl-2"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="hasOpenedAlert" class="gl-w-full">
|
||||
<environment-alert :environment="environment" class="gl-mt-4 gl-pl-3 gl-pt-3" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="gl-flex gl-flex-grow gl-items-baseline gl-p-4">
|
||||
<strong class="gl-block gl-w-1/3 gl-flex-shrink-0 gl-pr-4 md:gl-w-1/4 lg:gl-hidden">{{
|
||||
$options.i18n.actions
|
||||
}}</strong>
|
||||
<div class="gl-ml-auto">
|
||||
<div class="btn-group" role="group">
|
||||
<external-url
|
||||
v-if="externalUrl"
|
||||
:external-url="externalUrl"
|
||||
|
|
@ -258,6 +247,7 @@ export default {
|
|||
icon="ellipsis_v"
|
||||
category="secondary"
|
||||
placement="bottom-end"
|
||||
size="small"
|
||||
:toggle-text="__('More actions')"
|
||||
>
|
||||
<rollback
|
||||
|
|
@ -294,57 +284,18 @@ export default {
|
|||
/>
|
||||
</gl-disclosure-dropdown>
|
||||
</div>
|
||||
<p
|
||||
v-if="canShowAutoStopDate"
|
||||
class="gl-mb-0 gl-mt-3 gl-text-sm gl-text-subtle"
|
||||
data-testid="auto-stop-time"
|
||||
>
|
||||
<gl-sprintf :message="$options.i18n.autoStopIn">
|
||||
<template #time>
|
||||
<time-ago-tooltip :time="environment.autoStopAt" css-class="gl-font-bold" />
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<gl-collapse :visible="visible">
|
||||
<template v-if="hasDeployment">
|
||||
<div v-if="lastDeployment" :class="$options.deploymentClasses">
|
||||
<deployment
|
||||
:deployment="lastDeployment"
|
||||
:visible="visible"
|
||||
:class="{ 'gl-ml-7': inFolder }"
|
||||
latest
|
||||
class="gl-pl-4"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-if="upcomingDeployment"
|
||||
:class="$options.deploymentClasses"
|
||||
data-testid="upcoming-deployment-content"
|
||||
>
|
||||
<deployment
|
||||
:deployment="upcomingDeployment"
|
||||
:visible="visible"
|
||||
:class="{ 'gl-ml-7': inFolder }"
|
||||
class="gl-pl-4"
|
||||
>
|
||||
<template #approval>
|
||||
<environment-approval
|
||||
:required-approval-count="environment.requiredApprovalCount"
|
||||
:deployment-web-path="upcomingDeployment.webPath"
|
||||
/>
|
||||
</template>
|
||||
</deployment>
|
||||
</div>
|
||||
</template>
|
||||
<div v-else :class="$options.deploymentClasses">
|
||||
<gl-sprintf :message="$options.i18n.emptyState">
|
||||
<template #link="{ content }">
|
||||
<gl-link :href="helpPagePath">{{ content }}</gl-link>
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
</div>
|
||||
<div v-if="rolloutStatus" :class="$options.deployBoardClasses">
|
||||
<deploy-board-wrapper
|
||||
:rollout-status="rolloutStatus"
|
||||
:environment="environment"
|
||||
:class="{ 'gl-ml-7': inFolder }"
|
||||
class="gl-pl-4"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="hasOpenedAlert" class="gl-bg-gray-10 md:gl-px-7">
|
||||
<environment-alert :environment="environment" class="gl-py-5 gl-pl-4" />
|
||||
</div>
|
||||
</gl-collapse>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ module Types
|
|||
graphql_name 'PackageBase'
|
||||
description 'Represents a package in the Package Registry'
|
||||
|
||||
PROTECTION_RULE_EXISTS_BATCH_SIZE = 20
|
||||
|
||||
connection_type_class Types::CountableConnectionType
|
||||
|
||||
authorize :read_package
|
||||
|
|
@ -39,12 +41,14 @@ module Types
|
|||
def protection_rule_exists
|
||||
object_package_type_value = ::Packages::Package.package_types[object.package_type]
|
||||
|
||||
BatchLoader::GraphQL.for([object.name, object_package_type_value]).batch do |inputs, loader|
|
||||
::Packages::Protection::Rule
|
||||
.for_push_exists_for_multiple_packages(
|
||||
package_names: inputs.map(&:first), package_types: inputs.map(&:last), project_id: object.project_id
|
||||
)
|
||||
.each { |row| loader.call([row['package_name'], row['package_type']], row['protected']) }
|
||||
BatchLoader::GraphQL.for([object.project_id, object.name, object_package_type_value]).batch do |tuples, loader|
|
||||
tuples.each_slice(PROTECTION_RULE_EXISTS_BATCH_SIZE) do |projects_and_packages|
|
||||
::Packages::Protection::Rule
|
||||
.for_push_exists_for_projects_and_packages(projects_and_packages)
|
||||
.each do |row|
|
||||
loader.call([row['project_id'], row['package_name'], row['package_type']], row['protected'])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,30 @@ class ApplicationSetting < ApplicationRecord
|
|||
encrypted_vertex_ai_access_token_iv
|
||||
], remove_with: '17.5', remove_after: '2024-09-19'
|
||||
|
||||
ignore_columns %i[
|
||||
elasticsearch_aws
|
||||
elasticsearch_search
|
||||
elasticsearch_indexing
|
||||
elasticsearch_username
|
||||
elasticsearch_aws_region
|
||||
elasticsearch_aws_access_key
|
||||
elasticsearch_limit_indexing
|
||||
elasticsearch_pause_indexing
|
||||
elasticsearch_requeue_workers
|
||||
elasticsearch_max_bulk_size_mb
|
||||
elasticsearch_retry_on_failure
|
||||
elasticsearch_max_bulk_concurrency
|
||||
elasticsearch_client_request_timeout
|
||||
elasticsearch_worker_number_of_shards
|
||||
elasticsearch_analyzers_smartcn_search
|
||||
elasticsearch_analyzers_kuromoji_search
|
||||
elasticsearch_analyzers_smartcn_enabled
|
||||
elasticsearch_analyzers_kuromoji_enabled
|
||||
elasticsearch_indexed_field_length_limit
|
||||
elasticsearch_indexed_file_size_limit_kb
|
||||
elasticsearch_max_code_indexing_concurrency
|
||||
], remove_with: '17.11', remove_after: '2025-04-17'
|
||||
|
||||
INSTANCE_REVIEW_MIN_USERS = 50
|
||||
GRAFANA_URL_ERROR_MESSAGE = 'Please check your Grafana URL setting in ' \
|
||||
'Admin area > Settings > Metrics and profiling > Metrics - Grafana'
|
||||
|
|
|
|||
|
|
@ -47,32 +47,65 @@ module Packages
|
|||
.exists?
|
||||
end
|
||||
|
||||
def self.for_push_exists_for_multiple_packages(package_names:, package_types:, project_id:)
|
||||
return none if package_names.blank? || package_types.blank? || project_id.blank?
|
||||
return none if package_names.size != package_types.size
|
||||
##
|
||||
# Accepts a list of projects and packages and returns a result set
|
||||
# indicating whether the package name is protected.
|
||||
#
|
||||
# @param [Array<Array>] projects_and_packages an array of arrays where each sub-array contains
|
||||
# the project id (bigint), the package name (string) and the package type (smallint).
|
||||
# @return [ActiveRecord::Result] a result set indicating whether each project, package name and package type
|
||||
# is protected.
|
||||
#
|
||||
# Example:
|
||||
# Packages::Protection::Rule.for_push_exists_for_projects_and_packages([
|
||||
# [1, '@my_group/my_project_1/package_1', 2],
|
||||
# [1, '@my_group/my_project_1/package_2', 2],
|
||||
# [2, '@my_group/my_project_2/package_1', 3],
|
||||
# ...
|
||||
# ])
|
||||
#
|
||||
# [
|
||||
# {'project_id' => 1, 'package_name' => '@my_group/my_project_1/package_1', 'package_type' => 2,
|
||||
# 'protected' => true},
|
||||
# {'project_id' => 1, 'package_name' => '@my_group/my_project_1/package_2', 'package_type' => 2,
|
||||
# 'protected' => false},
|
||||
# {'project_id' => 2, 'package_name' => '@my_group/my_project_2/package_1', 'package_type' => 3,
|
||||
# 'protected' => true},
|
||||
# ...
|
||||
# ]
|
||||
#
|
||||
def self.for_push_exists_for_projects_and_packages(projects_and_packages)
|
||||
return none if projects_and_packages.blank?
|
||||
|
||||
project_ids, package_names, package_types = projects_and_packages.transpose
|
||||
|
||||
cte_query_sql = <<~SQL
|
||||
unnest(
|
||||
ARRAY[:project_ids]::bigint[],
|
||||
ARRAY[:package_names]::text[],
|
||||
ARRAY[:package_types]::smallint[]
|
||||
) AS projects_and_packages(project_id, package_name, package_type)
|
||||
SQL
|
||||
|
||||
cte_query =
|
||||
select('*').from(
|
||||
sanitize_sql_array(
|
||||
[
|
||||
"unnest(ARRAY[:package_names], ARRAY[:package_types]) AS x(package_name, package_type)",
|
||||
{ package_names: package_names, package_types: package_types }
|
||||
]
|
||||
)
|
||||
)
|
||||
select('*').from(sanitize_sql_array(
|
||||
[cte_query_sql, { project_ids: project_ids, package_names: package_names, package_types: package_types }]
|
||||
))
|
||||
|
||||
cte_name = :package_names_and_types_cte
|
||||
cte_name = :projects_and_packages_cte
|
||||
cte = Gitlab::SQL::CTE.new(cte_name, cte_query)
|
||||
|
||||
rules_cte_package_type = "#{cte_name}.#{connection.quote_column_name('package_type')}"
|
||||
rules_cte_project_id = "#{cte_name}.#{connection.quote_column_name('project_id')}"
|
||||
rules_cte_package_name = "#{cte_name}.#{connection.quote_column_name('package_name')}"
|
||||
rules_cte_package_type = "#{cte_name}.#{connection.quote_column_name('package_type')}"
|
||||
|
||||
protection_rule_exsits_subquery = select(1)
|
||||
.where(project_id: project_id)
|
||||
.where("#{rules_cte_project_id} = project_id")
|
||||
.where(arel_table[:package_type].eq(Arel.sql(rules_cte_package_type)))
|
||||
.where("#{rules_cte_package_name} ILIKE #{::Gitlab::SQL::Glob.to_like('package_name_pattern')}")
|
||||
|
||||
query = select(
|
||||
rules_cte_project_id,
|
||||
rules_cte_package_type,
|
||||
rules_cte_package_name,
|
||||
sanitize_sql_array(['EXISTS(?) AS protected', protection_rule_exsits_subquery])
|
||||
|
|
|
|||
|
|
@ -7,9 +7,19 @@ module VirtualRegistries
|
|||
include FileStoreMounter
|
||||
include Gitlab::SQL::Pattern
|
||||
include ::UpdateNamespaceStatistics
|
||||
include ShaAttribute
|
||||
|
||||
self.table_name = 'virtual_registries_packages_maven_cache_entries'
|
||||
|
||||
# we're using a composite primary key: upstream_id, relative_path and status
|
||||
self.primary_key = :upstream_id
|
||||
query_constraints :upstream_id, :relative_path, :status
|
||||
|
||||
belongs_to :group
|
||||
belongs_to :upstream, class_name: 'VirtualRegistries::Packages::Maven::Upstream', inverse_of: :cached_responses
|
||||
belongs_to :upstream,
|
||||
class_name: 'VirtualRegistries::Packages::Maven::Upstream',
|
||||
inverse_of: :cached_responses,
|
||||
optional: false
|
||||
|
||||
alias_attribute :namespace, :group
|
||||
|
||||
|
|
@ -20,21 +30,22 @@ module VirtualRegistries
|
|||
|
||||
ignore_column :downloaded_at, remove_with: '17.9', remove_after: '2025-01-23'
|
||||
|
||||
sha_attribute :file_sha1
|
||||
sha_attribute :file_md5
|
||||
|
||||
validates :group, top_level_group: true, presence: true
|
||||
validates :relative_path,
|
||||
:object_storage_key,
|
||||
:size,
|
||||
:file_sha1,
|
||||
presence: true
|
||||
validates :relative_path,
|
||||
:object_storage_key,
|
||||
:upstream_etag,
|
||||
:content_type,
|
||||
length: { maximum: 255 }
|
||||
validates :file_final_path, length: { maximum: 1024 }
|
||||
validates :upstream_etag, :content_type, length: { maximum: 255 }
|
||||
validates :relative_path, :object_storage_key, :file_final_path, length: { maximum: 1024 }
|
||||
validates :file_md5, length: { is: 32 }, allow_nil: true
|
||||
validates :file_sha1, length: { is: 40 }
|
||||
validates :relative_path,
|
||||
uniqueness: { scope: [:upstream_id, :status] },
|
||||
if: -> { upstream.present? && default? }
|
||||
if: :default?
|
||||
validates :file, presence: true
|
||||
|
||||
mount_file_store_uploader ::VirtualRegistries::CachedResponseUploader
|
||||
|
|
@ -47,6 +58,7 @@ module VirtualRegistries
|
|||
fuzzy_search(query, [:relative_path], use_minimum_char_limit: false)
|
||||
end
|
||||
scope :for_group, ->(group) { where(group: group) }
|
||||
scope :order_created_desc, -> { reorder(arel_table['created_at'].desc) }
|
||||
|
||||
def self.next_pending_destruction
|
||||
pending_destruction.lock('FOR UPDATE SKIP LOCKED').take
|
||||
|
|
@ -85,6 +97,13 @@ module VirtualRegistries
|
|||
(upstream_checked_at + upstream.cache_validity_hours.hours).past?
|
||||
end
|
||||
|
||||
def mark_as_pending_destruction
|
||||
update_columns(
|
||||
status: :pending_destruction,
|
||||
relative_path: "#{relative_path}/deleted/#{SecureRandom.uuid}"
|
||||
)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_object_storage_key
|
||||
|
|
|
|||
|
|
@ -55,6 +55,10 @@ module VirtualRegistries
|
|||
{ Authorization: authorization }
|
||||
end
|
||||
|
||||
def default_cached_responses
|
||||
cached_responses.default
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def reset_credentials
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ module VirtualRegistries
|
|||
def cached_response
|
||||
# TODO change this to support multiple upstreams
|
||||
# https://gitlab.com/gitlab-org/gitlab/-/issues/480461
|
||||
registry.upstream.cached_responses.default.find_by_relative_path(relative_path)
|
||||
registry.upstream.default_cached_responses.find_by_relative_path(relative_path)
|
||||
end
|
||||
strong_memoize_attr :cached_response
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,10 @@
|
|||
- if merge_request_dashboard_enabled?(current_user)
|
||||
= gl_tabs_nav do
|
||||
= gl_tab_link_to new_lists_enabled ? _('Active') : _('Needs attention'), merge_requests_dashboard_path
|
||||
= gl_tab_link_to new_lists_enabled ? _('Merged') : _('Following'), merge_requests_following_dashboard_path
|
||||
- if new_lists_enabled
|
||||
= gl_tab_link_to _('Merged'), merge_requests_merged_dashboard_path
|
||||
- else
|
||||
= gl_tab_link_to _('Following'), merge_requests_following_dashboard_path
|
||||
= gl_tab_link_to _('Search'), merge_requests_search_dashboard_path, item_active: true
|
||||
|
||||
%div{ class: "#{'gl-bg-gray-10' if merge_request_dashboard_enabled?(current_user)}" }
|
||||
|
|
|
|||
|
|
@ -3,8 +3,7 @@
|
|||
class AutoMergeProcessWorker # rubocop:disable Scalability/IdempotentWorker
|
||||
include ApplicationWorker
|
||||
|
||||
data_consistency :sticky, feature_flag: :auto_merge_process_worker_sticky
|
||||
|
||||
data_consistency :sticky
|
||||
sidekiq_options retry: 3
|
||||
|
||||
# Avoid _simultaneous execution_ of this job for the same MR,
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
---
|
||||
name: auto_merge_process_worker_sticky
|
||||
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/483008
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/167234
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/496567
|
||||
milestone: '17.5'
|
||||
group: group::ci platform
|
||||
type: worker
|
||||
default_enabled: false
|
||||
|
|
@ -588,6 +588,17 @@ user_details:
|
|||
- table: namespaces
|
||||
column: enterprise_group_id
|
||||
on_delete: async_nullify
|
||||
virtual_registries_packages_maven_cache_entries:
|
||||
- table: virtual_registries_packages_maven_upstreams
|
||||
column: upstream_id
|
||||
on_delete: update_column_to
|
||||
target_column: status
|
||||
target_value: 2
|
||||
- table: namespaces
|
||||
column: group_id
|
||||
on_delete: update_column_to
|
||||
target_column: status
|
||||
target_value: 2
|
||||
virtual_registries_packages_maven_cached_responses:
|
||||
- table: virtual_registries_packages_maven_upstreams
|
||||
column: upstream_id
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
table_name: virtual_registries_packages_maven_cache_entries
|
||||
classes:
|
||||
- VirtualRegistries::Packages::Maven::CachedResponse
|
||||
feature_categories:
|
||||
- virtual_registry
|
||||
description: Cache entry for the Maven virtual packages registry. Mainly the body
|
||||
of a response of a Maven upstream. Contains references to an object storage file.
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/174985
|
||||
milestone: '17.8'
|
||||
gitlab_schema: gitlab_main_cell
|
||||
sharding_key:
|
||||
group_id: namespaces
|
||||
table_size: small
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class CreateVirtualRegistriesPackagesMavenCacheEntries < Gitlab::Database::Migration[2.2]
|
||||
include Gitlab::Database::PartitioningMigrationHelpers::TableManagementHelpers
|
||||
|
||||
milestone '17.8'
|
||||
|
||||
TABLE_NAME = :virtual_registries_packages_maven_cache_entries
|
||||
|
||||
def up
|
||||
create_table TABLE_NAME, if_not_exists: true, options: 'PARTITION BY HASH (relative_path)',
|
||||
primary_key: [:upstream_id, :relative_path, :status] do |t|
|
||||
t.bigint :group_id, null: false
|
||||
t.bigint :upstream_id, null: false
|
||||
t.datetime_with_timezone :upstream_checked_at, null: false, default: -> { 'NOW()' }
|
||||
t.timestamps_with_timezone null: false
|
||||
t.integer :file_store, null: false, default: 1
|
||||
t.integer :size, null: false
|
||||
t.integer :status, null: false, default: 0, limit: 2
|
||||
t.text :relative_path, null: false, limit: 1024
|
||||
t.text :file, null: false, limit: 1024
|
||||
t.text :object_storage_key, null: false, limit: 1024
|
||||
t.text :upstream_etag, limit: 255
|
||||
t.text :content_type, limit: 255, null: false, default: 'application/octet-stream'
|
||||
t.text :file_final_path, limit: 1024
|
||||
t.binary :file_md5
|
||||
t.binary :file_sha1, null: false
|
||||
|
||||
# for text search on relative path
|
||||
t.index :relative_path,
|
||||
using: :gin,
|
||||
opclass: :gin_trgm_ops,
|
||||
name: :idx_vreg_pkgs_maven_cache_entries_on_relative_path_trigram
|
||||
|
||||
# index on sharding key
|
||||
t.index %i[group_id status], name: :idx_vreg_pkgs_maven_cache_entries_on_group_id_status
|
||||
|
||||
# for cleanup jobs
|
||||
t.index [:upstream_id, :relative_path],
|
||||
name: :idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_relpath,
|
||||
where: 'status = 2' # status: :pending_destruction
|
||||
|
||||
# for ordered pagination
|
||||
t.index [:upstream_id, :created_at],
|
||||
name: :idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_created_at,
|
||||
where: 'status = 0' # status: :default
|
||||
end
|
||||
|
||||
create_hash_partitions(TABLE_NAME, 16)
|
||||
end
|
||||
|
||||
def down
|
||||
drop_table TABLE_NAME
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddCheckConstraintsToVirtualRegistriesPackagesMavenCacheEntries < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.8'
|
||||
disable_ddl_transaction!
|
||||
|
||||
TABLE_NAME = :virtual_registries_packages_maven_cache_entries
|
||||
|
||||
def up
|
||||
constraint = check_constraint_name(TABLE_NAME.to_s, 'file_md5', 'max_length')
|
||||
add_check_constraint(TABLE_NAME, 'file_md5 IS NULL OR octet_length(file_md5) = 16', constraint)
|
||||
|
||||
constraint = check_constraint_name(TABLE_NAME.to_s, 'file_sha1', 'max_length')
|
||||
add_check_constraint(TABLE_NAME, 'octet_length(file_sha1) = 20', constraint)
|
||||
end
|
||||
|
||||
def down
|
||||
constraint = check_constraint_name(TABLE_NAME.to_s, 'file_md5', 'max_length')
|
||||
remove_check_constraint(TABLE_NAME, constraint)
|
||||
|
||||
constraint = check_constraint_name(TABLE_NAME.to_s, 'file_sha1', 'max_length')
|
||||
remove_check_constraint(TABLE_NAME, constraint)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
c113f28c36ba46cc7d7abd6b2d309e6e7e07393a0e6287c80ba06774bbf64ead
|
||||
|
|
@ -0,0 +1 @@
|
|||
e4465f563d1f69938fe522d71db09d17ea79cf8ff3c964ceaeb5108455d81e52
|
||||
839
db/structure.sql
839
db/structure.sql
|
|
@ -5933,6 +5933,466 @@ CREATE TABLE gitlab_partitions_static.namespace_descendants_31 (
|
|||
calculated_at timestamp with time zone
|
||||
);
|
||||
|
||||
CREATE TABLE virtual_registries_packages_maven_cache_entries (
|
||||
group_id bigint NOT NULL,
|
||||
upstream_id bigint NOT NULL,
|
||||
upstream_checked_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
file_store integer DEFAULT 1 NOT NULL,
|
||||
size integer NOT NULL,
|
||||
status smallint DEFAULT 0 NOT NULL,
|
||||
relative_path text NOT NULL,
|
||||
file text NOT NULL,
|
||||
object_storage_key text NOT NULL,
|
||||
upstream_etag text,
|
||||
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
|
||||
file_final_path text,
|
||||
file_md5 bytea,
|
||||
file_sha1 bytea NOT NULL,
|
||||
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
|
||||
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
|
||||
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
|
||||
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
|
||||
CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
|
||||
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
|
||||
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
|
||||
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
|
||||
)
|
||||
PARTITION BY HASH (relative_path);
|
||||
|
||||
CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_00 (
|
||||
group_id bigint NOT NULL,
|
||||
upstream_id bigint NOT NULL,
|
||||
upstream_checked_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
file_store integer DEFAULT 1 NOT NULL,
|
||||
size integer NOT NULL,
|
||||
status smallint DEFAULT 0 NOT NULL,
|
||||
relative_path text NOT NULL,
|
||||
file text NOT NULL,
|
||||
object_storage_key text NOT NULL,
|
||||
upstream_etag text,
|
||||
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
|
||||
file_final_path text,
|
||||
file_md5 bytea,
|
||||
file_sha1 bytea NOT NULL,
|
||||
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
|
||||
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
|
||||
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
|
||||
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
|
||||
CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
|
||||
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
|
||||
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
|
||||
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
|
||||
);
|
||||
|
||||
CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_01 (
|
||||
group_id bigint NOT NULL,
|
||||
upstream_id bigint NOT NULL,
|
||||
upstream_checked_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
file_store integer DEFAULT 1 NOT NULL,
|
||||
size integer NOT NULL,
|
||||
status smallint DEFAULT 0 NOT NULL,
|
||||
relative_path text NOT NULL,
|
||||
file text NOT NULL,
|
||||
object_storage_key text NOT NULL,
|
||||
upstream_etag text,
|
||||
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
|
||||
file_final_path text,
|
||||
file_md5 bytea,
|
||||
file_sha1 bytea NOT NULL,
|
||||
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
|
||||
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
|
||||
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
|
||||
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
|
||||
CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
|
||||
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
|
||||
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
|
||||
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
|
||||
);
|
||||
|
||||
CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_02 (
|
||||
group_id bigint NOT NULL,
|
||||
upstream_id bigint NOT NULL,
|
||||
upstream_checked_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
file_store integer DEFAULT 1 NOT NULL,
|
||||
size integer NOT NULL,
|
||||
status smallint DEFAULT 0 NOT NULL,
|
||||
relative_path text NOT NULL,
|
||||
file text NOT NULL,
|
||||
object_storage_key text NOT NULL,
|
||||
upstream_etag text,
|
||||
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
|
||||
file_final_path text,
|
||||
file_md5 bytea,
|
||||
file_sha1 bytea NOT NULL,
|
||||
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
|
||||
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
|
||||
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
|
||||
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
|
||||
CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
|
||||
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
|
||||
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
|
||||
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
|
||||
);
|
||||
|
||||
CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_03 (
|
||||
group_id bigint NOT NULL,
|
||||
upstream_id bigint NOT NULL,
|
||||
upstream_checked_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
file_store integer DEFAULT 1 NOT NULL,
|
||||
size integer NOT NULL,
|
||||
status smallint DEFAULT 0 NOT NULL,
|
||||
relative_path text NOT NULL,
|
||||
file text NOT NULL,
|
||||
object_storage_key text NOT NULL,
|
||||
upstream_etag text,
|
||||
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
|
||||
file_final_path text,
|
||||
file_md5 bytea,
|
||||
file_sha1 bytea NOT NULL,
|
||||
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
|
||||
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
|
||||
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
|
||||
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
|
||||
CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
|
||||
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
|
||||
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
|
||||
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
|
||||
);
|
||||
|
||||
CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_04 (
|
||||
group_id bigint NOT NULL,
|
||||
upstream_id bigint NOT NULL,
|
||||
upstream_checked_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
file_store integer DEFAULT 1 NOT NULL,
|
||||
size integer NOT NULL,
|
||||
status smallint DEFAULT 0 NOT NULL,
|
||||
relative_path text NOT NULL,
|
||||
file text NOT NULL,
|
||||
object_storage_key text NOT NULL,
|
||||
upstream_etag text,
|
||||
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
|
||||
file_final_path text,
|
||||
file_md5 bytea,
|
||||
file_sha1 bytea NOT NULL,
|
||||
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
|
||||
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
|
||||
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
|
||||
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
|
||||
CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
|
||||
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
|
||||
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
|
||||
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
|
||||
);
|
||||
|
||||
CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_05 (
|
||||
group_id bigint NOT NULL,
|
||||
upstream_id bigint NOT NULL,
|
||||
upstream_checked_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
file_store integer DEFAULT 1 NOT NULL,
|
||||
size integer NOT NULL,
|
||||
status smallint DEFAULT 0 NOT NULL,
|
||||
relative_path text NOT NULL,
|
||||
file text NOT NULL,
|
||||
object_storage_key text NOT NULL,
|
||||
upstream_etag text,
|
||||
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
|
||||
file_final_path text,
|
||||
file_md5 bytea,
|
||||
file_sha1 bytea NOT NULL,
|
||||
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
|
||||
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
|
||||
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
|
||||
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
|
||||
CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
|
||||
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
|
||||
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
|
||||
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
|
||||
);
|
||||
|
||||
CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_06 (
|
||||
group_id bigint NOT NULL,
|
||||
upstream_id bigint NOT NULL,
|
||||
upstream_checked_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
file_store integer DEFAULT 1 NOT NULL,
|
||||
size integer NOT NULL,
|
||||
status smallint DEFAULT 0 NOT NULL,
|
||||
relative_path text NOT NULL,
|
||||
file text NOT NULL,
|
||||
object_storage_key text NOT NULL,
|
||||
upstream_etag text,
|
||||
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
|
||||
file_final_path text,
|
||||
file_md5 bytea,
|
||||
file_sha1 bytea NOT NULL,
|
||||
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
|
||||
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
|
||||
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
|
||||
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
|
||||
CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
|
||||
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
|
||||
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
|
||||
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
|
||||
);
|
||||
|
||||
CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_07 (
|
||||
group_id bigint NOT NULL,
|
||||
upstream_id bigint NOT NULL,
|
||||
upstream_checked_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
file_store integer DEFAULT 1 NOT NULL,
|
||||
size integer NOT NULL,
|
||||
status smallint DEFAULT 0 NOT NULL,
|
||||
relative_path text NOT NULL,
|
||||
file text NOT NULL,
|
||||
object_storage_key text NOT NULL,
|
||||
upstream_etag text,
|
||||
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
|
||||
file_final_path text,
|
||||
file_md5 bytea,
|
||||
file_sha1 bytea NOT NULL,
|
||||
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
|
||||
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
|
||||
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
|
||||
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
|
||||
CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
|
||||
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
|
||||
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
|
||||
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
|
||||
);
|
||||
|
||||
CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_08 (
|
||||
group_id bigint NOT NULL,
|
||||
upstream_id bigint NOT NULL,
|
||||
upstream_checked_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
file_store integer DEFAULT 1 NOT NULL,
|
||||
size integer NOT NULL,
|
||||
status smallint DEFAULT 0 NOT NULL,
|
||||
relative_path text NOT NULL,
|
||||
file text NOT NULL,
|
||||
object_storage_key text NOT NULL,
|
||||
upstream_etag text,
|
||||
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
|
||||
file_final_path text,
|
||||
file_md5 bytea,
|
||||
file_sha1 bytea NOT NULL,
|
||||
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
|
||||
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
|
||||
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
|
||||
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
|
||||
CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
|
||||
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
|
||||
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
|
||||
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
|
||||
);
|
||||
|
||||
CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_09 (
|
||||
group_id bigint NOT NULL,
|
||||
upstream_id bigint NOT NULL,
|
||||
upstream_checked_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
file_store integer DEFAULT 1 NOT NULL,
|
||||
size integer NOT NULL,
|
||||
status smallint DEFAULT 0 NOT NULL,
|
||||
relative_path text NOT NULL,
|
||||
file text NOT NULL,
|
||||
object_storage_key text NOT NULL,
|
||||
upstream_etag text,
|
||||
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
|
||||
file_final_path text,
|
||||
file_md5 bytea,
|
||||
file_sha1 bytea NOT NULL,
|
||||
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
|
||||
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
|
||||
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
|
||||
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
|
||||
CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
|
||||
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
|
||||
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
|
||||
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
|
||||
);
|
||||
|
||||
CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_10 (
|
||||
group_id bigint NOT NULL,
|
||||
upstream_id bigint NOT NULL,
|
||||
upstream_checked_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
file_store integer DEFAULT 1 NOT NULL,
|
||||
size integer NOT NULL,
|
||||
status smallint DEFAULT 0 NOT NULL,
|
||||
relative_path text NOT NULL,
|
||||
file text NOT NULL,
|
||||
object_storage_key text NOT NULL,
|
||||
upstream_etag text,
|
||||
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
|
||||
file_final_path text,
|
||||
file_md5 bytea,
|
||||
file_sha1 bytea NOT NULL,
|
||||
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
|
||||
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
|
||||
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
|
||||
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
|
||||
CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
|
||||
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
|
||||
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
|
||||
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
|
||||
);
|
||||
|
||||
CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_11 (
|
||||
group_id bigint NOT NULL,
|
||||
upstream_id bigint NOT NULL,
|
||||
upstream_checked_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
file_store integer DEFAULT 1 NOT NULL,
|
||||
size integer NOT NULL,
|
||||
status smallint DEFAULT 0 NOT NULL,
|
||||
relative_path text NOT NULL,
|
||||
file text NOT NULL,
|
||||
object_storage_key text NOT NULL,
|
||||
upstream_etag text,
|
||||
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
|
||||
file_final_path text,
|
||||
file_md5 bytea,
|
||||
file_sha1 bytea NOT NULL,
|
||||
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
|
||||
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
|
||||
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
|
||||
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
|
||||
CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
|
||||
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
|
||||
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
|
||||
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
|
||||
);
|
||||
|
||||
CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_12 (
|
||||
group_id bigint NOT NULL,
|
||||
upstream_id bigint NOT NULL,
|
||||
upstream_checked_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
file_store integer DEFAULT 1 NOT NULL,
|
||||
size integer NOT NULL,
|
||||
status smallint DEFAULT 0 NOT NULL,
|
||||
relative_path text NOT NULL,
|
||||
file text NOT NULL,
|
||||
object_storage_key text NOT NULL,
|
||||
upstream_etag text,
|
||||
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
|
||||
file_final_path text,
|
||||
file_md5 bytea,
|
||||
file_sha1 bytea NOT NULL,
|
||||
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
|
||||
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
|
||||
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
|
||||
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
|
||||
CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
|
||||
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
|
||||
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
|
||||
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
|
||||
);
|
||||
|
||||
CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_13 (
|
||||
group_id bigint NOT NULL,
|
||||
upstream_id bigint NOT NULL,
|
||||
upstream_checked_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
file_store integer DEFAULT 1 NOT NULL,
|
||||
size integer NOT NULL,
|
||||
status smallint DEFAULT 0 NOT NULL,
|
||||
relative_path text NOT NULL,
|
||||
file text NOT NULL,
|
||||
object_storage_key text NOT NULL,
|
||||
upstream_etag text,
|
||||
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
|
||||
file_final_path text,
|
||||
file_md5 bytea,
|
||||
file_sha1 bytea NOT NULL,
|
||||
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
|
||||
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
|
||||
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
|
||||
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
|
||||
CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
|
||||
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
|
||||
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
|
||||
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
|
||||
);
|
||||
|
||||
CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_14 (
|
||||
group_id bigint NOT NULL,
|
||||
upstream_id bigint NOT NULL,
|
||||
upstream_checked_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
file_store integer DEFAULT 1 NOT NULL,
|
||||
size integer NOT NULL,
|
||||
status smallint DEFAULT 0 NOT NULL,
|
||||
relative_path text NOT NULL,
|
||||
file text NOT NULL,
|
||||
object_storage_key text NOT NULL,
|
||||
upstream_etag text,
|
||||
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
|
||||
file_final_path text,
|
||||
file_md5 bytea,
|
||||
file_sha1 bytea NOT NULL,
|
||||
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
|
||||
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
|
||||
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
|
||||
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
|
||||
CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
|
||||
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
|
||||
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
|
||||
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
|
||||
);
|
||||
|
||||
CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_15 (
|
||||
group_id bigint NOT NULL,
|
||||
upstream_id bigint NOT NULL,
|
||||
upstream_checked_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
file_store integer DEFAULT 1 NOT NULL,
|
||||
size integer NOT NULL,
|
||||
status smallint DEFAULT 0 NOT NULL,
|
||||
relative_path text NOT NULL,
|
||||
file text NOT NULL,
|
||||
object_storage_key text NOT NULL,
|
||||
upstream_etag text,
|
||||
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
|
||||
file_final_path text,
|
||||
file_md5 bytea,
|
||||
file_sha1 bytea NOT NULL,
|
||||
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
|
||||
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
|
||||
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
|
||||
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
|
||||
CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
|
||||
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
|
||||
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
|
||||
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
|
||||
);
|
||||
|
||||
CREATE TABLE abuse_events (
|
||||
id bigint NOT NULL,
|
||||
user_id bigint,
|
||||
|
|
@ -23460,6 +23920,38 @@ ALTER TABLE ONLY namespace_descendants ATTACH PARTITION gitlab_partitions_static
|
|||
|
||||
ALTER TABLE ONLY namespace_descendants ATTACH PARTITION gitlab_partitions_static.namespace_descendants_31 FOR VALUES WITH (modulus 32, remainder 31);
|
||||
|
||||
ALTER TABLE ONLY virtual_registries_packages_maven_cache_entries ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_00 FOR VALUES WITH (modulus 16, remainder 0);
|
||||
|
||||
ALTER TABLE ONLY virtual_registries_packages_maven_cache_entries ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_01 FOR VALUES WITH (modulus 16, remainder 1);
|
||||
|
||||
ALTER TABLE ONLY virtual_registries_packages_maven_cache_entries ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_02 FOR VALUES WITH (modulus 16, remainder 2);
|
||||
|
||||
ALTER TABLE ONLY virtual_registries_packages_maven_cache_entries ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_03 FOR VALUES WITH (modulus 16, remainder 3);
|
||||
|
||||
ALTER TABLE ONLY virtual_registries_packages_maven_cache_entries ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_04 FOR VALUES WITH (modulus 16, remainder 4);
|
||||
|
||||
ALTER TABLE ONLY virtual_registries_packages_maven_cache_entries ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_05 FOR VALUES WITH (modulus 16, remainder 5);
|
||||
|
||||
ALTER TABLE ONLY virtual_registries_packages_maven_cache_entries ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_06 FOR VALUES WITH (modulus 16, remainder 6);
|
||||
|
||||
ALTER TABLE ONLY virtual_registries_packages_maven_cache_entries ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_07 FOR VALUES WITH (modulus 16, remainder 7);
|
||||
|
||||
ALTER TABLE ONLY virtual_registries_packages_maven_cache_entries ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_08 FOR VALUES WITH (modulus 16, remainder 8);
|
||||
|
||||
ALTER TABLE ONLY virtual_registries_packages_maven_cache_entries ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_09 FOR VALUES WITH (modulus 16, remainder 9);
|
||||
|
||||
ALTER TABLE ONLY virtual_registries_packages_maven_cache_entries ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_10 FOR VALUES WITH (modulus 16, remainder 10);
|
||||
|
||||
ALTER TABLE ONLY virtual_registries_packages_maven_cache_entries ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_11 FOR VALUES WITH (modulus 16, remainder 11);
|
||||
|
||||
ALTER TABLE ONLY virtual_registries_packages_maven_cache_entries ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_12 FOR VALUES WITH (modulus 16, remainder 12);
|
||||
|
||||
ALTER TABLE ONLY virtual_registries_packages_maven_cache_entries ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_13 FOR VALUES WITH (modulus 16, remainder 13);
|
||||
|
||||
ALTER TABLE ONLY virtual_registries_packages_maven_cache_entries ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_14 FOR VALUES WITH (modulus 16, remainder 14);
|
||||
|
||||
ALTER TABLE ONLY virtual_registries_packages_maven_cache_entries ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_15 FOR VALUES WITH (modulus 16, remainder 15);
|
||||
|
||||
ALTER TABLE ONLY p_ci_builds ATTACH PARTITION ci_builds FOR VALUES IN ('100');
|
||||
|
||||
ALTER TABLE ONLY p_ci_builds_metadata ATTACH PARTITION ci_builds_metadata FOR VALUES IN ('100');
|
||||
|
|
@ -25314,6 +25806,57 @@ ALTER TABLE ONLY gitlab_partitions_static.namespace_descendants_30
|
|||
ALTER TABLE ONLY gitlab_partitions_static.namespace_descendants_31
|
||||
ADD CONSTRAINT namespace_descendants_31_pkey PRIMARY KEY (namespace_id);
|
||||
|
||||
ALTER TABLE ONLY virtual_registries_packages_maven_cache_entries
|
||||
ADD CONSTRAINT virtual_registries_packages_maven_cache_entries_pkey PRIMARY KEY (upstream_id, relative_path, status);
|
||||
|
||||
ALTER TABLE ONLY gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_00
|
||||
ADD CONSTRAINT virtual_registries_packages_maven_cache_entries_00_pkey PRIMARY KEY (upstream_id, relative_path, status);
|
||||
|
||||
ALTER TABLE ONLY gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_01
|
||||
ADD CONSTRAINT virtual_registries_packages_maven_cache_entries_01_pkey PRIMARY KEY (upstream_id, relative_path, status);
|
||||
|
||||
ALTER TABLE ONLY gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_02
|
||||
ADD CONSTRAINT virtual_registries_packages_maven_cache_entries_02_pkey PRIMARY KEY (upstream_id, relative_path, status);
|
||||
|
||||
ALTER TABLE ONLY gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_03
|
||||
ADD CONSTRAINT virtual_registries_packages_maven_cache_entries_03_pkey PRIMARY KEY (upstream_id, relative_path, status);
|
||||
|
||||
ALTER TABLE ONLY gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_04
|
||||
ADD CONSTRAINT virtual_registries_packages_maven_cache_entries_04_pkey PRIMARY KEY (upstream_id, relative_path, status);
|
||||
|
||||
ALTER TABLE ONLY gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_05
|
||||
ADD CONSTRAINT virtual_registries_packages_maven_cache_entries_05_pkey PRIMARY KEY (upstream_id, relative_path, status);
|
||||
|
||||
ALTER TABLE ONLY gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_06
|
||||
ADD CONSTRAINT virtual_registries_packages_maven_cache_entries_06_pkey PRIMARY KEY (upstream_id, relative_path, status);
|
||||
|
||||
ALTER TABLE ONLY gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_07
|
||||
ADD CONSTRAINT virtual_registries_packages_maven_cache_entries_07_pkey PRIMARY KEY (upstream_id, relative_path, status);
|
||||
|
||||
ALTER TABLE ONLY gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_08
|
||||
ADD CONSTRAINT virtual_registries_packages_maven_cache_entries_08_pkey PRIMARY KEY (upstream_id, relative_path, status);
|
||||
|
||||
ALTER TABLE ONLY gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_09
|
||||
ADD CONSTRAINT virtual_registries_packages_maven_cache_entries_09_pkey PRIMARY KEY (upstream_id, relative_path, status);
|
||||
|
||||
ALTER TABLE ONLY gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_10
|
||||
ADD CONSTRAINT virtual_registries_packages_maven_cache_entries_10_pkey PRIMARY KEY (upstream_id, relative_path, status);
|
||||
|
||||
ALTER TABLE ONLY gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_11
|
||||
ADD CONSTRAINT virtual_registries_packages_maven_cache_entries_11_pkey PRIMARY KEY (upstream_id, relative_path, status);
|
||||
|
||||
ALTER TABLE ONLY gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_12
|
||||
ADD CONSTRAINT virtual_registries_packages_maven_cache_entries_12_pkey PRIMARY KEY (upstream_id, relative_path, status);
|
||||
|
||||
ALTER TABLE ONLY gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_13
|
||||
ADD CONSTRAINT virtual_registries_packages_maven_cache_entries_13_pkey PRIMARY KEY (upstream_id, relative_path, status);
|
||||
|
||||
ALTER TABLE ONLY gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_14
|
||||
ADD CONSTRAINT virtual_registries_packages_maven_cache_entries_14_pkey PRIMARY KEY (upstream_id, relative_path, status);
|
||||
|
||||
ALTER TABLE ONLY gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_15
|
||||
ADD CONSTRAINT virtual_registries_packages_maven_cache_entries_15_pkey PRIMARY KEY (upstream_id, relative_path, status);
|
||||
|
||||
ALTER TABLE ONLY abuse_events
|
||||
ADD CONSTRAINT abuse_events_pkey PRIMARY KEY (id);
|
||||
|
||||
|
|
@ -28887,6 +29430,142 @@ CREATE INDEX namespace_descendants_30_namespace_id_idx ON gitlab_partitions_stat
|
|||
|
||||
CREATE INDEX namespace_descendants_31_namespace_id_idx ON gitlab_partitions_static.namespace_descendants_31 USING btree (namespace_id) WHERE (outdated_at IS NOT NULL);
|
||||
|
||||
CREATE INDEX idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_relpath ON ONLY virtual_registries_packages_maven_cache_entries USING btree (upstream_id, relative_path) WHERE (status = 2);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_mav_upstream_id_relative_path_idx10 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_10 USING btree (upstream_id, relative_path) WHERE (status = 2);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_mav_upstream_id_relative_path_idx11 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_11 USING btree (upstream_id, relative_path) WHERE (status = 2);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_mav_upstream_id_relative_path_idx12 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_12 USING btree (upstream_id, relative_path) WHERE (status = 2);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_mav_upstream_id_relative_path_idx13 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_13 USING btree (upstream_id, relative_path) WHERE (status = 2);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_mav_upstream_id_relative_path_idx14 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_14 USING btree (upstream_id, relative_path) WHERE (status = 2);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_mav_upstream_id_relative_path_idx15 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_15 USING btree (upstream_id, relative_path) WHERE (status = 2);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_mave_upstream_id_relative_path_idx1 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_01 USING btree (upstream_id, relative_path) WHERE (status = 2);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_mave_upstream_id_relative_path_idx2 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_02 USING btree (upstream_id, relative_path) WHERE (status = 2);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_mave_upstream_id_relative_path_idx3 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_03 USING btree (upstream_id, relative_path) WHERE (status = 2);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_mave_upstream_id_relative_path_idx4 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_04 USING btree (upstream_id, relative_path) WHERE (status = 2);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_mave_upstream_id_relative_path_idx5 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_05 USING btree (upstream_id, relative_path) WHERE (status = 2);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_mave_upstream_id_relative_path_idx6 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_06 USING btree (upstream_id, relative_path) WHERE (status = 2);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_mave_upstream_id_relative_path_idx7 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_07 USING btree (upstream_id, relative_path) WHERE (status = 2);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_mave_upstream_id_relative_path_idx8 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_08 USING btree (upstream_id, relative_path) WHERE (status = 2);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_mave_upstream_id_relative_path_idx9 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_09 USING btree (upstream_id, relative_path) WHERE (status = 2);
|
||||
|
||||
CREATE INDEX idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_created_at ON ONLY virtual_registries_packages_maven_cache_entries USING btree (upstream_id, created_at) WHERE (status = 0);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven__upstream_id_created_at_idx10 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_10 USING btree (upstream_id, created_at) WHERE (status = 0);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven__upstream_id_created_at_idx11 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_11 USING btree (upstream_id, created_at) WHERE (status = 0);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven__upstream_id_created_at_idx12 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_12 USING btree (upstream_id, created_at) WHERE (status = 0);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven__upstream_id_created_at_idx13 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_13 USING btree (upstream_id, created_at) WHERE (status = 0);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven__upstream_id_created_at_idx14 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_14 USING btree (upstream_id, created_at) WHERE (status = 0);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven__upstream_id_created_at_idx15 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_15 USING btree (upstream_id, created_at) WHERE (status = 0);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_c_upstream_id_created_at_idx1 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_01 USING btree (upstream_id, created_at) WHERE (status = 0);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_c_upstream_id_created_at_idx2 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_02 USING btree (upstream_id, created_at) WHERE (status = 0);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_c_upstream_id_created_at_idx3 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_03 USING btree (upstream_id, created_at) WHERE (status = 0);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_c_upstream_id_created_at_idx4 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_04 USING btree (upstream_id, created_at) WHERE (status = 0);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_c_upstream_id_created_at_idx5 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_05 USING btree (upstream_id, created_at) WHERE (status = 0);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_c_upstream_id_created_at_idx6 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_06 USING btree (upstream_id, created_at) WHERE (status = 0);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_c_upstream_id_created_at_idx7 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_07 USING btree (upstream_id, created_at) WHERE (status = 0);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_c_upstream_id_created_at_idx8 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_08 USING btree (upstream_id, created_at) WHERE (status = 0);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_c_upstream_id_created_at_idx9 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_09 USING btree (upstream_id, created_at) WHERE (status = 0);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_ca_upstream_id_created_at_idx ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_00 USING btree (upstream_id, created_at) WHERE (status = 0);
|
||||
|
||||
CREATE INDEX idx_vreg_pkgs_maven_cache_entries_on_group_id_status ON ONLY virtual_registries_packages_maven_cache_entries USING btree (group_id, status);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_cache_e_group_id_status_idx10 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_10 USING btree (group_id, status);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_cache_e_group_id_status_idx11 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_11 USING btree (group_id, status);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_cache_e_group_id_status_idx12 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_12 USING btree (group_id, status);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_cache_e_group_id_status_idx13 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_13 USING btree (group_id, status);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_cache_e_group_id_status_idx14 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_14 USING btree (group_id, status);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_cache_e_group_id_status_idx15 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_15 USING btree (group_id, status);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_cache_en_group_id_status_idx1 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_01 USING btree (group_id, status);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_cache_en_group_id_status_idx2 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_02 USING btree (group_id, status);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_cache_en_group_id_status_idx3 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_03 USING btree (group_id, status);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_cache_en_group_id_status_idx4 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_04 USING btree (group_id, status);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_cache_en_group_id_status_idx5 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_05 USING btree (group_id, status);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_cache_en_group_id_status_idx6 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_06 USING btree (group_id, status);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_cache_en_group_id_status_idx7 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_07 USING btree (group_id, status);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_cache_en_group_id_status_idx8 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_08 USING btree (group_id, status);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_cache_en_group_id_status_idx9 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_09 USING btree (group_id, status);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_cache_ent_group_id_status_idx ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_00 USING btree (group_id, status);
|
||||
|
||||
CREATE INDEX idx_vreg_pkgs_maven_cache_entries_on_relative_path_trigram ON ONLY virtual_registries_packages_maven_cache_entries USING gin (relative_path gin_trgm_ops);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_cache_ent_relative_path_idx10 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_10 USING gin (relative_path gin_trgm_ops);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_cache_ent_relative_path_idx11 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_11 USING gin (relative_path gin_trgm_ops);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_cache_ent_relative_path_idx12 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_12 USING gin (relative_path gin_trgm_ops);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_cache_ent_relative_path_idx13 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_13 USING gin (relative_path gin_trgm_ops);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_cache_ent_relative_path_idx14 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_14 USING gin (relative_path gin_trgm_ops);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_cache_ent_relative_path_idx15 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_15 USING gin (relative_path gin_trgm_ops);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_cache_entr_relative_path_idx1 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_01 USING gin (relative_path gin_trgm_ops);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_cache_entr_relative_path_idx2 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_02 USING gin (relative_path gin_trgm_ops);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_cache_entr_relative_path_idx3 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_03 USING gin (relative_path gin_trgm_ops);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_cache_entr_relative_path_idx4 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_04 USING gin (relative_path gin_trgm_ops);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_cache_entr_relative_path_idx5 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_05 USING gin (relative_path gin_trgm_ops);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_cache_entr_relative_path_idx6 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_06 USING gin (relative_path gin_trgm_ops);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_cache_entr_relative_path_idx7 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_07 USING gin (relative_path gin_trgm_ops);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_cache_entr_relative_path_idx8 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_08 USING gin (relative_path gin_trgm_ops);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_cache_entr_relative_path_idx9 ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_09 USING gin (relative_path gin_trgm_ops);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_cache_entri_relative_path_idx ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_00 USING gin (relative_path gin_trgm_ops);
|
||||
|
||||
CREATE INDEX virtual_registries_packages_maven_upstream_id_relative_path_idx ON gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_00 USING btree (upstream_id, relative_path) WHERE (status = 2);
|
||||
|
||||
CREATE INDEX analytics_index_audit_events_part_on_created_at_and_author_id ON ONLY audit_events USING btree (created_at, author_id);
|
||||
|
||||
CREATE INDEX analytics_index_events_on_created_at_and_author_id ON events USING btree (created_at, author_id);
|
||||
|
|
@ -35637,6 +36316,166 @@ ALTER INDEX index_on_namespace_descendants_outdated ATTACH PARTITION gitlab_part
|
|||
|
||||
ALTER INDEX namespace_descendants_pkey ATTACH PARTITION gitlab_partitions_static.namespace_descendants_31_pkey;
|
||||
|
||||
ALTER INDEX idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_relpath ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_mav_upstream_id_relative_path_idx10;
|
||||
|
||||
ALTER INDEX idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_relpath ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_mav_upstream_id_relative_path_idx11;
|
||||
|
||||
ALTER INDEX idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_relpath ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_mav_upstream_id_relative_path_idx12;
|
||||
|
||||
ALTER INDEX idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_relpath ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_mav_upstream_id_relative_path_idx13;
|
||||
|
||||
ALTER INDEX idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_relpath ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_mav_upstream_id_relative_path_idx14;
|
||||
|
||||
ALTER INDEX idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_relpath ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_mav_upstream_id_relative_path_idx15;
|
||||
|
||||
ALTER INDEX idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_relpath ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_mave_upstream_id_relative_path_idx1;
|
||||
|
||||
ALTER INDEX idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_relpath ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_mave_upstream_id_relative_path_idx2;
|
||||
|
||||
ALTER INDEX idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_relpath ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_mave_upstream_id_relative_path_idx3;
|
||||
|
||||
ALTER INDEX idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_relpath ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_mave_upstream_id_relative_path_idx4;
|
||||
|
||||
ALTER INDEX idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_relpath ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_mave_upstream_id_relative_path_idx5;
|
||||
|
||||
ALTER INDEX idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_relpath ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_mave_upstream_id_relative_path_idx6;
|
||||
|
||||
ALTER INDEX idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_relpath ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_mave_upstream_id_relative_path_idx7;
|
||||
|
||||
ALTER INDEX idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_relpath ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_mave_upstream_id_relative_path_idx8;
|
||||
|
||||
ALTER INDEX idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_relpath ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_mave_upstream_id_relative_path_idx9;
|
||||
|
||||
ALTER INDEX idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_created_at ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven__upstream_id_created_at_idx10;
|
||||
|
||||
ALTER INDEX idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_created_at ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven__upstream_id_created_at_idx11;
|
||||
|
||||
ALTER INDEX idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_created_at ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven__upstream_id_created_at_idx12;
|
||||
|
||||
ALTER INDEX idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_created_at ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven__upstream_id_created_at_idx13;
|
||||
|
||||
ALTER INDEX idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_created_at ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven__upstream_id_created_at_idx14;
|
||||
|
||||
ALTER INDEX idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_created_at ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven__upstream_id_created_at_idx15;
|
||||
|
||||
ALTER INDEX idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_created_at ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_c_upstream_id_created_at_idx1;
|
||||
|
||||
ALTER INDEX idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_created_at ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_c_upstream_id_created_at_idx2;
|
||||
|
||||
ALTER INDEX idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_created_at ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_c_upstream_id_created_at_idx3;
|
||||
|
||||
ALTER INDEX idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_created_at ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_c_upstream_id_created_at_idx4;
|
||||
|
||||
ALTER INDEX idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_created_at ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_c_upstream_id_created_at_idx5;
|
||||
|
||||
ALTER INDEX idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_created_at ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_c_upstream_id_created_at_idx6;
|
||||
|
||||
ALTER INDEX idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_created_at ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_c_upstream_id_created_at_idx7;
|
||||
|
||||
ALTER INDEX idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_created_at ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_c_upstream_id_created_at_idx8;
|
||||
|
||||
ALTER INDEX idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_created_at ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_c_upstream_id_created_at_idx9;
|
||||
|
||||
ALTER INDEX idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_created_at ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_ca_upstream_id_created_at_idx;
|
||||
|
||||
ALTER INDEX idx_vreg_pkgs_maven_cache_entries_on_group_id_status ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_e_group_id_status_idx10;
|
||||
|
||||
ALTER INDEX idx_vreg_pkgs_maven_cache_entries_on_group_id_status ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_e_group_id_status_idx11;
|
||||
|
||||
ALTER INDEX idx_vreg_pkgs_maven_cache_entries_on_group_id_status ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_e_group_id_status_idx12;
|
||||
|
||||
ALTER INDEX idx_vreg_pkgs_maven_cache_entries_on_group_id_status ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_e_group_id_status_idx13;
|
||||
|
||||
ALTER INDEX idx_vreg_pkgs_maven_cache_entries_on_group_id_status ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_e_group_id_status_idx14;
|
||||
|
||||
ALTER INDEX idx_vreg_pkgs_maven_cache_entries_on_group_id_status ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_e_group_id_status_idx15;
|
||||
|
||||
ALTER INDEX idx_vreg_pkgs_maven_cache_entries_on_group_id_status ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_en_group_id_status_idx1;
|
||||
|
||||
ALTER INDEX idx_vreg_pkgs_maven_cache_entries_on_group_id_status ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_en_group_id_status_idx2;
|
||||
|
||||
ALTER INDEX idx_vreg_pkgs_maven_cache_entries_on_group_id_status ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_en_group_id_status_idx3;
|
||||
|
||||
ALTER INDEX idx_vreg_pkgs_maven_cache_entries_on_group_id_status ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_en_group_id_status_idx4;
|
||||
|
||||
ALTER INDEX idx_vreg_pkgs_maven_cache_entries_on_group_id_status ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_en_group_id_status_idx5;
|
||||
|
||||
ALTER INDEX idx_vreg_pkgs_maven_cache_entries_on_group_id_status ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_en_group_id_status_idx6;
|
||||
|
||||
ALTER INDEX idx_vreg_pkgs_maven_cache_entries_on_group_id_status ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_en_group_id_status_idx7;
|
||||
|
||||
ALTER INDEX idx_vreg_pkgs_maven_cache_entries_on_group_id_status ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_en_group_id_status_idx8;
|
||||
|
||||
ALTER INDEX idx_vreg_pkgs_maven_cache_entries_on_group_id_status ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_en_group_id_status_idx9;
|
||||
|
||||
ALTER INDEX idx_vreg_pkgs_maven_cache_entries_on_group_id_status ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_ent_group_id_status_idx;
|
||||
|
||||
ALTER INDEX idx_vreg_pkgs_maven_cache_entries_on_relative_path_trigram ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_ent_relative_path_idx10;
|
||||
|
||||
ALTER INDEX idx_vreg_pkgs_maven_cache_entries_on_relative_path_trigram ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_ent_relative_path_idx11;
|
||||
|
||||
ALTER INDEX idx_vreg_pkgs_maven_cache_entries_on_relative_path_trigram ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_ent_relative_path_idx12;
|
||||
|
||||
ALTER INDEX idx_vreg_pkgs_maven_cache_entries_on_relative_path_trigram ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_ent_relative_path_idx13;
|
||||
|
||||
ALTER INDEX idx_vreg_pkgs_maven_cache_entries_on_relative_path_trigram ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_ent_relative_path_idx14;
|
||||
|
||||
ALTER INDEX idx_vreg_pkgs_maven_cache_entries_on_relative_path_trigram ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_ent_relative_path_idx15;
|
||||
|
||||
ALTER INDEX idx_vreg_pkgs_maven_cache_entries_on_relative_path_trigram ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entr_relative_path_idx1;
|
||||
|
||||
ALTER INDEX idx_vreg_pkgs_maven_cache_entries_on_relative_path_trigram ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entr_relative_path_idx2;
|
||||
|
||||
ALTER INDEX idx_vreg_pkgs_maven_cache_entries_on_relative_path_trigram ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entr_relative_path_idx3;
|
||||
|
||||
ALTER INDEX idx_vreg_pkgs_maven_cache_entries_on_relative_path_trigram ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entr_relative_path_idx4;
|
||||
|
||||
ALTER INDEX idx_vreg_pkgs_maven_cache_entries_on_relative_path_trigram ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entr_relative_path_idx5;
|
||||
|
||||
ALTER INDEX idx_vreg_pkgs_maven_cache_entries_on_relative_path_trigram ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entr_relative_path_idx6;
|
||||
|
||||
ALTER INDEX idx_vreg_pkgs_maven_cache_entries_on_relative_path_trigram ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entr_relative_path_idx7;
|
||||
|
||||
ALTER INDEX idx_vreg_pkgs_maven_cache_entries_on_relative_path_trigram ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entr_relative_path_idx8;
|
||||
|
||||
ALTER INDEX idx_vreg_pkgs_maven_cache_entries_on_relative_path_trigram ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entr_relative_path_idx9;
|
||||
|
||||
ALTER INDEX idx_vreg_pkgs_maven_cache_entries_on_relative_path_trigram ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entri_relative_path_idx;
|
||||
|
||||
ALTER INDEX virtual_registries_packages_maven_cache_entries_pkey ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_00_pkey;
|
||||
|
||||
ALTER INDEX virtual_registries_packages_maven_cache_entries_pkey ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_01_pkey;
|
||||
|
||||
ALTER INDEX virtual_registries_packages_maven_cache_entries_pkey ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_02_pkey;
|
||||
|
||||
ALTER INDEX virtual_registries_packages_maven_cache_entries_pkey ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_03_pkey;
|
||||
|
||||
ALTER INDEX virtual_registries_packages_maven_cache_entries_pkey ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_04_pkey;
|
||||
|
||||
ALTER INDEX virtual_registries_packages_maven_cache_entries_pkey ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_05_pkey;
|
||||
|
||||
ALTER INDEX virtual_registries_packages_maven_cache_entries_pkey ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_06_pkey;
|
||||
|
||||
ALTER INDEX virtual_registries_packages_maven_cache_entries_pkey ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_07_pkey;
|
||||
|
||||
ALTER INDEX virtual_registries_packages_maven_cache_entries_pkey ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_08_pkey;
|
||||
|
||||
ALTER INDEX virtual_registries_packages_maven_cache_entries_pkey ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_09_pkey;
|
||||
|
||||
ALTER INDEX virtual_registries_packages_maven_cache_entries_pkey ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_10_pkey;
|
||||
|
||||
ALTER INDEX virtual_registries_packages_maven_cache_entries_pkey ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_11_pkey;
|
||||
|
||||
ALTER INDEX virtual_registries_packages_maven_cache_entries_pkey ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_12_pkey;
|
||||
|
||||
ALTER INDEX virtual_registries_packages_maven_cache_entries_pkey ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_13_pkey;
|
||||
|
||||
ALTER INDEX virtual_registries_packages_maven_cache_entries_pkey ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_14_pkey;
|
||||
|
||||
ALTER INDEX virtual_registries_packages_maven_cache_entries_pkey ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_cache_entries_15_pkey;
|
||||
|
||||
ALTER INDEX idx_vregs_pkgs_mvn_cache_entries_on_pending_upt_id_relpath ATTACH PARTITION gitlab_partitions_static.virtual_registries_packages_maven_upstream_id_relative_path_idx;
|
||||
|
||||
ALTER INDEX p_ci_builds_status_created_at_project_id_idx ATTACH PARTITION ci_builds_gitlab_monitor_metrics;
|
||||
|
||||
ALTER INDEX p_ci_builds_metadata_pkey ATTACH PARTITION ci_builds_metadata_pkey;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,10 @@ DETAILS:
|
|||
|
||||
Use this API to retrieve details about arbitrary tokens and to revoke them. Unlike other APIs that expose token information, this API allows you to retrieve details or revoke tokens without knowing the specific type of token.
|
||||
|
||||
## Token Prefixes
|
||||
|
||||
When making a request, tokens must begin with `glpat` or the current [custom prefix](../../administration/settings/account_and_limit_settings.md#personal-access-token-prefix). If the token begins with a previous custom prefix, the operation will fail. Interest in support for previous custom prefixes is tracked in [issue 165663](https://gitlab.com/gitlab-org/gitlab/-/issues/165663).
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- You must have administrator access to the instance.
|
||||
|
|
@ -47,7 +51,7 @@ Supported attributes:
|
|||
|
||||
| Attribute | Type | Required | Description |
|
||||
|--------------|---------|----------|----------------------------|
|
||||
| `token` | string | Yes | Existing token to identify |
|
||||
| `token` | string | Yes | Existing token to identify. Must begin with `glpat` or the current [custom prefix](../../administration/settings/account_and_limit_settings.md#personal-access-token-prefix). |
|
||||
|
||||
If successful, returns [`200`](../rest/troubleshooting.md#status-codes) and information about the token.
|
||||
|
||||
|
|
@ -119,7 +123,7 @@ Supported attributes:
|
|||
|
||||
| Attribute | Type | Required | Description |
|
||||
|--------------|---------|----------|--------------------------|
|
||||
| `token` | string | Yes | Existing token to revoke |
|
||||
| `token` | string | Yes | Existing token to revoke. Must begin with `glpat` or the current [custom prefix](../../administration/settings/account_and_limit_settings.md#personal-access-token-prefix). |
|
||||
|
||||
If successful, returns [`204`](../rest/troubleshooting.md#status-codes) without content.
|
||||
|
||||
|
|
|
|||
|
|
@ -696,6 +696,8 @@ The commit status API for use with GitLab.
|
|||
|
||||
### List the statuses of a commit
|
||||
|
||||
> - `pipeline_id`, `order_by`, and `sort` fields [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/176142) in GitLab 17.9.
|
||||
|
||||
List the statuses of a commit in a project.
|
||||
The pagination parameters `page` and `per_page` can be used to restrict the list of references.
|
||||
|
||||
|
|
@ -703,14 +705,17 @@ The pagination parameters `page` and `per_page` can be used to restrict the list
|
|||
GET /projects/:id/repository/commits/:sha/statuses
|
||||
```
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-paths) |
|
||||
| `sha` | string | yes | The commit SHA |
|
||||
| `ref` | string | no | The name of a repository branch or tag or, if not given, the default branch |
|
||||
| `stage` | string | no | Filter by [build stage](../ci/yaml/index.md#stages), for example, `test` |
|
||||
| `name` | string | no | Filter by [job name](../ci/yaml/index.md#job-keywords), for example, `bundler:audit` |
|
||||
| `all` | boolean | no | Return all statuses, not only the latest ones |
|
||||
| Attribute | Type | Required | Description |
|
||||
|---------------|----------------| -------- |--------------------------------------------------------------------------------------|
|
||||
| `id` | integer/string | Yes | ID or [URL-encoded path of the project](rest/index.md#namespaced-paths). |
|
||||
| `sha` | string | Yes | Hash of the commit. |
|
||||
| `ref` | string | No | Name of the branch or tag. Default is the default branch. |
|
||||
| `stage` | string | No | Filter statuses by [build stage](../ci/yaml/index.md#stages). For example, `test`. |
|
||||
| `name` | string | No | Filter statuses by [job name](../ci/yaml/index.md#job-keywords). For example, `bundler:audit`. |
|
||||
| `pipeline_id` | integer | No | Filter statuses by pipeline ID. For example, `1234`. |
|
||||
| `order_by` | string | No | Values for sorting statuses. Valid values are `id` and `pipeline_id`. Default is `id`. |
|
||||
| `sort` | string | No | Sort statuses in ascending or descending order. Valid values are `asc` and `desc`. Default is `asc`. |
|
||||
| `all` | boolean | No | Include all statuses instead of latest only. Default is `false`. |
|
||||
|
||||
```shell
|
||||
curl --header "PRIVATE-TOKEN: <your_access_token>" \
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ Example request:
|
|||
|
||||
```shell
|
||||
curl --header "PRIVATE-TOKEN: <your_access_token>" \
|
||||
--url "https://gitlab.example.com/api/v4/projects/7/registry/protection/rules"
|
||||
--url "https://gitlab.example.com/api/v4/projects/7/registry/protection/repository/rules"
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
|
|
|||
|
|
@ -22670,6 +22670,7 @@ Represents a product analytics dashboard.
|
|||
| <a id="customizabledashboardconfigurationproject"></a>`configurationProject` | [`Project`](#project) | Project which contains the dashboard definition. |
|
||||
| <a id="customizabledashboarddescription"></a>`description` | [`String`](#string) | Description of the dashboard. |
|
||||
| <a id="customizabledashboarderrors"></a>`errors` | [`[String!]`](#string) | Errors on yaml definition. |
|
||||
| <a id="customizabledashboardfilters"></a>`filters` | [`JSON`](#json) | Dashboard global filters. |
|
||||
| <a id="customizabledashboardpanels"></a>`panels` | [`CustomizableDashboardPanelConnection`](#customizabledashboardpanelconnection) | Panels shown on the dashboard. (see [Connections](#connections)) |
|
||||
| <a id="customizabledashboardslug"></a>`slug` | [`String!`](#string) | Slug of the dashboard. |
|
||||
| <a id="customizabledashboardstatus"></a>`status` **{warning-solid}** | [`String`](#string) | **Introduced** in GitLab 17.0. **Status**: Experiment. Status of the dashboard. |
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ Predefined variables become available at three different phases of pipeline exec
|
|||
| `CI_OPEN_MERGE_REQUESTS` | Pre-pipeline | A comma-separated list of up to four merge requests that use the current branch and project as the merge request source. Only available in branch and merge request pipelines if the branch has an associated merge request. For example, `gitlab-org/gitlab!333,gitlab-org/gitlab-foss!11`. |
|
||||
| `CI_PAGES_DOMAIN` | Pre-pipeline | The instance's domain that hosts GitLab Pages, not including the namespace subdomain. To use the full hostname, use `CI_PAGES_HOSTNAME` instead. |
|
||||
| `CI_PAGES_HOSTNAME` | Job-only | The full hostname of the Pages deployment. |
|
||||
| `CI_PAGES_URL` | Job-only | The URL for a GitLab Pages site. Always a subdomain of `CI_PAGES_DOMAIN`. |
|
||||
| `CI_PAGES_URL` | Job-only | The URL for a GitLab Pages site. Always a subdomain of `CI_PAGES_DOMAIN`. In GitLab 17.8 and later, when the [feature flag](../../administration/feature_flags.md) named `fix_pages_ci_variables` is enabled, the value includes the `path_prefix` when one is specified. Enabled on GitLab.com in GitLab 17.8. |
|
||||
| `CI_PIPELINE_ID` | Job-only | The instance-level ID of the current pipeline. This ID is unique across all projects on the GitLab instance. |
|
||||
| `CI_PIPELINE_IID` | Pipeline | The project-level IID (internal ID) of the current pipeline. This ID is unique only in the current project. |
|
||||
| `CI_PIPELINE_SOURCE` | Pre-pipeline | How the pipeline was triggered. The value can be one of the [pipeline sources](../jobs/job_rules.md#ci_pipeline_source-predefined-variable). |
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ an integrated GitLab workflow experience.
|
|||
- **Code generation**: Generates code based on a natural language code comment block.
|
||||
Write a comment, then press <kbd>Enter</kbd> to generate code based on the context of your
|
||||
comment, and the rest of your code.
|
||||
- **Context-aware suggestions**: Uses currently open files, content before and after the cursor,
|
||||
- **Context-aware suggestions**: Uses open files in your IDE, content before and after the cursor,
|
||||
filename, and extension type to provide relevant suggestions.
|
||||
- **Support for multiple languages**: Works with various programming languages supported by your development environment.
|
||||
|
||||
|
|
|
|||
|
|
@ -46,10 +46,14 @@ To enable GitLab Language Server debug logs:
|
|||
|
||||
The debug logs are available in the `idea.log` log file. To view this file, either:
|
||||
|
||||
<!-- vale gitlab_base.SubstitutionWarning = NO -->
|
||||
|
||||
- In your IDE, go to **Help > Show Log in Finder**.
|
||||
- Go to the directory `/Users/<user>/Library/Logs/JetBrains/IntelliJIdea<build_version>`, replacing
|
||||
`<user>` and `<build_version>` with the appropriate values.
|
||||
|
||||
<!-- vale gitlab_base.SubstitutionWarning = YES -->
|
||||
|
||||
## Certificate errors
|
||||
|
||||
If your machine connects to your GitLab instance through a proxy, you might encounter
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ description: "Connect and use GitLab Duo in Neovim."
|
|||
|
||||
# GitLab plugin for Neovim - `gitlab.vim`
|
||||
|
||||
The [GitLab plugin](https://gitlab.com/gitlab-org/editor-extensions/gitlab.vim)
|
||||
integrates GitLab with Neovim, and is built in Lua.
|
||||
The [GitLab plugin](https://gitlab.com/gitlab-org/editor-extensions/gitlab.vim) is a Lua-based plugin
|
||||
that integrates GitLab with Neovim.
|
||||
|
||||
[Install and configure the extension](setup.md).
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ To enable more logging:
|
|||
|
||||
## Reproduce the problem in a minimal project
|
||||
|
||||
To help improve the maintainers' ability to understand and resolve your issue, create a sample
|
||||
To help project maintainers understand and resolve your issue, create a sample
|
||||
configuration or project that reproduces your issue. For example, when troubleshooting
|
||||
a problem with Code Suggestions:
|
||||
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ A full list of environment variables is available in the extension's help text a
|
|||
To configure this extension:
|
||||
|
||||
1. Configure your desired file types. For example, because this plugin supports Ruby, it adds a `FileType ruby` auto-command.
|
||||
To configure this behavior for additional file types, add more file types to the `code_suggestions.auto_filetypes` setup option:
|
||||
To configure this behavior for more file types, add more file types to the `code_suggestions.auto_filetypes` setup option:
|
||||
|
||||
```lua
|
||||
require('gitlab').setup({
|
||||
|
|
|
|||
|
|
@ -57,5 +57,5 @@ This extension provides these custom commands, which you can configure:
|
|||
You can access the extension's custom commands with keyboard shortcuts, which you can customize:
|
||||
|
||||
1. On the top bar, go to **Tools > Options**.
|
||||
1. Go to **Environment > Keyboard**. Commands exposed by this extension are prefixed with `GitLab.`.
|
||||
1. Go to **Environment > Keyboard**. This extension prefixes its commands with `GitLab.`.
|
||||
1. Select a command, and assign it a keyboard shortcut.
|
||||
|
|
|
|||
|
|
@ -9,7 +9,10 @@ description: "Use the GitLab Workflow extension for VS Code to handle common Git
|
|||
|
||||
If your GitLab project uses CI/CD pipelines, you can start, watch, and debug CI/CD pipelines from the
|
||||
GitLab Workflow extension for VS Code. When you work locally on a Git branch, the bottom status bar
|
||||
shows the status of its most recent pipeline, or shows **No pipeline** if a pipeline hasn't run yet:
|
||||
shows either:
|
||||
|
||||
- The status of its most recent pipeline.
|
||||
- **No pipeline** if a pipeline hasn't run yet.
|
||||
|
||||

|
||||
|
||||
|
|
|
|||
|
|
@ -91,10 +91,10 @@ Not all item types support all parameters. These parameters apply to all query t
|
|||
| `draft` | **{dotted-circle}** No | `no` | Filter merge requests against their draft status: `yes` returns only merge requests in [draft status](../../user/project/merge_requests/drafts.md), `no` returns only merge requests not in draft status. Available only for merge requests. |
|
||||
| `excludeAssignee` | **{dotted-circle}** No | not applicable | Return items not assigned to the given username. Available only for issues. For the current user, set to `<current_user>`. |
|
||||
| `excludeAuthor` | **{dotted-circle}** No | not applicable | Return items not created by the given username. Available only for issues. For the current user, set to `<current_user>`. |
|
||||
| `excludeLabels` | **{dotted-circle}** No | `[]` | Array of label names. Available only for issues. To be returned, items must have none of the labels in the array. Predefined names are case-insensitive. |
|
||||
| `excludeLabels` | **{dotted-circle}** No | `[]` | Array of label names. Available only for issues. Items returned have none of the labels in the array. Predefined names are case-insensitive. |
|
||||
| `excludeMilestone` | **{dotted-circle}** No | not applicable | The milestone title to exclude. Available only for issues. |
|
||||
| `excludeSearch` | **{dotted-circle}** No | not applicable | Search GitLab items that doesn't have the search key in their title or description. Works only with issues. |
|
||||
| `labels` | **{dotted-circle}** No | `[]` | Array of label names. To be returned, items must have all labels in the array. `None` returns items with no labels. `Any` returns items with at least one label. Predefined names are case-insensitive. |
|
||||
| `labels` | **{dotted-circle}** No | `[]` | Array of label names. Items returned have all labels in the array. `None` returns items with no labels. `Any` returns items with at least one label. Predefined names are case-insensitive. |
|
||||
| `maxResults` | **{dotted-circle}** No | 20 | The number of results to show. |
|
||||
| `milestone` | **{dotted-circle}** No | not applicable | The milestone title. `None` lists all items with no milestone. `Any` lists all items with an assigned milestone. Not available for epics and vulnerabilities. |
|
||||
| `orderBy` | **{dotted-circle}** No | `created_at` | Return entities ordered by the selected value. Possible values: `created_at`, `updated_at`, `priority`, `due_date`, `relative_position`, `label_priority`, `milestone_due`, `popularity`, `weight`. Some values are specific to issues, and some to merge requests. For more information, see [List merge requests](../../api/merge_requests.md#list-merge-requests). |
|
||||
|
|
|
|||
|
|
@ -171,9 +171,9 @@ Use this extension to review, comment on, and approve merge requests without lea
|
|||
merge request you want to review. Its sidebar entry expands with more information.
|
||||
1. Under the merge request's number and title, select **Description** to read more about the merge request.
|
||||
1. To review the proposed changes to a file, select the file from the list to show it in a VS Code tab.
|
||||
Diff comments are shown inline in the tab. In the list, deleted files are marked in red:
|
||||
GitLab shows diff comments inline in the tab. In the list, deleted files are marked in red:
|
||||
|
||||

|
||||

|
||||
|
||||
Use the diff to:
|
||||
|
||||
|
|
@ -240,11 +240,11 @@ DETAILS:
|
|||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-vscode-extension/-/issues/1675) in VS Code extension version 5.31.
|
||||
|
||||
Static application security testing (SAST) in VS Code detects vulnerabilities in the active file.
|
||||
With early detection, you can remediate vulnerabilities before your changes are merged into the
|
||||
With early detection, you can remediate vulnerabilities before you merge your changes into the
|
||||
default branch.
|
||||
|
||||
When you trigger a SAST scan, the content of the active file is passed to GitLab and checked against
|
||||
SAST vulnerability rules. Scan results are shown in the primary side bar.
|
||||
SAST vulnerability rules. GitLab shows scan results in the primary side bar.
|
||||
|
||||
Prerequisites:
|
||||
|
||||
|
|
@ -254,6 +254,8 @@ Prerequisites:
|
|||
|
||||
To perform SAST scanning of a file in VS Code:
|
||||
|
||||
<!-- markdownlint-disable MD044 -->
|
||||
|
||||
1. Open the file.
|
||||
1. Trigger the SAST scan by either:
|
||||
- Saving the file (if you have [selected the **Enable scanning on file save** option](setup.md#code-security)).
|
||||
|
|
@ -266,11 +268,11 @@ To perform SAST scanning of a file in VS Code:
|
|||
1. View the results of the SAST scan.
|
||||
1. View the **Primary Side Bar**.
|
||||
1. Select GitLab Workflow ({tanuki}) to display the extension sidebar.
|
||||
<!-- markdownlint-disable MD044 -->
|
||||
1. Expand the **GITLAB REMOTE SCAN (SAST)** section.
|
||||
|
||||
The results of the SAST scan are listed in descending order by severity. To see details of a
|
||||
finding, select it in the **GITLAB REMOTE SCAN (SAST)** section of the extension sidebar.
|
||||
|
||||
<!-- markdownlint-enable MD044 -->
|
||||
|
||||
## Search issues and merge requests
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ The extension shows information in the VS Code status bar if both:
|
|||
|
||||
To configure settings, go to **Settings > Extensions > GitLab Workflow**.
|
||||
|
||||
By default, Code Suggestions and GitLab Duo Chat are turned on, so if you have
|
||||
By default, Code Suggestions and GitLab Duo Chat are enabled, so if you have
|
||||
the GitLab Duo add-on and a seat assigned, you should have access.
|
||||
|
||||
### Code security
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ These instructions were tested on Arch Linux `5.14.3-arch1-1` and VS Code 1.60.0
|
|||
### MacOS
|
||||
|
||||
NOTE:
|
||||
These instructions are untested, but likely work as intended. If you can confirm this setup,
|
||||
These instructions are untested, but should work as intended. If you can confirm this setup,
|
||||
create a documentation issue with more information.
|
||||
|
||||
Make sure you see the self-signed CA in your keychain:
|
||||
|
|
|
|||
|
|
@ -123,9 +123,8 @@ A workaround exists for MacOS:
|
|||
|
||||
### Ubuntu workaround
|
||||
|
||||
When VS Code is installed with `snap` in Ubuntu 20.04 and 22.04, it can't read passwords from the OS keychain that extension versions 3.44.0
|
||||
and later use for secure token storage.
|
||||
|
||||
When you install VS Code with `snap` in Ubuntu 20.04 and 22.04, VS Code can't read passwords from the
|
||||
OS keychain. Extension versions 3.44.0 and later use the OS keychain for secure token storage.
|
||||
A workaround exists for Ubuntu users who use versions of VS Code earlier than 1.68.0:
|
||||
|
||||
- You can downgrade the GitLab Workflow extension to version 3.43.1.
|
||||
|
|
@ -141,7 +140,7 @@ the last three steps to re-authenticate.
|
|||
|
||||
## Set token with environment variables
|
||||
|
||||
If you often delete your VS Code storage, such as in Gitpod containers, you can create environment variables
|
||||
If you often delete your VS Code storage, such as in Gitpod containers, set environment variables
|
||||
before starting VS Code. If you set the token in a
|
||||
[VS Code environment variable](https://code.visualstudio.com/docs/editor/variables-reference#_environment-variables),
|
||||
you don't have to set a personal access token each time you delete your VS Code storage. Set these variables:
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ DETAILS:
|
|||
> - Introduced in GitLab 15.9 as an [experiment](../../policy/development_stages_support.md#experiment) feature [with a flag](../../administration/feature_flags.md) named `combined_analytics_dashboards`. Disabled by default.
|
||||
> - `combined_analytics_dashboards` [enabled](https://gitlab.com/gitlab-org/gitlab/-/issues/389067) by default in GitLab 16.11.
|
||||
> - `combined_analytics_dashboards` [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/454350) in GitLab 17.1.
|
||||
> - `filters` configuration [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/505317) in GitLab 17.9. Disabled by default.
|
||||
|
||||
Analytics dashboards help you visualize the collected data.
|
||||
You can use built-in dashboards by GitLab or create your own dashboards with custom visualizations.
|
||||
|
|
@ -193,6 +194,27 @@ and one visualization (line chart) that applies to all dashboards, the file stru
|
|||
│ └── example_line_chart.yaml
|
||||
```
|
||||
|
||||
### Dashboard filters
|
||||
|
||||
Dashboards support the following filters:
|
||||
|
||||
- **Date range**: Date selector to filter data by date.
|
||||
- **Anonymous users**: Toggle to include or exclude anonymous users from the dataset.
|
||||
|
||||
To enable filters, in the `.yaml` configuration file set the filter's `enabled` option to `true`:
|
||||
|
||||
```yaml
|
||||
title: My dashboard
|
||||
...
|
||||
filters:
|
||||
excludeAnonymousUsers:
|
||||
enabled: true
|
||||
dateRange:
|
||||
enabled: true
|
||||
```
|
||||
|
||||
See a complete [dashboard configuration example](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/gitlab/analytics/product_analytics/dashboards/audience.yaml).
|
||||
|
||||
## Define a chart visualization
|
||||
|
||||
You can define different charts and add visualization options to some of them, such as:
|
||||
|
|
|
|||
|
|
@ -246,7 +246,12 @@ GitLab.com customers must contact their Customer Success Manager to enable this
|
|||
|
||||
You can add files in your VS Code workspace to ask GitLab Duo Chat about.
|
||||
|
||||
You cannot add local files that are not part of a repository.
|
||||
Prerequisites:
|
||||
|
||||
- You cannot add local files that are not part of a repository.
|
||||
- Only text-based files can be included. Binary files (such as PDFs or images) are not supported.
|
||||
|
||||
To do this:
|
||||
|
||||
1. In your IDE, in GitLab Duo Chat, type `/include`.
|
||||
1. To add files, you can either:
|
||||
|
|
|
|||
|
|
@ -343,7 +343,7 @@ possibility. For example:
|
|||
deploy-pages:
|
||||
stage: deploy
|
||||
script:
|
||||
- echo "Pages accessible through ${CI_PAGES_URL}/${PAGES_PREFIX}"
|
||||
- echo "Pages accessible through ${CI_PAGES_URL}"
|
||||
variables:
|
||||
PAGES_PREFIX: "" # No prefix by default (master)
|
||||
pages: # specifies that this is a Pages job
|
||||
|
|
@ -379,14 +379,14 @@ For example:
|
|||
deploy-pages:
|
||||
stage: deploy
|
||||
script:
|
||||
- echo "Pages accessible through ${CI_PAGES_URL}/${PAGES_PREFIX}"
|
||||
- echo "Pages accessible through ${CI_PAGES_URL}"
|
||||
variables:
|
||||
PAGES_PREFIX: "" # no prefix by default (master)
|
||||
pages: # specifies that this is a Pages job
|
||||
path_prefix: "$PAGES_PREFIX"
|
||||
environment:
|
||||
name: "Pages ${PAGES_PREFIX}"
|
||||
url: "${CI_PAGES_URL}/${PAGES_PREFIX}"
|
||||
url: $CI_PAGES_URL
|
||||
artifacts:
|
||||
paths:
|
||||
- public
|
||||
|
|
|
|||
|
|
@ -2,4 +2,7 @@ inherit_from:
|
|||
- ../config/rubocop.yml
|
||||
|
||||
Gemfile/MissingFeatureCategory:
|
||||
Enabled: false
|
||||
Enabled: false
|
||||
|
||||
Search/NamespacedClass:
|
||||
Enabled: false
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ PATH
|
|||
gitlab-active-context (0.0.1)
|
||||
activesupport
|
||||
connection_pool
|
||||
elasticsearch
|
||||
pg
|
||||
zeitwerk
|
||||
|
||||
|
|
@ -56,7 +57,22 @@ GEM
|
|||
date (3.4.1)
|
||||
diff-lcs (1.5.1)
|
||||
drb (2.2.1)
|
||||
elasticsearch (7.17.11)
|
||||
elasticsearch-api (= 7.17.11)
|
||||
elasticsearch-transport (= 7.17.11)
|
||||
elasticsearch-api (7.17.11)
|
||||
multi_json
|
||||
elasticsearch-transport (7.17.11)
|
||||
base64
|
||||
faraday (>= 1, < 3)
|
||||
multi_json
|
||||
erubi (1.13.0)
|
||||
faraday (2.12.2)
|
||||
faraday-net_http (>= 2.0, < 3.5)
|
||||
json
|
||||
logger
|
||||
faraday-net_http (3.4.0)
|
||||
net-http (>= 0.5.0)
|
||||
gitlab-styles (13.0.2)
|
||||
rubocop (~> 1.68.0)
|
||||
rubocop-capybara (~> 2.21.0)
|
||||
|
|
@ -81,6 +97,9 @@ GEM
|
|||
nokogiri (>= 1.12.0)
|
||||
mini_portile2 (2.8.8)
|
||||
minitest (5.25.4)
|
||||
multi_json (1.15.0)
|
||||
net-http (0.6.0)
|
||||
uri
|
||||
nokogiri (1.17.1)
|
||||
mini_portile2 (~> 2.8.2)
|
||||
racc (~> 1.4)
|
||||
|
|
|
|||
|
|
@ -30,13 +30,23 @@ ActiveContext.configure do |config|
|
|||
config.databases = {
|
||||
es1: {
|
||||
adapter: 'elasticsearch',
|
||||
prefix: 'gitlab',
|
||||
prefix: 'gitlab_active_context',
|
||||
options: ::Gitlab::CurrentSettings.elasticsearch_config
|
||||
}
|
||||
}
|
||||
end
|
||||
```
|
||||
|
||||
#### Elasticsearch Configuration Options
|
||||
|
||||
| Option | Description | Required | Default | Example |
|
||||
|--------|-------------|----------|---------|---------|
|
||||
| `url` | The URL of the Elasticsearch server | Yes | N/A | `'http://localhost:9200'` |
|
||||
| `prefix` | The prefix for Elasticsearch indices | No | `'gitlab_active_context'` | `'my_custom_prefix'` |
|
||||
| `client_request_timeout` | The timeout for client requests in seconds | No | N/A | `60` |
|
||||
| `retry_on_failure` | The number of times to retry a failed request | No | `0` (no retries) | `3` |
|
||||
| `debug` | Enable or disable debug logging | No | `false` | `true` |
|
||||
|
||||
## Contributing
|
||||
|
||||
TODO
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ Gem::Specification.new do |spec|
|
|||
|
||||
spec.add_dependency 'activesupport'
|
||||
spec.add_dependency 'connection_pool'
|
||||
spec.add_dependency 'elasticsearch'
|
||||
spec.add_dependency 'pg'
|
||||
spec.add_dependency 'zeitwerk'
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ module ActiveContext
|
|||
module Databases
|
||||
module Concerns
|
||||
module Client
|
||||
DEFAULT_PREFIX = 'gitlab'
|
||||
DEFAULT_PREFIX = 'gitlab_active_context'
|
||||
|
||||
attr_reader :options
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ActiveContext
|
||||
module Databases
|
||||
module Elasticsearch
|
||||
class Adapter
|
||||
include ActiveContext::Databases::Concerns::Adapter
|
||||
|
||||
def client_klass
|
||||
ActiveContext::Databases::Elasticsearch::Client
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ActiveContext
|
||||
module Databases
|
||||
module Elasticsearch
|
||||
class Client
|
||||
include ActiveContext::Databases::Concerns::Client
|
||||
|
||||
OPEN_TIMEOUT = 5
|
||||
NO_RETRY = 0
|
||||
|
||||
def initialize(options)
|
||||
@options = options
|
||||
end
|
||||
|
||||
def search(_query)
|
||||
res = client.search
|
||||
QueryResult.new(res)
|
||||
end
|
||||
|
||||
def client
|
||||
::Elasticsearch::Client.new(elasticsearch_config)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def elasticsearch_config
|
||||
{
|
||||
adapter: :net_http,
|
||||
urls: options[:url],
|
||||
transport_options: {
|
||||
request: {
|
||||
timeout: options[:client_request_timeout],
|
||||
open_timeout: OPEN_TIMEOUT
|
||||
}
|
||||
},
|
||||
randomize_hosts: true,
|
||||
retry_on_failure: options[:retry_on_failure] || NO_RETRY,
|
||||
log: options[:debug],
|
||||
debug: options[:debug]
|
||||
}.compact
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ActiveContext
|
||||
module Databases
|
||||
module Elasticsearch
|
||||
class QueryResult
|
||||
include ActiveContext::Databases::Concerns::QueryResult
|
||||
|
||||
def initialize(result)
|
||||
@result = result
|
||||
end
|
||||
|
||||
def count
|
||||
result['hits']['total']['value']
|
||||
end
|
||||
|
||||
def each
|
||||
return enum_for(:each) unless block_given?
|
||||
|
||||
result['hits']['hits'].each do |hit|
|
||||
yield hit['_source']
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :result
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe ActiveContext::Databases::Elasticsearch::Adapter do
|
||||
let(:options) { { url: 'http://localhost:9200' } }
|
||||
|
||||
subject(:adapter) { described_class.new(options) }
|
||||
|
||||
it 'delegates search to client' do
|
||||
query = ActiveContext::Query.filter(foo: :bar)
|
||||
expect(adapter.client).to receive(:search).with(query)
|
||||
|
||||
adapter.search(query)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe ActiveContext::Databases::Elasticsearch::Client do
|
||||
let(:options) { { url: 'http://localhost:9200' } }
|
||||
|
||||
subject(:client) { described_class.new(options) }
|
||||
|
||||
describe '#search' do
|
||||
let(:elasticsearch_client) { instance_double(Elasticsearch::Client) }
|
||||
let(:search_response) { { 'hits' => { 'total' => 5, 'hits' => [] } } }
|
||||
|
||||
before do
|
||||
allow(client).to receive(:client).and_return(elasticsearch_client)
|
||||
allow(elasticsearch_client).to receive(:search).and_return(search_response)
|
||||
end
|
||||
|
||||
it 'calls search on the Elasticsearch client' do
|
||||
expect(elasticsearch_client).to receive(:search)
|
||||
client.search('query')
|
||||
end
|
||||
|
||||
it 'returns a QueryResult object' do
|
||||
result = client.search('query')
|
||||
expect(result).to be_a(ActiveContext::Databases::Elasticsearch::QueryResult)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#client' do
|
||||
let(:elasticsearch_config) { client.send(:elasticsearch_config) }
|
||||
let(:options) { { url: 'http://localhost:9200', client_request_timeout: 30, retry_on_failure: 3, debug: true } }
|
||||
|
||||
it 'returns an instance of Elasticsearch::Client' do
|
||||
expect(Elasticsearch::Client).to receive(:new).with(elasticsearch_config)
|
||||
client.client
|
||||
end
|
||||
|
||||
it 'includes all expected keys with correct values' do
|
||||
expect(elasticsearch_config).to include(
|
||||
adapter: :net_http,
|
||||
urls: 'http://localhost:9200',
|
||||
transport_options: {
|
||||
request: {
|
||||
timeout: 30,
|
||||
open_timeout: 5
|
||||
}
|
||||
},
|
||||
randomize_hosts: true,
|
||||
retry_on_failure: 3,
|
||||
log: true,
|
||||
debug: true
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#prefix' do
|
||||
it 'returns default prefix when not specified' do
|
||||
expect(client.prefix).to eq('gitlab_active_context')
|
||||
end
|
||||
|
||||
it 'returns configured prefix' do
|
||||
client = described_class.new(options.merge(prefix: 'custom'))
|
||||
expect(client.prefix).to eq('custom')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe ActiveContext::Databases::Elasticsearch::QueryResult do
|
||||
let(:elasticsearch_result) do
|
||||
{
|
||||
'hits' => {
|
||||
'total' => { 'value' => 2 },
|
||||
'hits' => [
|
||||
{ '_source' => { 'id' => 1, 'name' => 'test1' } },
|
||||
{ '_source' => { 'id' => 2, 'name' => 'test2' } }
|
||||
]
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
subject(:query_result) { described_class.new(elasticsearch_result) }
|
||||
|
||||
describe '#count' do
|
||||
it 'returns the total number of hits' do
|
||||
expect(query_result.count).to eq(2)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#each' do
|
||||
it 'yields each hit source' do
|
||||
expected_sources = [
|
||||
{ 'id' => 1, 'name' => 'test1' },
|
||||
{ 'id' => 2, 'name' => 'test2' }
|
||||
]
|
||||
|
||||
expect { |b| query_result.each(&b) }.to yield_successive_args(*expected_sources)
|
||||
end
|
||||
|
||||
it 'returns an enumerator when no block is given' do
|
||||
expect(query_result.each).to be_a(Enumerator)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'enumerable behavior' do
|
||||
it 'implements Enumerable methods' do
|
||||
expect(query_result.map { |hit| hit['id'] }).to eq([1, 2]) # rubocop: disable Rails/Pluck -- pluck not implemented
|
||||
expect(query_result.select { |hit| hit['id'] == 1 }).to eq([{ 'id' => 1, 'name' => 'test1' }])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -44,7 +44,7 @@ RSpec.describe ActiveContext::Databases::Postgresql::Client do
|
|||
|
||||
describe '#prefix' do
|
||||
it 'returns default prefix when not specified' do
|
||||
expect(client.prefix).to eq('gitlab')
|
||||
expect(client.prefix).to eq('gitlab_active_context')
|
||||
end
|
||||
|
||||
it 'returns configured prefix' do
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
require "active_context"
|
||||
require 'logger'
|
||||
require 'elasticsearch'
|
||||
|
||||
RSpec.configure do |config|
|
||||
# Enable flags like --only-failures and --next-failure
|
||||
|
|
|
|||
|
|
@ -7,8 +7,14 @@ module API
|
|||
feature_category :continuous_integration
|
||||
urgency :low
|
||||
|
||||
ALLOWED_SORT_VALUES = %w[id pipeline_id].freeze
|
||||
DEFAULT_SORT_VALUE = 'id'
|
||||
|
||||
ALLOWED_SORT_DIRECTIONS = %w[asc desc].freeze
|
||||
DEFAULT_SORT_DIRECTION = 'asc'
|
||||
|
||||
params do
|
||||
requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
|
||||
requires :id, types: [String, Integer], desc: 'ID or URL-encoded path of the project.'
|
||||
end
|
||||
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
|
||||
include PaginationParams
|
||||
|
|
@ -25,11 +31,23 @@ module API
|
|||
is_array true
|
||||
end
|
||||
params do
|
||||
requires :sha, type: String, desc: 'The commit hash', documentation: { example: '18f3e63d05582537db6d183d9d557be09e1f90c8' }
|
||||
optional :ref, type: String, desc: 'The ref', documentation: { example: 'develop' }
|
||||
optional :stage, type: String, desc: 'The stage', documentation: { example: 'test' }
|
||||
optional :name, type: String, desc: 'The name', documentation: { example: 'bundler:audit' }
|
||||
optional :all, type: Boolean, desc: 'Show all statuses', documentation: { default: false }
|
||||
requires :sha, type: String, desc: 'Hash of the commit.', documentation: { example: '18f3e63d05582537db6d183d9d557be09e1f90c8' }
|
||||
optional :ref, type: String, desc: 'Name of the branch or tag. Default is the default branch.', documentation: { example: 'develop' }
|
||||
optional :stage, type: String, desc: 'Filter statuses by build stage.', documentation: { example: 'test' }
|
||||
optional :name, type: String, desc: 'Filter statuses by job name.', documentation: { example: 'bundler:audit' }
|
||||
optional :pipeline_id, type: Integer, desc: 'Filter statuses by pipeline ID.', documentation: { example: 1234 }
|
||||
optional :all, type: Boolean, desc: 'Include all statuses instead of latest only. Default is `false`.', documentation: { default: false }
|
||||
optional :order_by,
|
||||
type: String,
|
||||
values: ALLOWED_SORT_VALUES,
|
||||
default: DEFAULT_SORT_VALUE,
|
||||
desc: 'Values for sorting statuses. Valid values are `id` and `pipeline_id`. Default is `id`.',
|
||||
documentation: { default: DEFAULT_SORT_VALUE }
|
||||
optional :sort,
|
||||
type: String,
|
||||
values: ALLOWED_SORT_DIRECTIONS,
|
||||
desc: 'Sort statuses in ascending or descending order. Valid values are `asc` and `desc`. Default is `asc`.',
|
||||
documentation: { default: DEFAULT_SORT_DIRECTION }
|
||||
use :pagination
|
||||
end
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
|
|
@ -39,11 +57,13 @@ module API
|
|||
not_found!('Commit') unless user_project.commit(params[:sha])
|
||||
|
||||
pipelines = user_project.ci_pipelines.where(sha: params[:sha])
|
||||
pipelines = pipelines.where(id: params[:pipeline_id]) if params[:pipeline_id].present?
|
||||
statuses = ::CommitStatus.where(pipeline: pipelines)
|
||||
statuses = statuses.latest unless to_boolean(params[:all])
|
||||
statuses = statuses.where(ref: params[:ref]) if params[:ref].present?
|
||||
statuses = statuses.where(stage: params[:stage]) if params[:stage].present?
|
||||
statuses = statuses.where(name: params[:name]) if params[:name].present?
|
||||
statuses = order_and_sort_statuses(statuses)
|
||||
present paginate(statuses), with: Entities::CommitStatus
|
||||
end
|
||||
# rubocop: enable CodeReuse/ActiveRecord
|
||||
|
|
@ -95,6 +115,14 @@ module API
|
|||
updatable_optional_attributes = %w[target_url description coverage]
|
||||
attributes_for_keys(updatable_optional_attributes)
|
||||
end
|
||||
|
||||
# rubocop: disable CodeReuse/ActiveRecord -- Better code maintainability here, this won't be reused anywhere
|
||||
def order_and_sort_statuses(statuses)
|
||||
sort_direction = params[:sort].presence || DEFAULT_SORT_DIRECTION
|
||||
order_column = ALLOWED_SORT_VALUES.include?(params[:order_by]) ? params[:order_by] : DEFAULT_SORT_VALUE
|
||||
statuses.order(order_column => sort_direction)
|
||||
end
|
||||
# rubocop: enable CodeReuse/ActiveRecord
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ module API
|
|||
strong_memoize_attr :upstream
|
||||
|
||||
def cached_responses
|
||||
upstream.cached_responses.default.search_by_relative_path(params[:search])
|
||||
upstream.default_cached_responses.order_created_desc.search_by_relative_path(params[:search])
|
||||
end
|
||||
|
||||
def cached_response
|
||||
|
|
@ -108,7 +108,7 @@ module API
|
|||
authorize! :destroy_virtual_registry, cached_response.upstream
|
||||
|
||||
destroy_conditionally!(cached_response) do |cached_response|
|
||||
render_validation_error!(cached_response) unless cached_response.update(upstream: nil)
|
||||
render_validation_error!(cached_response) unless cached_response.mark_as_pending_destruction
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,10 +4,14 @@
|
|||
module Gitlab
|
||||
module Database
|
||||
module Sos
|
||||
TASKS = [].freeze
|
||||
TASKS = [
|
||||
Sos::ShowAllSettings
|
||||
].freeze
|
||||
|
||||
def self.run
|
||||
TASKS
|
||||
def self.run(output_file)
|
||||
Output.writing(output_file, mode: :directory) do |output|
|
||||
TASKS.each { |t| t.run(output) }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Database
|
||||
module Sos
|
||||
class Output
|
||||
def self.writing(path, mode:)
|
||||
output = new(path, mode: mode)
|
||||
yield output
|
||||
ensure
|
||||
output.finish
|
||||
end
|
||||
|
||||
def initialize(path, mode:)
|
||||
@mode = mode
|
||||
if mode == :zip
|
||||
@zip = Zip::File.open(path, create: true) # rubocop:disable Performance/Rubyzip -- opening a file so no performance issues
|
||||
elsif mode == :directory # Used in testing, it's a lot easier to inspect a directory than a zip file
|
||||
@dir = path
|
||||
else
|
||||
raise "mode must be one of :zip, :directory"
|
||||
end
|
||||
end
|
||||
|
||||
def finish
|
||||
@zip.close if @mode == :zip
|
||||
end
|
||||
|
||||
def write_file(relative_path)
|
||||
if @mode == :zip
|
||||
@zip.get_output_stream(relative_path) do |f|
|
||||
yield f
|
||||
end
|
||||
else
|
||||
abs_path = File.join(@dir, relative_path)
|
||||
FileUtils.mkdir_p(File.dirname(abs_path))
|
||||
File.open(abs_path, 'w+') do |f|
|
||||
yield f
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'csv'
|
||||
|
||||
# Create a csv with all the pg settings
|
||||
|
||||
module Gitlab
|
||||
module Database
|
||||
module Sos
|
||||
class ShowAllSettings
|
||||
def self.run(output)
|
||||
query_results = ApplicationRecord.connection.execute('SHOW ALL;')
|
||||
|
||||
output.write_file('pg_settings.csv') do |f|
|
||||
CSV.open(f, 'w+') do |csv|
|
||||
# headers [name, setting, description]
|
||||
csv << query_results.fields
|
||||
# data
|
||||
query_results.each do |row|
|
||||
csv << row.values
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -21,7 +21,7 @@ namespace :gitlab do
|
|||
|
||||
desc 'Gitlab | DB | Troubleshoot issues with the database'
|
||||
task sos: :environment do
|
||||
Gitlab::Database::Sos.run
|
||||
Gitlab::Database::Sos.run("tmp/sos")
|
||||
end
|
||||
|
||||
namespace :mark_migration_complete do
|
||||
|
|
|
|||
|
|
@ -17024,9 +17024,6 @@ msgstr ""
|
|||
msgid "Created %{time_ago}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Created %{timeago}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Created %{timestamp}"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -19636,9 +19633,6 @@ msgstr ""
|
|||
msgid "DeployTokens|Your new project deploy token has been created."
|
||||
msgstr ""
|
||||
|
||||
msgid "Deployed %{timeago}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Deployed to"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -19800,9 +19794,6 @@ msgstr ""
|
|||
msgid "Deployment|Deployment #%{iid}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Deployment|Deployment ID"
|
||||
msgstr ""
|
||||
|
||||
msgid "Deployment|Deployment approvals require a Premium or Ultimate subscription"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -19913,6 +19904,15 @@ msgstr ""
|
|||
msgid "Deployment|There was an issue fetching the deployment, please try again later."
|
||||
msgstr ""
|
||||
|
||||
msgid "Deployment|Triggered by %{username}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Deployment|Triggered by %{username} on %{time}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Deployment|Triggered on %{time}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Deployment|Triggerer"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -22250,6 +22250,9 @@ msgstr ""
|
|||
msgid "Environments|A freeze period is in effect from %{startTime} to %{endTime}. Deployments might fail during this time. For more information, see the %{docsLinkStart}deploy freeze documentation%{docsLinkEnd}."
|
||||
msgstr ""
|
||||
|
||||
msgid "Environments|Actions"
|
||||
msgstr ""
|
||||
|
||||
msgid "Environments|An error occurred while canceling the auto stop, please try again"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -22322,6 +22325,9 @@ msgstr ""
|
|||
msgid "Environments|Deployment history"
|
||||
msgstr ""
|
||||
|
||||
msgid "Environments|Deployments"
|
||||
msgstr ""
|
||||
|
||||
msgid "Environments|Edit environment"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -22370,6 +22376,9 @@ msgstr ""
|
|||
msgid "Environments|Learn more about stopping environments"
|
||||
msgstr ""
|
||||
|
||||
msgid "Environments|Name"
|
||||
msgstr ""
|
||||
|
||||
msgid "Environments|New environment"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -300,7 +300,7 @@
|
|||
"swagger-cli": "^4.0.4",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"timezone-mock": "^1.0.8",
|
||||
"vite": "^6.0.6",
|
||||
"vite": "^6.0.7",
|
||||
"vite-plugin-ruby": "^5.1.1",
|
||||
"vue-loader-vue3": "npm:vue-loader@17.4.2",
|
||||
"vue-test-utils-compat": "0.0.14",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
# Lines beginning with a hash are ignored, like this one.
|
||||
# Do not add new specs to this file.
|
||||
ee/spec/frontend/access_tokens/components/expires_at_field_spec.js
|
||||
ee/spec/frontend/admin/application_settings/deletion_protection/index_spec.js
|
||||
ee/spec/frontend/admin/application_settings/general/components/license_dropzone_spec.js
|
||||
ee/spec/frontend/admin/signup_restrictions/components/signup_form_spec.js
|
||||
ee/spec/frontend/admin/subscriptions/show/components/subscription_activation_form_spec.js
|
||||
|
|
@ -276,7 +275,6 @@ spec/frontend/super_sidebar/components/nav_item_router_link_spec.js
|
|||
spec/frontend/super_sidebar/components/organization_switcher_spec.js
|
||||
spec/frontend/super_sidebar/components/sidebar_portal_spec.js
|
||||
spec/frontend/super_sidebar/components/user_menu_spec.js
|
||||
spec/frontend/tags/init_delete_tag_modal_spec.js
|
||||
spec/frontend/todos/components/filtered_search_tokens/group_token_spec.js
|
||||
spec/frontend/todos/components/filtered_search_tokens/project_token_spec.js
|
||||
spec/frontend/tooltips/components/tooltips_spec.js
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ FactoryBot.define do
|
|||
upstream_etag { OpenSSL::Digest.hexdigest('SHA256', 'test') }
|
||||
content_type { 'text/plain' }
|
||||
file_final_path { '5f/9c/5f9c/@final/c7/4c/240c' }
|
||||
file_md5 { '54ce07f4124259b2ea58548e9d620004' }
|
||||
file_sha1 { 'bbde7c9fb6d74f9a2393bb36b0d4ac7e72c227ee' }
|
||||
file_md5 { 'd8e8fca2dc0f896fd7cb4cb0031ba249' }
|
||||
file_sha1 { '4e1243bd22c66e76c2ba9eddc1f91394e57f9f83' }
|
||||
status { :default }
|
||||
|
||||
transient do
|
||||
|
|
|
|||
|
|
@ -135,8 +135,6 @@ RSpec.describe 'Environments page', :js, feature_category: :continuous_delivery
|
|||
context 'when there are no deployments' do
|
||||
before do
|
||||
visit_environments(project)
|
||||
|
||||
page.click_button _('Expand')
|
||||
end
|
||||
|
||||
it 'shows environments names and counters' do
|
||||
|
|
@ -162,13 +160,11 @@ RSpec.describe 'Environments page', :js, feature_category: :continuous_delivery
|
|||
create(:deployment, :success, environment: environment, sha: project.commit.id)
|
||||
end
|
||||
|
||||
it 'shows deployment SHA and internal ID' do
|
||||
it 'shows deployment SHA' do
|
||||
visit_environments(project)
|
||||
page.click_button _('Expand')
|
||||
|
||||
expect(page).to have_text(deployment.short_sha)
|
||||
expect(page).to have_link(deployment.commit.full_title)
|
||||
expect(page).to have_content(deployment.iid)
|
||||
end
|
||||
|
||||
context 'when builds and manual actions are present' do
|
||||
|
|
@ -353,7 +349,6 @@ RSpec.describe 'Environments page', :js, feature_category: :continuous_delivery
|
|||
it 'does not show deployments', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/409990' do
|
||||
visit_environments(project)
|
||||
|
||||
page.click_button _('Expand')
|
||||
expect(page).to have_content(s_('Environments|There are no deployments for this environment yet. Learn more about setting up deployments.'))
|
||||
end
|
||||
end
|
||||
|
|
@ -368,10 +363,8 @@ RSpec.describe 'Environments page', :js, feature_category: :continuous_delivery
|
|||
it "renders the upcoming deployment", :aggregate_failures do
|
||||
visit_environments(project)
|
||||
|
||||
page.click_button _('Expand')
|
||||
|
||||
within(upcoming_deployment_content_selector) do
|
||||
expect(page).to have_content("##{deployment.iid}")
|
||||
expect(page).to have_content(project.commit.short_id)
|
||||
expect(page).to have_link(href: /#{deployment.user.username}/)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
import { initCatalog } from '~/ci/catalog/';
|
||||
import { createWrapper } from '@vue/test-utils';
|
||||
import { initCatalog } from '~/ci/catalog';
|
||||
import * as Router from '~/ci/catalog/router';
|
||||
import GlobalCatalog from '~/ci/catalog/global_catalog.vue';
|
||||
import CiResourcesPage from '~/ci/catalog/components/pages/ci_resources_page.vue';
|
||||
|
||||
describe('~/ci/catalog/index', () => {
|
||||
|
|
@ -7,7 +9,7 @@ describe('~/ci/catalog/index', () => {
|
|||
const SELECTOR = 'SELECTOR';
|
||||
|
||||
let el;
|
||||
let component;
|
||||
let wrapper;
|
||||
const baseRoute = '/explore/catalog';
|
||||
|
||||
const createElement = () => {
|
||||
|
|
@ -21,15 +23,17 @@ describe('~/ci/catalog/index', () => {
|
|||
el = null;
|
||||
});
|
||||
|
||||
const findGlobalCatalog = () => wrapper.findComponent(GlobalCatalog);
|
||||
|
||||
describe('when the element exists', () => {
|
||||
beforeEach(() => {
|
||||
createElement();
|
||||
jest.spyOn(Router, 'createRouter');
|
||||
component = initCatalog(`#${SELECTOR}`);
|
||||
wrapper = createWrapper(initCatalog(`#${SELECTOR}`));
|
||||
});
|
||||
|
||||
it('returns a Vue Instance', () => {
|
||||
expect(component.$options.name).toBe('GlobalCatalog');
|
||||
it('renders the GlobalCatalog component', () => {
|
||||
expect(findGlobalCatalog().exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('creates a router with the received base path and component', () => {
|
||||
|
|
@ -40,7 +44,7 @@ describe('~/ci/catalog/index', () => {
|
|||
|
||||
describe('When the element does not exist', () => {
|
||||
it('returns `null`', () => {
|
||||
expect(initCatalog('foo')).toBe(null);
|
||||
expect(initCatalog('foo')).toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,23 +1,12 @@
|
|||
import Vue from 'vue';
|
||||
import VueApollo from 'vue-apollo';
|
||||
import { GlLoadingIcon } from '@gitlab/ui';
|
||||
import { mountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import { useFakeDate } from 'helpers/fake_date';
|
||||
import { stubTransition } from 'helpers/stub_transition';
|
||||
import { localeDateFormat } from '~/lib/utils/datetime_utility';
|
||||
import { GlIcon, GlLink, GlTruncate, GlSprintf } from '@gitlab/ui';
|
||||
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
|
||||
import Deployment from '~/environments/components/deployment.vue';
|
||||
import Commit from '~/environments/components/commit.vue';
|
||||
import DeploymentStatusLink from '~/environments/components/deployment_status_link.vue';
|
||||
import createMockApollo from 'helpers/mock_apollo_helper';
|
||||
import waitForPromises from 'helpers/wait_for_promises';
|
||||
import getDeploymentDetails from '~/environments/graphql/queries/deployment_details.query.graphql';
|
||||
import { resolvedEnvironment, resolvedDeploymentDetails } from './graphql/mock_data';
|
||||
import { resolvedEnvironment } from './graphql/mock_data';
|
||||
|
||||
describe('~/environments/components/deployment.vue', () => {
|
||||
Vue.use(VueApollo);
|
||||
useFakeDate(2022, 0, 8, 16);
|
||||
|
||||
let deployment;
|
||||
let wrapper;
|
||||
|
||||
|
|
@ -25,32 +14,35 @@ describe('~/environments/components/deployment.vue', () => {
|
|||
deployment = resolvedEnvironment.lastDeployment;
|
||||
});
|
||||
|
||||
const createWrapper = ({ propsData = {}, options = {} } = {}) => {
|
||||
const mockApollo = createMockApollo([
|
||||
[getDeploymentDetails, jest.fn().mockResolvedValue(resolvedDeploymentDetails)],
|
||||
]);
|
||||
|
||||
return mountExtended(Deployment, {
|
||||
stubs: { transition: stubTransition() },
|
||||
const createWrapper = ({ propsData = {} } = {}) => {
|
||||
return shallowMountExtended(Deployment, {
|
||||
propsData: {
|
||||
deployment,
|
||||
visible: true,
|
||||
...propsData,
|
||||
},
|
||||
apolloProvider: mockApollo,
|
||||
provide: { projectPath: '/1' },
|
||||
...options,
|
||||
stubs: { GlTruncate, GlSprintf },
|
||||
});
|
||||
};
|
||||
|
||||
afterEach(() => {
|
||||
wrapper?.destroy();
|
||||
});
|
||||
const findStatusLink = () => wrapper.findComponent(DeploymentStatusLink);
|
||||
const findLatestBadge = () => wrapper.findByText('Latest Deployed');
|
||||
const findApprovalBadge = () => wrapper.findByText('Needs Approval');
|
||||
const findCommit = () => wrapper.findComponent(Commit);
|
||||
const findShortSha = () => wrapper.findByTestId('deployment-commit-sha');
|
||||
const findCopyButton = () => wrapper.findComponent(ClipboardButton);
|
||||
const findShortShaLink = () => findShortSha().findComponent(GlLink);
|
||||
const findShortShaIcon = () => findShortSha().findComponent(GlIcon);
|
||||
const findTag = () => wrapper.findByTestId('deployment-tag');
|
||||
const findTagLink = () => findTag().findComponent(GlLink);
|
||||
const findTagIcon = () => findTag().findComponent(GlIcon);
|
||||
const findTimestamp = () => wrapper.findByTestId('deployment-timestamp');
|
||||
const findTriggerer = () => wrapper.findByTestId('deployment-triggerer');
|
||||
const findUserLink = () => findTriggerer().findComponent(GlLink);
|
||||
|
||||
describe('status', () => {
|
||||
it('should pass the deployable status to the link', () => {
|
||||
wrapper = createWrapper();
|
||||
expect(wrapper.findComponent(DeploymentStatusLink).props()).toEqual({
|
||||
expect(findStatusLink().props()).toEqual({
|
||||
status: deployment.status,
|
||||
deploymentJob: deployment.deployable,
|
||||
deployment,
|
||||
|
|
@ -62,53 +54,52 @@ describe('~/environments/components/deployment.vue', () => {
|
|||
it('should show a badge if the deployment is latest', () => {
|
||||
wrapper = createWrapper({ propsData: { latest: true } });
|
||||
|
||||
const badge = wrapper.findByText('Latest Deployed');
|
||||
|
||||
expect(badge.exists()).toBe(true);
|
||||
expect(findLatestBadge().exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('should not show a badge if the deployment is not latest', () => {
|
||||
wrapper = createWrapper();
|
||||
|
||||
const badge = wrapper.findByText('Latest Deployed');
|
||||
|
||||
expect(badge.exists()).toBe(false);
|
||||
expect(findLatestBadge().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('iid', () => {
|
||||
const findIid = () => wrapper.findByTitle('Deployment ID');
|
||||
const findDeploymentIcon = () => wrapper.findComponent({ ref: 'deployment-iid-icon' });
|
||||
describe('approval badge', () => {
|
||||
it('should show a badge if the deployment needs approval', () => {
|
||||
wrapper = createWrapper({
|
||||
propsData: { deployment: { ...deployment, pendingApprovalCount: 5 } },
|
||||
});
|
||||
|
||||
describe('is present', () => {
|
||||
expect(findApprovalBadge().exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('should not show a badge if the deployment does not need approval', () => {
|
||||
wrapper = createWrapper();
|
||||
|
||||
expect(findApprovalBadge().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('commit message', () => {
|
||||
describe('with commit', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = createWrapper();
|
||||
});
|
||||
|
||||
it('should show the iid', () => {
|
||||
const iid = findIid();
|
||||
expect(iid.exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('should show an icon for the iid', () => {
|
||||
const deploymentIcon = findDeploymentIcon();
|
||||
expect(deploymentIcon.props('name')).toBe('deployments');
|
||||
it('shows the commit component', () => {
|
||||
expect(findCommit().props('commit')).toBe(deployment.commit);
|
||||
});
|
||||
});
|
||||
|
||||
describe('is not present', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = createWrapper({ propsData: { deployment: { ...deployment, iid: '' } } });
|
||||
});
|
||||
describe('without a commit', () => {
|
||||
it('displays nothing', () => {
|
||||
const noCommit = {
|
||||
...deployment,
|
||||
commit: null,
|
||||
};
|
||||
wrapper = createWrapper({ propsData: { deployment: noCommit } });
|
||||
|
||||
it('should not show the iid', () => {
|
||||
const iid = findIid();
|
||||
expect(iid.exists()).toBe(false);
|
||||
});
|
||||
|
||||
it('should not show an icon for the iid', () => {
|
||||
const deploymentIcon = findDeploymentIcon();
|
||||
expect(deploymentIcon.exists()).toBe(false);
|
||||
expect(findCommit().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -120,21 +111,16 @@ describe('~/environments/components/deployment.vue', () => {
|
|||
});
|
||||
|
||||
it('shows the short SHA for the commit of the deployment', () => {
|
||||
const sha = wrapper.findByRole('link', { name: 'Commit SHA' });
|
||||
|
||||
expect(sha.exists()).toBe(true);
|
||||
expect(sha.text()).toBe(deployment.commit.shortId);
|
||||
expect(sha.attributes('href')).toBe(deployment.commit.commitPath);
|
||||
expect(findShortShaLink().text()).toBe(deployment.commit.shortId);
|
||||
expect(findShortShaLink().attributes('href')).toBe(deployment.commit.commitPath);
|
||||
});
|
||||
|
||||
it('shows the commit icon', () => {
|
||||
const icon = wrapper.findComponent({ ref: 'deployment-commit-icon' });
|
||||
expect(icon.props('name')).toBe('commit');
|
||||
expect(findShortShaIcon().props('name')).toBe('commit');
|
||||
});
|
||||
|
||||
it('shows a copy button for the sha', () => {
|
||||
const button = wrapper.findComponent(ClipboardButton);
|
||||
expect(button.props()).toMatchObject({
|
||||
expect(findCopyButton().props()).toMatchObject({
|
||||
text: deployment.commit.shortId,
|
||||
title: 'Copy commit SHA',
|
||||
});
|
||||
|
|
@ -151,144 +137,98 @@ describe('~/environments/components/deployment.vue', () => {
|
|||
},
|
||||
},
|
||||
});
|
||||
const sha = wrapper.findByTestId('deployment-commit-sha');
|
||||
expect(sha.exists()).toBe(false);
|
||||
expect(findShortSha().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('deployedAt', () => {
|
||||
describe('is present', () => {
|
||||
it('shows the timestamp the deployment was deployed at', () => {
|
||||
wrapper = createWrapper();
|
||||
const date = wrapper.findByTestId('deployment-timestamp');
|
||||
expect(date.text()).toBe('Deployed 1 day ago');
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('created at time', () => {
|
||||
describe('is present and deploymentAt is null', () => {
|
||||
it('shows the timestamp the deployment was created at', () => {
|
||||
wrapper = createWrapper({ propsData: { deployment: { ...deployment, deployedAt: null } } });
|
||||
|
||||
const date = wrapper.findByTestId('deployment-timestamp');
|
||||
expect(date.text()).toBe('Created 1 day ago');
|
||||
describe('tag', () => {
|
||||
describe('is present', () => {
|
||||
const ref = {
|
||||
name: 'v1.0.0',
|
||||
refPath: '/tags/v1.0.0',
|
||||
};
|
||||
beforeEach(() => {
|
||||
const deploymentWithTag = {
|
||||
...deployment,
|
||||
tag: true,
|
||||
ref,
|
||||
};
|
||||
wrapper = createWrapper({
|
||||
propsData: {
|
||||
deployment: deploymentWithTag,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('shows tag information', () => {
|
||||
expect(findTagLink().text()).toBe(ref.name);
|
||||
expect(findTagLink().attributes('href')).toBe(ref.refPath);
|
||||
});
|
||||
|
||||
it('displays the tag icon', () => {
|
||||
expect(findTagIcon().props('name')).toBe('tag');
|
||||
});
|
||||
});
|
||||
|
||||
describe('is not present', () => {
|
||||
it('does not show the tag', () => {
|
||||
wrapper = createWrapper();
|
||||
expect(findTag().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('triggered text', () => {
|
||||
it('shows the timestamp the deployment was created at if deployedAt is null', () => {
|
||||
wrapper = createWrapper({
|
||||
propsData: { deployment: { ...deployment, deployedAt: null } },
|
||||
});
|
||||
expect(findTimestamp().text()).toBe('January 7, 2022 at 3:46:27 PM GMT');
|
||||
});
|
||||
|
||||
it('shows the timestamp the deployment was deployed at if deployedAt is present', () => {
|
||||
wrapper = createWrapper();
|
||||
expect(findTimestamp().text()).toBe('January 7, 2022 at 3:47:32 PM GMT');
|
||||
});
|
||||
|
||||
describe('is not present', () => {
|
||||
it('does not show the timestamp', () => {
|
||||
wrapper = createWrapper({ propsData: { deployment: { ...deployment, createdAt: null } } });
|
||||
const date = wrapper.findByTitle(
|
||||
localeDateFormat.asDateTimeFull.format(deployment.createdAt),
|
||||
);
|
||||
wrapper = createWrapper({
|
||||
propsData: { deployment: { ...deployment, createdAt: null, deployedAt: null } },
|
||||
});
|
||||
|
||||
expect(date.exists()).toBe(false);
|
||||
expect(findTimestamp().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('commit message', () => {
|
||||
describe('with commit', () => {
|
||||
describe('deployment user', () => {
|
||||
describe('is present', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = createWrapper();
|
||||
});
|
||||
|
||||
it('shows the commit component', () => {
|
||||
const commit = wrapper.findComponent(Commit);
|
||||
expect(commit.props('commit')).toBe(deployment.commit);
|
||||
it('shows triggerer information', () => {
|
||||
expect(findUserLink().text()).toBe('@root');
|
||||
expect(findUserLink().attributes('href')).toBe('/root');
|
||||
});
|
||||
});
|
||||
|
||||
describe('without a commit', () => {
|
||||
it('displays nothing', () => {
|
||||
const noCommit = {
|
||||
...deployment,
|
||||
commit: null,
|
||||
};
|
||||
wrapper = createWrapper({ propsData: { deployment: noCommit } });
|
||||
describe('is not present', () => {
|
||||
const deploymentWithoutUser = {
|
||||
...deployment,
|
||||
user: null,
|
||||
};
|
||||
|
||||
const commit = wrapper.findComponent(Commit);
|
||||
expect(commit.exists()).toBe(false);
|
||||
it('does not show the tag', () => {
|
||||
wrapper = createWrapper({
|
||||
propsData: {
|
||||
deployment: deploymentWithoutUser,
|
||||
},
|
||||
});
|
||||
expect(findTriggerer().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('details', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = createWrapper();
|
||||
});
|
||||
|
||||
it('shows information about the deployment', () => {
|
||||
const username = wrapper.findByRole('link', { name: `@${deployment.user.username}` });
|
||||
|
||||
expect(username.attributes('href')).toBe(deployment.user.path);
|
||||
const job = wrapper.findByRole('link', { name: deployment.deployable.name });
|
||||
expect(job.attributes('href')).toBe(deployment.deployable.buildPath);
|
||||
const apiBadge = wrapper.findByText('API');
|
||||
expect(apiBadge.exists()).toBe(false);
|
||||
|
||||
const branchLabel = wrapper.findByText('Branch');
|
||||
expect(branchLabel.exists()).toBe(true);
|
||||
const tagLabel = wrapper.findByText('Tag');
|
||||
expect(tagLabel.exists()).toBe(false);
|
||||
const ref = wrapper.findByRole('link', { name: deployment.ref.name });
|
||||
expect(ref.attributes('href')).toBe(deployment.ref.refPath);
|
||||
});
|
||||
|
||||
it('shows information about tags related to the deployment', async () => {
|
||||
expect(wrapper.findByText('Tags').exists()).toBe(true);
|
||||
expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(true);
|
||||
|
||||
await waitForPromises();
|
||||
|
||||
for (let i = 1; i < 6; i += 1) {
|
||||
const tagName = `testTag${i}`;
|
||||
const testTag = wrapper.findByText(tagName);
|
||||
expect(testTag.exists()).toBe(true);
|
||||
expect(testTag.attributes('href')).toBe(`tags/${tagName}`);
|
||||
}
|
||||
expect(wrapper.findByText('testTag6').exists()).toBe(false);
|
||||
expect(wrapper.findByText('Tag').exists()).toBe(false);
|
||||
// with more than 5 tags, show overflow marker
|
||||
expect(wrapper.findByText('...').exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with tagged deployment', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = createWrapper({ propsData: { deployment: { ...deployment, tag: true } } });
|
||||
});
|
||||
|
||||
it('shows tags instead of branch', () => {
|
||||
const refLabel = wrapper.findByText('Tags');
|
||||
expect(refLabel.exists()).toBe(true);
|
||||
|
||||
const branchLabel = wrapper.findByText('Branch');
|
||||
expect(branchLabel.exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with API deployment', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = createWrapper({ propsData: { deployment: { ...deployment, deployable: null } } });
|
||||
});
|
||||
|
||||
it('shows API instead of a job name', () => {
|
||||
const apiBadge = wrapper.findByText('API');
|
||||
expect(apiBadge.exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
describe('without a job path', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = createWrapper({
|
||||
propsData: {
|
||||
deployment: { ...deployment, deployable: { name: deployment.deployable.name } },
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('shows a span instead of a link', () => {
|
||||
const job = wrapper.findByTitle(deployment.deployable.name);
|
||||
expect(job.attributes('href')).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -195,6 +195,16 @@ describe('~/environments/components/environments_app.vue', () => {
|
|||
expect(text).toContainEqual(expect.stringMatching('production'));
|
||||
});
|
||||
|
||||
it('should show environments table headers when there are environments are present', async () => {
|
||||
await createWrapperWithMocked({
|
||||
environmentsApp: resolvedEnvironmentsApp,
|
||||
folder: resolvedFolder,
|
||||
});
|
||||
|
||||
const tableHeaders = wrapper.findByTestId('environments-table-header');
|
||||
expect(tableHeaders.text()).toBe('Name Deployments Actions');
|
||||
});
|
||||
|
||||
it('should show an empty state with no environments', async () => {
|
||||
await createWrapperWithMocked({
|
||||
environmentsApp: { ...resolvedEnvironmentsApp, environments: [] },
|
||||
|
|
@ -203,6 +213,15 @@ describe('~/environments/components/environments_app.vue', () => {
|
|||
expect(wrapper.findComponent(EmptyState).exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('should not show environments table headers with no environment', async () => {
|
||||
await createWrapperWithMocked({
|
||||
environmentsApp: { ...resolvedEnvironmentsApp, environments: [] },
|
||||
});
|
||||
|
||||
const tableHeaders = wrapper.findByTestId('environments-table-header');
|
||||
expect(tableHeaders.exists()).toBe(false);
|
||||
});
|
||||
|
||||
it('should show a button to create a new environment', async () => {
|
||||
await createWrapperWithMocked({
|
||||
environmentsApp: resolvedEnvironmentsApp,
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ describe('EnvironmentsFolderAppComponent', () => {
|
|||
await waitForPromises();
|
||||
});
|
||||
|
||||
it('should list environmnets in folder', () => {
|
||||
it('should list environments in folder', () => {
|
||||
const items = findEnvironmentItems();
|
||||
expect(items.length).toBe(resolvedFolder.environments.length);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -555,7 +555,7 @@ export const resolvedEnvironment = {
|
|||
sha: 'f3ba6dd84f8f891373e9b869135622b954852db1',
|
||||
ref: { name: 'main', refPath: '/h5bp/html5-boilerplate/-/tree/main' },
|
||||
status: 'success',
|
||||
createdAt: '2022-01-07T15:47:27.415Z',
|
||||
createdAt: '2022-01-07T15:46:27.415Z',
|
||||
deployedAt: '2022-01-07T15:47:32.450Z',
|
||||
tierInYaml: 'staging',
|
||||
tag: false,
|
||||
|
|
@ -870,7 +870,7 @@ export const resolvedEnvironmentToRollback = {
|
|||
sha: 'f3ba6dd84f8f891373e9b869135622b954852db1',
|
||||
ref: { name: 'main', refPath: '/h5bp/html5-boilerplate/-/tree/main' },
|
||||
status: 'success',
|
||||
createdAt: '2022-01-07T15:47:27.415Z',
|
||||
createdAt: '2022-01-07T15:46:27.415Z',
|
||||
deployedAt: '2022-01-07T15:47:32.450Z',
|
||||
tierInYaml: 'staging',
|
||||
tag: false,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import VueApollo from 'vue-apollo';
|
||||
import Vue from 'vue';
|
||||
import { GlCollapse, GlLink, GlSprintf, GlButton } from '@gitlab/ui';
|
||||
import { GlLink, GlSprintf } from '@gitlab/ui';
|
||||
import createMockApollo from 'helpers/mock_apollo_helper';
|
||||
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import waitForPromises from 'helpers/wait_for_promises';
|
||||
|
|
@ -36,18 +36,13 @@ describe('~/environments/components/new_environment_item.vue', () => {
|
|||
projectPath: '/1',
|
||||
...provideData,
|
||||
},
|
||||
stubs: { GlSprintf, TimeAgoTooltip, GlCollapse },
|
||||
stubs: { GlSprintf, TimeAgoTooltip },
|
||||
});
|
||||
|
||||
const findDeployment = () => wrapper.findComponent(Deployment);
|
||||
const findActions = () => wrapper.findComponent(EnvironmentActions);
|
||||
const findNameLink = () => wrapper.findComponent(GlLink);
|
||||
const findCollapse = () => wrapper.findComponent(GlCollapse);
|
||||
|
||||
const expandCollapsedSection = async () => {
|
||||
const button = wrapper.findComponent(GlButton);
|
||||
await button.vm.$emit('click');
|
||||
};
|
||||
const findEmptyState = () => wrapper.findByTestId('deployments-empty-state');
|
||||
|
||||
it('displays the name when not in a folder', () => {
|
||||
wrapper = createWrapper({ apolloProvider: createApolloProvider() });
|
||||
|
|
@ -315,31 +310,6 @@ describe('~/environments/components/new_environment_item.vue', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('collapse', () => {
|
||||
const findCollapseButton = () => wrapper.findComponent(GlButton);
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = createWrapper({ apolloProvider: createApolloProvider() });
|
||||
});
|
||||
|
||||
it('is collapsed by default', () => {
|
||||
expect(findCollapse().props('visible')).toBe(false);
|
||||
expect(findCollapseButton().props('icon')).toBe('chevron-lg-right');
|
||||
expect(findNameLink().classes('gl-font-bold')).toBe(false);
|
||||
});
|
||||
|
||||
it('opens on click', async () => {
|
||||
expect(findDeployment().props('visible')).toBe(false);
|
||||
|
||||
await expandCollapsedSection();
|
||||
|
||||
expect(findCollapseButton().attributes('aria-label')).toBe('Collapse');
|
||||
expect(findCollapseButton().props('icon')).toBe('chevron-lg-down');
|
||||
expect(findNameLink().classes('gl-font-bold')).toBe(true);
|
||||
expect(findCollapse().props('visible')).toBe(true);
|
||||
expect(findDeployment().props('visible')).toBe(true);
|
||||
});
|
||||
});
|
||||
describe('last deployment', () => {
|
||||
it('should pass the last deployment to the deployment component when it exists', () => {
|
||||
wrapper = createWrapper({ apolloProvider: createApolloProvider() });
|
||||
|
|
@ -373,7 +343,7 @@ describe('~/environments/components/new_environment_item.vue', () => {
|
|||
});
|
||||
|
||||
const deployment = findDeployment();
|
||||
expect(deployment.props('deployment')).toEqual(upcomingDeployment);
|
||||
expect(deployment.props('deployment')).toMatchObject(upcomingDeployment);
|
||||
});
|
||||
it('should not show the upcoming deployment when it is missing', () => {
|
||||
const environment = {
|
||||
|
|
@ -393,7 +363,7 @@ describe('~/environments/components/new_environment_item.vue', () => {
|
|||
});
|
||||
|
||||
describe('empty state', () => {
|
||||
it('should link to documentation', async () => {
|
||||
it('should link to documentation', () => {
|
||||
const environment = {
|
||||
...resolvedEnvironment,
|
||||
lastDeployment: null,
|
||||
|
|
@ -405,27 +375,23 @@ describe('~/environments/components/new_environment_item.vue', () => {
|
|||
apolloProvider: createApolloProvider(),
|
||||
});
|
||||
|
||||
await expandCollapsedSection();
|
||||
|
||||
expect(findCollapse().text()).toBe(
|
||||
expect(findEmptyState().text()).toBe(
|
||||
'There are no deployments for this environment yet. Learn more about setting up deployments.',
|
||||
);
|
||||
expect(findCollapse().findComponent(GlLink).attributes('href')).toBe('/help');
|
||||
expect(findEmptyState().findComponent(GlLink).attributes('href')).toBe('/help');
|
||||
});
|
||||
|
||||
it('should not link to the documentation when there are deployments', async () => {
|
||||
it('should not show empty state when there are deployments', () => {
|
||||
wrapper = createWrapper({
|
||||
apolloProvider: createApolloProvider(),
|
||||
});
|
||||
|
||||
await expandCollapsedSection();
|
||||
|
||||
expect(findCollapse().findComponent(GlLink).exists()).toBe(false);
|
||||
expect(findEmptyState().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('deploy boards', () => {
|
||||
it('should show a deploy board if the environment has a rollout status', async () => {
|
||||
it('should show a deploy board if the environment has a rollout status', () => {
|
||||
const environment = {
|
||||
...resolvedEnvironment,
|
||||
rolloutStatus,
|
||||
|
|
@ -436,20 +402,15 @@ describe('~/environments/components/new_environment_item.vue', () => {
|
|||
apolloProvider: createApolloProvider(),
|
||||
});
|
||||
|
||||
await expandCollapsedSection();
|
||||
|
||||
const deployBoard = wrapper.findComponent(DeployBoardWrapper);
|
||||
expect(deployBoard.exists()).toBe(true);
|
||||
expect(deployBoard.props('rolloutStatus')).toBe(rolloutStatus);
|
||||
});
|
||||
|
||||
it('should not show a deploy board if the environment has no rollout status', async () => {
|
||||
it('should not show a deploy board if the environment has no rollout status', () => {
|
||||
wrapper = createWrapper({
|
||||
apolloProvider: createApolloProvider(),
|
||||
});
|
||||
|
||||
await expandCollapsedSection();
|
||||
|
||||
const deployBoard = wrapper.findComponent(DeployBoardWrapper);
|
||||
expect(deployBoard.exists()).toBe(false);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,23 +1,42 @@
|
|||
import Vue from 'vue';
|
||||
import { resetHTMLFixture, setHTMLFixture } from 'helpers/fixtures';
|
||||
import initDeleteTagModal from '../../../app/assets/javascripts/tags/init_delete_tag_modal';
|
||||
import { createWrapper } from '@vue/test-utils';
|
||||
|
||||
import initDeleteTagModal from '~/tags/init_delete_tag_modal';
|
||||
import DeleteTagModal from '~/tags/components/delete_tag_modal.vue';
|
||||
|
||||
describe('initDeleteTagModal', () => {
|
||||
beforeEach(() => {
|
||||
setHTMLFixture('<div class="js-delete-tag-modal"></div>');
|
||||
});
|
||||
let appRoot;
|
||||
let wrapper;
|
||||
|
||||
const createAppRoot = () => {
|
||||
appRoot = document.createElement('div');
|
||||
appRoot.setAttribute('class', 'js-delete-tag-modal');
|
||||
document.body.appendChild(appRoot);
|
||||
|
||||
wrapper = createWrapper(initDeleteTagModal());
|
||||
};
|
||||
|
||||
afterEach(() => {
|
||||
resetHTMLFixture();
|
||||
if (appRoot) {
|
||||
appRoot.remove();
|
||||
appRoot = null;
|
||||
}
|
||||
});
|
||||
|
||||
it('should mount the delete tag modal', () => {
|
||||
expect(initDeleteTagModal()).toBeInstanceOf(Vue);
|
||||
expect(document.querySelector('.js-delete-tag-modal')).toBeNull();
|
||||
const findDeleteTagModal = () => wrapper.findComponent(DeleteTagModal);
|
||||
|
||||
describe('when there is no app root', () => {
|
||||
it('returns false', () => {
|
||||
expect(initDeleteTagModal()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return false if the mounting element is missing', () => {
|
||||
document.querySelector('.js-delete-tag-modal').remove();
|
||||
expect(initDeleteTagModal()).toBe(false);
|
||||
describe('when there is an app root', () => {
|
||||
beforeEach(() => {
|
||||
createAppRoot();
|
||||
});
|
||||
|
||||
it('renders the modal', () => {
|
||||
expect(findDeleteTagModal().exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -29,7 +29,8 @@ RSpec.describe Gitlab::Database::NamespaceProjectIdsEachBatch, feature_category:
|
|||
end
|
||||
|
||||
context 'when passed an optional resolver' do
|
||||
it 'returns the correct project IDs filtered by resolver' do
|
||||
it 'returns the correct project IDs filtered by resolver',
|
||||
quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/497833' do
|
||||
resolver = ->(batch) {
|
||||
Project.where(id: batch).where(path: [project1.path, project2.path]).pluck_primary_key
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Database::Sos::Output, feature_category: :database do
|
||||
let(:temp_directory) { Dir.mktmpdir }
|
||||
let(:zip_path) { File.join(temp_directory, 'test.zip') }
|
||||
let(:directory_path) { File.join(temp_directory, 'test_directory') }
|
||||
|
||||
after do
|
||||
FileUtils.remove_entry(temp_directory)
|
||||
end
|
||||
|
||||
describe '#writing' do
|
||||
it 'yields an output object and ensures finish is called' do
|
||||
expect_next_instance_of(described_class) do |instance|
|
||||
expect(instance).to receive(:finish)
|
||||
end
|
||||
|
||||
described_class.writing(zip_path, mode: :zip) do |output|
|
||||
expect(output).to be_a(described_class)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#initialize' do
|
||||
it 'raises an error for invalid mode' do
|
||||
expect { described_class.new(zip_path, mode: :invalid) }
|
||||
.to raise_error(RuntimeError, "mode must be one of :zip, :directory")
|
||||
end
|
||||
end
|
||||
|
||||
describe '#write_file' do
|
||||
let(:relative_path) { 'test/file.txt' }
|
||||
let(:content) { 'PG Settings' }
|
||||
|
||||
it 'writes content to a file in zip mode' do
|
||||
described_class.writing(zip_path, mode: :zip) do |output|
|
||||
output.write_file(relative_path) { |f| f.write(content) }
|
||||
end
|
||||
|
||||
Zip::File.open(zip_path) do |zip_file|
|
||||
expect(zip_file.read(relative_path)).to eq(content)
|
||||
end
|
||||
end
|
||||
|
||||
it 'writes content to a file in directory mode' do
|
||||
described_class.writing(directory_path, mode: :directory) do |output|
|
||||
output.write_file(relative_path) { |f| f.write(content) }
|
||||
end
|
||||
|
||||
expect(File.read(File.join(directory_path, relative_path))).to eq(content)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Database::Sos::ShowAllSettings, feature_category: :database do
|
||||
describe '#run' do
|
||||
let(:temp_directory) { Dir.mktmpdir }
|
||||
let(:output_file_path) { temp_directory }
|
||||
let(:expected_file_path) { File.join(temp_directory, 'pg_settings.csv') }
|
||||
let(:output) { Gitlab::Database::Sos::Output.new(output_file_path, mode: :directory) }
|
||||
|
||||
after do
|
||||
FileUtils.remove_entry(temp_directory)
|
||||
end
|
||||
|
||||
it 'creates a CSV file with the correct headers and data' do
|
||||
described_class.run(output)
|
||||
output.finish
|
||||
|
||||
expect(File.exist?(expected_file_path)).to be true
|
||||
|
||||
csv_content = CSV.read(expected_file_path)
|
||||
|
||||
expect(csv_content.first).to eq(%w[name setting description])
|
||||
|
||||
block_size_row = csv_content.find { |row| row[0] == 'block_size' }
|
||||
|
||||
expect(block_size_row).not_to be_nil
|
||||
# NOTE: 8192 bytes is the default value for the block size in Postgres so
|
||||
# it's safe to say this value will not change for us.
|
||||
expect(block_size_row[1]).to eq('8192')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -5,8 +5,15 @@ require 'spec_helper'
|
|||
# WIP
|
||||
RSpec.describe Gitlab::Database::Sos, feature_category: :database do
|
||||
describe '#run' do
|
||||
let(:temp_directory) { Dir.mktmpdir }
|
||||
let(:output_file_path) { temp_directory }
|
||||
|
||||
after do
|
||||
FileUtils.remove_entry(temp_directory)
|
||||
end
|
||||
|
||||
it "executes sos" do
|
||||
result = described_class.run
|
||||
result = described_class.run(output_file_path)
|
||||
expect(result).to eq(Gitlab::Database::Sos::TASKS)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -308,73 +308,113 @@ RSpec.describe Packages::Protection::Rule, type: :model, feature_category: :pack
|
|||
end
|
||||
end
|
||||
|
||||
describe '.for_push_exists_for_multiple_packages' do
|
||||
let_it_be(:project_with_ppr) { create(:project) }
|
||||
|
||||
let_it_be(:ppr_for_maintainer) do
|
||||
describe '.for_push_exists_for_projects_and_packages' do
|
||||
let_it_be(:project1) { create(:project) }
|
||||
let_it_be(:project1_ppr) do
|
||||
create(:package_protection_rule,
|
||||
package_name_pattern: '@my-scope/my-package-prod*',
|
||||
project: project_with_ppr,
|
||||
project: project1,
|
||||
package_type: :npm
|
||||
)
|
||||
end
|
||||
|
||||
let(:package_names) {
|
||||
%w[
|
||||
@my-scope/my-package-prod-1
|
||||
@my-scope/my-package-prod-unmatched-package-type
|
||||
@my-scope/unmatched-package-name
|
||||
@my-scope/unmatched-package-name-and-package-type
|
||||
]
|
||||
}
|
||||
let_it_be(:project2) { create(:project) }
|
||||
let_it_be(:project2_ppr) do create(:package_protection_rule, project: project2) end
|
||||
|
||||
let(:package_types) do
|
||||
let_it_be(:unprotected_project) { create(:project) }
|
||||
|
||||
let(:package_type_npm) { Packages::Package.package_types[:npm] }
|
||||
|
||||
let(:single_project_input) do
|
||||
[
|
||||
Packages::Package.package_types[:npm],
|
||||
Packages::Package.package_types[:maven],
|
||||
Packages::Package.package_types[:npm],
|
||||
Packages::Package.package_types[:maven]
|
||||
[project1.id, '@my-scope/my-package-prod-1', Packages::Package.package_types[:npm]],
|
||||
[project1.id, '@my-scope/my-package-prod-unmatched-package-type', Packages::Package.package_types[:maven]],
|
||||
[project1.id, '@my-scope/unmatched-package-name', Packages::Package.package_types[:npm]],
|
||||
[project1.id, '@my-scope/unmatched-package-name-and-package-type', Packages::Package.package_types[:maven]]
|
||||
]
|
||||
end
|
||||
|
||||
subject do
|
||||
described_class
|
||||
.for_push_exists_for_multiple_packages(
|
||||
project_id: project_with_ppr.id,
|
||||
package_names: package_names,
|
||||
package_types: package_types
|
||||
)
|
||||
.to_a
|
||||
let(:single_project_expected_result) do
|
||||
[
|
||||
{ 'project_id' => project1.id,
|
||||
'package_name' => '@my-scope/my-package-prod-1',
|
||||
'package_type' => Packages::Package.package_types[:npm],
|
||||
'protected' => true },
|
||||
{ 'project_id' => project1.id,
|
||||
'package_name' => '@my-scope/my-package-prod-unmatched-package-type',
|
||||
'package_type' => Packages::Package.package_types[:maven],
|
||||
'protected' => false },
|
||||
{ 'project_id' => project1.id,
|
||||
'package_name' => '@my-scope/unmatched-package-name',
|
||||
'package_type' => Packages::Package.package_types[:npm],
|
||||
'protected' => false },
|
||||
{ 'project_id' => project1.id,
|
||||
'package_name' => '@my-scope/unmatched-package-name-and-package-type',
|
||||
'package_type' => Packages::Package.package_types[:maven],
|
||||
'protected' => false }
|
||||
]
|
||||
end
|
||||
|
||||
it do
|
||||
is_expected.to eq([
|
||||
{ "package_name" => '@my-scope/my-package-prod-1',
|
||||
"package_type" => Packages::Package.package_types[:npm],
|
||||
"protected" => true },
|
||||
{ "package_name" => '@my-scope/my-package-prod-unmatched-package-type',
|
||||
"package_type" => Packages::Package.package_types[:maven],
|
||||
"protected" => false },
|
||||
{ "package_name" => '@my-scope/unmatched-package-name',
|
||||
"package_type" => Packages::Package.package_types[:npm],
|
||||
"protected" => false },
|
||||
{ "package_name" => '@my-scope/unmatched-package-name-and-package-type',
|
||||
"package_type" => Packages::Package.package_types[:maven],
|
||||
"protected" => false }
|
||||
])
|
||||
let(:multi_projects_input) do
|
||||
[
|
||||
*single_project_input,
|
||||
[project2.id, project2_ppr.package_name_pattern, Packages::Package.package_types[project2_ppr.package_type]],
|
||||
[project2.id, "#{project2_ppr.package_name_pattern}-unprotected",
|
||||
Packages::Package.package_types[project2_ppr.package_type]]
|
||||
]
|
||||
end
|
||||
|
||||
context 'when edge cases' do
|
||||
where(:package_names, :package_types, :expected_result) do
|
||||
nil | nil | []
|
||||
[] | [] | []
|
||||
nil | [] | []
|
||||
%w[@my-scope/my-package-prod-1] | [] | []
|
||||
end
|
||||
let(:multi_projects_expected_result) do
|
||||
[
|
||||
*single_project_expected_result,
|
||||
{ 'project_id' => project2.id,
|
||||
'package_name' => project2_ppr.package_name_pattern,
|
||||
'package_type' => Packages::Package.package_types[project2_ppr.package_type],
|
||||
'protected' => true },
|
||||
{ 'project_id' => project2.id,
|
||||
'package_name' => "#{project2_ppr.package_name_pattern}-unprotected",
|
||||
'package_type' => Packages::Package.package_types[project2_ppr.package_type],
|
||||
'protected' => false }
|
||||
]
|
||||
end
|
||||
|
||||
with_them do
|
||||
it { is_expected.to eq([]) }
|
||||
end
|
||||
let(:unprotected_projects_input) do
|
||||
[
|
||||
*multi_projects_input,
|
||||
[unprotected_project.id, "#{unprotected_project.full_path}-unprotected1", package_type_npm],
|
||||
[unprotected_project.id, "#{unprotected_project.full_path}-unprotected2", package_type_npm]
|
||||
]
|
||||
end
|
||||
|
||||
let(:unprotected_projects_expected_result) do
|
||||
[
|
||||
*multi_projects_expected_result,
|
||||
{ 'project_id' => unprotected_project.id,
|
||||
'package_name' => "#{unprotected_project.full_path}-unprotected1",
|
||||
'package_type' => package_type_npm,
|
||||
'protected' => false },
|
||||
{ 'project_id' => unprotected_project.id,
|
||||
'package_name' => "#{unprotected_project.full_path}-unprotected2",
|
||||
'package_type' => package_type_npm,
|
||||
'protected' => false }
|
||||
]
|
||||
end
|
||||
|
||||
subject { described_class.for_push_exists_for_projects_and_packages(projects_and_packages).to_a }
|
||||
|
||||
# rubocop:disable Layout/LineLength -- Avoid formatting to ensure one-line table syntax
|
||||
where(:projects_and_packages, :expected_result) do
|
||||
ref(:single_project_input) | ref(:single_project_expected_result)
|
||||
ref(:multi_projects_input) | ref(:multi_projects_expected_result)
|
||||
ref(:unprotected_projects_input) | ref(:unprotected_projects_expected_result)
|
||||
nil | []
|
||||
[] | []
|
||||
[[nil, nil, nil]] | [{ "package_name" => nil, "package_type" => nil, "project_id" => nil, "protected" => false }]
|
||||
end
|
||||
# rubocop:enable Layout/LineLength
|
||||
|
||||
with_them do
|
||||
it { is_expected.to match_array expected_result }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -18,10 +18,16 @@ RSpec.describe VirtualRegistries::Packages::Maven::CachedResponse, type: :model,
|
|||
it { is_expected.to validate_presence_of(attr) }
|
||||
end
|
||||
|
||||
%i[relative_path upstream_etag content_type].each do |attr|
|
||||
%i[upstream_etag content_type].each do |attr|
|
||||
it { is_expected.to validate_length_of(attr).is_at_most(255) }
|
||||
end
|
||||
it { is_expected.to validate_length_of(:file_final_path).is_at_most(1024) }
|
||||
|
||||
%i[relative_path object_storage_key file_final_path].each do |attr|
|
||||
it { is_expected.to validate_length_of(attr).is_at_most(1024) }
|
||||
end
|
||||
|
||||
it { is_expected.to validate_length_of(:file_md5).is_equal_to(32).allow_nil }
|
||||
it { is_expected.to validate_length_of(:file_sha1).is_equal_to(40) }
|
||||
|
||||
context 'with persisted cached response' do
|
||||
before do
|
||||
|
|
@ -30,20 +36,6 @@ RSpec.describe VirtualRegistries::Packages::Maven::CachedResponse, type: :model,
|
|||
|
||||
it { is_expected.to validate_uniqueness_of(:relative_path).scoped_to(:upstream_id, :status) }
|
||||
|
||||
context 'when upstream_id is nil' do
|
||||
let(:new_cached_response) { build(:virtual_registries_packages_maven_cached_response) }
|
||||
|
||||
before do
|
||||
cached_response.update!(upstream_id: nil)
|
||||
new_cached_response.upstream = nil
|
||||
end
|
||||
|
||||
it 'does not validate uniqueness of relative_path' do
|
||||
new_cached_response.validate
|
||||
expect(new_cached_response.errors.messages_for(:relative_path)).not_to include 'has already been taken'
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a similar cached response in a different status' do
|
||||
let!(:cached_response_in_error) do
|
||||
create(
|
||||
|
|
@ -77,6 +69,7 @@ RSpec.describe VirtualRegistries::Packages::Maven::CachedResponse, type: :model,
|
|||
it 'belongs to an upstream' do
|
||||
is_expected.to belong_to(:upstream)
|
||||
.class_name('VirtualRegistries::Packages::Maven::Upstream')
|
||||
.required
|
||||
.inverse_of(:cached_responses)
|
||||
end
|
||||
end
|
||||
|
|
@ -116,12 +109,12 @@ RSpec.describe VirtualRegistries::Packages::Maven::CachedResponse, type: :model,
|
|||
end
|
||||
|
||||
it 'can not be too large' do
|
||||
cached_response.object_storage_key = 'a' * 256
|
||||
cached_response.object_storage_key = 'a' * 1025
|
||||
cached_response.relative_path = nil
|
||||
|
||||
expect(cached_response).to be_invalid
|
||||
expect(cached_response.errors.full_messages)
|
||||
.to include('Object storage key is too long (maximum is 255 characters)')
|
||||
.to include('Object storage key is too long (maximum is 1024 characters)')
|
||||
end
|
||||
|
||||
it 'is set before saving' do
|
||||
|
|
@ -186,7 +179,7 @@ RSpec.describe VirtualRegistries::Packages::Maven::CachedResponse, type: :model,
|
|||
upstream: upstream,
|
||||
group_id: upstream.group_id,
|
||||
relative_path: '/test',
|
||||
updates: { file: file, size: size, file_sha1: 'test' }
|
||||
updates: { file: file, size: size, file_sha1: '4e1243bd22c66e76c2ba9eddc1f91394e57f9f95' }
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
@ -274,10 +267,45 @@ RSpec.describe VirtualRegistries::Packages::Maven::CachedResponse, type: :model,
|
|||
end
|
||||
end
|
||||
|
||||
describe '#mark_as_pending_destruction' do
|
||||
let_it_be_with_refind(:cached_response) { create(:virtual_registries_packages_maven_cached_response, :default) }
|
||||
|
||||
subject(:execute) { cached_response.mark_as_pending_destruction }
|
||||
|
||||
shared_examples 'updating the status and relative_path properly' do
|
||||
it 'updates the status and relative_path' do
|
||||
previous_path = cached_response.relative_path
|
||||
|
||||
expect { execute }.to change { cached_response.status }.from('default').to('pending_destruction')
|
||||
.and not_change { cached_response.object_storage_key }
|
||||
|
||||
expect(cached_response.relative_path).to start_with(previous_path)
|
||||
expect(cached_response.relative_path).to include('/deleted/')
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'updating the status and relative_path properly'
|
||||
|
||||
context 'with an existing pending destruction record with same relative_path and upstream_id' do
|
||||
let_it_be(:already_pending_destruction) do
|
||||
create(
|
||||
:virtual_registries_packages_maven_cached_response,
|
||||
:pending_destruction,
|
||||
upstream: cached_response.upstream,
|
||||
relative_path: cached_response.relative_path
|
||||
)
|
||||
end
|
||||
|
||||
it_behaves_like 'updating the status and relative_path properly'
|
||||
end
|
||||
end
|
||||
|
||||
context 'with loose foreign key on virtual_registries_packages_maven_cached_responses.upstream_id' do
|
||||
it_behaves_like 'update by a loose foreign key' do
|
||||
let_it_be(:parent) { create(:virtual_registries_packages_maven_upstream) }
|
||||
let_it_be(:model) { create(:virtual_registries_packages_maven_cached_response, upstream: parent) }
|
||||
|
||||
let(:find_model) { model.reload }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -285,6 +313,8 @@ RSpec.describe VirtualRegistries::Packages::Maven::CachedResponse, type: :model,
|
|||
it_behaves_like 'update by a loose foreign key' do
|
||||
let_it_be(:parent) { create(:group) }
|
||||
let_it_be(:model) { create(:virtual_registries_packages_maven_cached_response, group: parent) }
|
||||
|
||||
let(:find_model) { model.reload }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -231,4 +231,20 @@ RSpec.describe VirtualRegistries::Packages::Maven::Upstream, type: :model, featu
|
|||
|
||||
it { is_expected.not_to include('username', 'password') }
|
||||
end
|
||||
|
||||
describe '#default_cached_responses' do
|
||||
let_it_be(:upstream) { create(:virtual_registries_packages_maven_upstream) }
|
||||
|
||||
let_it_be(:default_cached_response) do
|
||||
create(:virtual_registries_packages_maven_cached_response, upstream: upstream)
|
||||
end
|
||||
|
||||
let_it_be(:pending_destruction_cached_response) do
|
||||
create(:virtual_registries_packages_maven_cached_response, :pending_destruction, upstream: upstream)
|
||||
end
|
||||
|
||||
subject { upstream.default_cached_responses }
|
||||
|
||||
it { is_expected.to contain_exactly(default_cached_response) }
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@ RSpec.describe API::CommitStatuses, :clean_gitlab_redis_cache, feature_category:
|
|||
context "reporter user" do
|
||||
let(:statuses_id) { json_response.map { |status| status['id'] } }
|
||||
|
||||
def create_status(commit, opts = {})
|
||||
create(:commit_status, { pipeline: commit, ref: commit.ref }.merge(opts))
|
||||
def create_status(pipeline, opts = {})
|
||||
create(:commit_status, { pipeline: pipeline, ref: pipeline.ref }.merge(opts))
|
||||
end
|
||||
|
||||
let!(:status1) { create_status(master, status: 'running', retried: true) }
|
||||
|
|
@ -58,44 +58,73 @@ RSpec.describe API::CommitStatuses, :clean_gitlab_redis_cache, feature_category:
|
|||
end
|
||||
end
|
||||
|
||||
context 'all commit statuses' do
|
||||
shared_examples_for 'get commit statuses' do
|
||||
before do
|
||||
get api(get_url, reporter), params: { all: 1 }
|
||||
get api(get_url, reporter), params: params
|
||||
end
|
||||
|
||||
it 'returns all commit statuses' do
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(response).to include_pagination_headers
|
||||
expect(json_response).to be_an Array
|
||||
expect(statuses_id).to contain_exactly(
|
||||
status1.id, status2.id, status3.id, status4.id, status5.id, status6.id
|
||||
)
|
||||
expect(statuses_id).to eq(expected_statuses)
|
||||
end
|
||||
end
|
||||
|
||||
context 'Get all commit statuses' do
|
||||
let(:params) { { all: 1 } }
|
||||
let(:expected_statuses) { [status1.id, status2.id, status3.id, status4.id, status5.id, status6.id] }
|
||||
|
||||
it_behaves_like 'get commit statuses'
|
||||
end
|
||||
|
||||
context 'latest commit statuses for specific ref' do
|
||||
before do
|
||||
get api(get_url, reporter), params: { ref: 'develop' }
|
||||
end
|
||||
let(:params) { { ref: 'develop' } }
|
||||
let(:expected_statuses) { [status3.id, status5.id] }
|
||||
|
||||
it 'returns latest commit statuses for specific ref' do
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(response).to include_pagination_headers
|
||||
expect(json_response).to be_an Array
|
||||
expect(statuses_id).to contain_exactly(status3.id, status5.id)
|
||||
end
|
||||
it_behaves_like 'get commit statuses'
|
||||
end
|
||||
|
||||
context 'latest commit statues for specific name' do
|
||||
before do
|
||||
get api(get_url, reporter), params: { name: 'coverage' }
|
||||
end
|
||||
let(:params) { { name: 'coverage' } }
|
||||
let(:expected_statuses) { [status4.id, status5.id] }
|
||||
|
||||
it 'return latest commit statuses for specific name' do
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(response).to include_pagination_headers
|
||||
expect(json_response).to be_an Array
|
||||
expect(statuses_id).to contain_exactly(status4.id, status5.id)
|
||||
it_behaves_like 'get commit statuses'
|
||||
end
|
||||
|
||||
context 'latest commit statuses for specific pipeline' do
|
||||
let(:params) { { pipeline_id: develop.id } }
|
||||
let(:expected_statuses) { [status3.id, status5.id] }
|
||||
|
||||
it_behaves_like 'get commit statuses'
|
||||
end
|
||||
|
||||
context 'return commit statuses sort by desc id' do
|
||||
let(:params) { { all: 1, sort: "desc" } }
|
||||
let(:expected_statuses) { [status6.id, status5.id, status4.id, status3.id, status2.id, status1.id] }
|
||||
|
||||
it_behaves_like 'get commit statuses'
|
||||
end
|
||||
|
||||
context 'return commit statuses sort by desc pipeline_id' do
|
||||
let(:params) { { all: 1, order_by: "pipeline_id", sort: "desc" } }
|
||||
let(:expected_statuses) { [status3.id, status5.id, status1.id, status2.id, status4.id, status6.id] }
|
||||
|
||||
it_behaves_like 'get commit statuses'
|
||||
end
|
||||
|
||||
context 'return commit statuses sort by asc pipeline_id' do
|
||||
let(:params) { { all: 1, order_by: "pipeline_id" } }
|
||||
let(:expected_statuses) { [status1.id, status2.id, status4.id, status6.id, status3.id, status5.id] }
|
||||
|
||||
it_behaves_like 'get commit statuses'
|
||||
end
|
||||
|
||||
context 'Bad filter commit statuses' do
|
||||
it 'return commit statuses order by an unmanaged field' do
|
||||
get api(get_url, reporter), params: { all: 1, order_by: "name" }
|
||||
|
||||
expect(response).to have_gitlab_http_status(:bad_request)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -43,4 +43,93 @@ RSpec.describe 'getting a package list for a group', feature_category: :package_
|
|||
expect(graphql_data_at(:b, :packages)).to be(nil)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'protectionRuleExists' do
|
||||
let_it_be(:project1_package_protected) { create(:npm_package, project: project1) }
|
||||
let_it_be(:project1_package) { create(:npm_package, project: project1) }
|
||||
let_it_be(:package_protection_rule1) do
|
||||
create(:package_protection_rule, project: project1,
|
||||
package_name_pattern: project1_package_protected.name,
|
||||
package_type: project1_package_protected.package_type,
|
||||
minimum_access_level_for_push: :admin)
|
||||
end
|
||||
|
||||
let_it_be(:project2_package_protected) { create(:npm_package, project: project2) }
|
||||
let_it_be(:project2_package) { create(:npm_package, project: project2) }
|
||||
let_it_be(:package_protection_rule2) do
|
||||
create(:package_protection_rule, project: project2,
|
||||
package_name_pattern: project2_package_protected.name,
|
||||
package_type: project2_package_protected.package_type,
|
||||
minimum_access_level_for_push: :admin)
|
||||
end
|
||||
|
||||
let_it_be_with_reload(:project3) { create(:project, :private, group: resource) }
|
||||
let_it_be(:project3_package_protected) { create(:npm_package, project: project3) }
|
||||
let_it_be(:project3_package) { create(:npm_package, project: project3) }
|
||||
let_it_be(:package_protection_rule3) do
|
||||
create(:package_protection_rule, project: project3,
|
||||
package_name_pattern: project3_package_protected.name,
|
||||
package_type: project3_package_protected.package_type,
|
||||
minimum_access_level_for_push: :admin)
|
||||
end
|
||||
|
||||
let(:packages) { graphql_data_at(resource_type, :packages, :nodes) }
|
||||
|
||||
let(:query) do
|
||||
graphql_query_for(
|
||||
resource_type,
|
||||
{ 'fullPath' => resource.full_path },
|
||||
query_graphql_field('packages', {}, fields)
|
||||
)
|
||||
end
|
||||
|
||||
let(:fields) do
|
||||
<<~QUERY
|
||||
nodes {
|
||||
name
|
||||
protectionRuleExists
|
||||
}
|
||||
QUERY
|
||||
end
|
||||
|
||||
subject(:send_graphql_request) { post_graphql(query, current_user: current_user) }
|
||||
|
||||
before do
|
||||
resource.add_reporter(current_user)
|
||||
end
|
||||
|
||||
it 'returns true for all protected packages' do
|
||||
send_graphql_request
|
||||
|
||||
expect(packages).to match_array([
|
||||
a_hash_including('name' => project1_package_protected.name, 'protectionRuleExists' => true),
|
||||
a_hash_including('name' => project2_package_protected.name, 'protectionRuleExists' => true),
|
||||
a_hash_including('name' => project3_package_protected.name, 'protectionRuleExists' => true),
|
||||
a_hash_including('name' => project1_package.name, 'protectionRuleExists' => false),
|
||||
a_hash_including('name' => project2_package.name, 'protectionRuleExists' => false),
|
||||
a_hash_including('name' => project3_package.name, 'protectionRuleExists' => false)
|
||||
])
|
||||
end
|
||||
|
||||
it 'executes only one database queries for all projects at once' do
|
||||
expect { send_graphql_request }.to match_query_count(1).for_model(::Packages::Protection::Rule)
|
||||
end
|
||||
|
||||
context 'when 25 packages belong to group' do
|
||||
let_it_be(:resource) { create(:group) }
|
||||
let_it_be(:projects) { create_list(:project, 5, :private, group: resource) }
|
||||
|
||||
before_all do
|
||||
projects.each do |project|
|
||||
package = create_list(:npm_package, 5, project: project)
|
||||
create(:package_protection_rule, project: project, package_name_pattern: package.first.name,
|
||||
package_type: package.first.package_type)
|
||||
end
|
||||
end
|
||||
|
||||
it 'executes only two database queries to check the protection rules for packages in batches of 20' do
|
||||
expect { send_graphql_request }.to match_query_count(2).for_model(::Packages::Protection::Rule)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -115,21 +115,11 @@ RSpec.describe API::VirtualRegistries::Packages::Maven::CachedResponses, :aggreg
|
|||
let(:id) { Base64.urlsafe_encode64("#{upstream.id} #{cached_response.relative_path}") }
|
||||
let(:url) { "/virtual_registries/packages/maven/cached_responses/#{id}" }
|
||||
|
||||
let_it_be(:processing_cached_response) do
|
||||
create(
|
||||
:virtual_registries_packages_maven_cached_response,
|
||||
:processing,
|
||||
upstream: upstream,
|
||||
group: upstream.group,
|
||||
relative_path: cached_response.relative_path
|
||||
)
|
||||
end
|
||||
|
||||
subject(:api_request) { delete api(url), headers: headers }
|
||||
|
||||
shared_examples 'successful response' do
|
||||
it 'returns a successful response' do
|
||||
expect { api_request }.to change { upstream.cached_responses.count }.by(-1)
|
||||
expect { api_request }.to change { cached_response.reload.status }.from('default').to('pending_destruction')
|
||||
expect(response).to have_gitlab_http_status(:no_content)
|
||||
end
|
||||
end
|
||||
|
|
@ -192,7 +182,7 @@ RSpec.describe API::VirtualRegistries::Packages::Maven::CachedResponses, :aggreg
|
|||
before do
|
||||
allow_next_found_instance_of(cached_response.class) do |instance|
|
||||
errors = ActiveModel::Errors.new(instance).tap { |e| e.add(:cached_response, 'error message') }
|
||||
allow(instance).to receive_messages(save: false, errors: errors)
|
||||
allow(instance).to receive_messages(mark_as_pending_destruction: false, errors: errors)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -217,7 +217,11 @@ RSpec.describe API::VirtualRegistries::Packages::Maven::Endpoints, :aggregate_fa
|
|||
api(url),
|
||||
file_key: :file,
|
||||
headers: headers,
|
||||
params: { file: file_upload, 'file.md5' => 'md5', 'file.sha1' => 'sha1' },
|
||||
params: {
|
||||
file: file_upload,
|
||||
'file.md5' => 'd8e8fca2dc0f896fd7cb4cb0031ba249',
|
||||
'file.sha1' => '4e1243bd22c66e76c2ba9eddc1f91394e57f9f83'
|
||||
},
|
||||
send_rewritten_field: true
|
||||
)
|
||||
end
|
||||
|
|
@ -228,7 +232,7 @@ RSpec.describe API::VirtualRegistries::Packages::Maven::Endpoints, :aggregate_fa
|
|||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(response.body).to eq('')
|
||||
expect(upstream.cached_responses.last).to have_attributes(
|
||||
expect(upstream.default_cached_responses.search_by_relative_path(path).last).to have_attributes(
|
||||
relative_path: "/#{path}",
|
||||
upstream_etag: nil,
|
||||
upstream_checked_at: Time.zone.now,
|
||||
|
|
|
|||
|
|
@ -12,7 +12,13 @@ RSpec.describe VirtualRegistries::Packages::Maven::CachedResponses::CreateOrUpda
|
|||
let(:etag) { 'test' }
|
||||
let(:content_type) { 'text/xml' }
|
||||
let(:params) { { path: path, file: file, etag: etag, content_type: content_type } }
|
||||
let(:file) { UploadedFile.new(Tempfile.new(etag).path, sha1: 'sha1', md5: 'md5') }
|
||||
let(:file) do
|
||||
UploadedFile.new(
|
||||
Tempfile.new(etag).path,
|
||||
sha1: '4e1243bd22c66e76c2ba9eddc1f91394e57f9f83',
|
||||
md5: 'd8e8fca2dc0f896fd7cb4cb0031ba249'
|
||||
)
|
||||
end
|
||||
|
||||
let(:service) do
|
||||
described_class.new(upstream: upstream, current_user: user, params: params)
|
||||
|
|
@ -22,7 +28,7 @@ RSpec.describe VirtualRegistries::Packages::Maven::CachedResponses::CreateOrUpda
|
|||
subject(:execute) { service.execute }
|
||||
|
||||
shared_examples 'returning a service response success response' do
|
||||
shared_examples 'creating a new cached response' do |with_md5: 'md5'|
|
||||
shared_examples 'creating a new cached response' do |with_md5: 'd8e8fca2dc0f896fd7cb4cb0031ba249'|
|
||||
it 'returns a success service response', :freeze_time do
|
||||
expect { execute }.to change { upstream.cached_responses.count }.by(1)
|
||||
expect(execute).to be_success
|
||||
|
|
@ -36,7 +42,7 @@ RSpec.describe VirtualRegistries::Packages::Maven::CachedResponses::CreateOrUpda
|
|||
relative_path: "/#{path}",
|
||||
upstream_etag: etag,
|
||||
content_type: content_type,
|
||||
file_sha1: 'sha1',
|
||||
file_sha1: '4e1243bd22c66e76c2ba9eddc1f91394e57f9f83',
|
||||
file_md5: with_md5
|
||||
)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ RSpec.describe VirtualRegistries::Packages::Maven::HandleFileRequestService, :ag
|
|||
end
|
||||
|
||||
context 'with a cached response' do
|
||||
let_it_be_with_reload(:cached_response) do
|
||||
let_it_be_with_refind(:cached_response) do
|
||||
create(:virtual_registries_packages_maven_cached_response,
|
||||
:upstream_checked,
|
||||
upstream: registry.upstream,
|
||||
|
|
|
|||
|
|
@ -14858,10 +14858,10 @@ vite-plugin-ruby@^5.1.1:
|
|||
debug "^4.3.4"
|
||||
fast-glob "^3.3.2"
|
||||
|
||||
vite@^6.0.6:
|
||||
version "6.0.6"
|
||||
resolved "https://registry.yarnpkg.com/vite/-/vite-6.0.6.tgz#a851674fcff55b0c1962f72082354b8802e48505"
|
||||
integrity sha512-NSjmUuckPmDU18bHz7QZ+bTYhRR0iA72cs2QAxCqDpafJ0S6qetco0LB3WW2OxlMHS0JmAv+yZ/R3uPmMyGTjQ==
|
||||
vite@^6.0.7:
|
||||
version "6.0.7"
|
||||
resolved "https://registry.yarnpkg.com/vite/-/vite-6.0.7.tgz#f0f8c120733b04af52b4a1e3e7cb54eb851a799b"
|
||||
integrity sha512-RDt8r/7qx9940f8FcOIAH9PTViRrghKaK2K1jY3RaAURrEUbm9Du1mJ72G+jlhtG3WwodnfzY8ORQZbBavZEAQ==
|
||||
dependencies:
|
||||
esbuild "^0.24.2"
|
||||
postcss "^8.4.49"
|
||||
|
|
|
|||
Loading…
Reference in New Issue