Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2024-08-20 12:08:55 +00:00
parent d4fd5ba33a
commit c267f0eefb
100 changed files with 9130 additions and 485 deletions

View File

@ -1,19 +0,0 @@
---
# Cop supports --autocorrect.
GraphQL/UnnecessaryFieldAlias:
Exclude:
- 'app/graphql/types/ci/pipeline_type.rb'
- 'app/graphql/types/ci/runner_manager_type.rb'
- 'app/graphql/types/ci/runner_type.rb'
- 'app/graphql/types/deployment_tag_type.rb'
- 'app/graphql/types/issue_type.rb'
- 'app/graphql/types/ml/model_version_links_type.rb'
- 'app/graphql/types/projects/fork_details_type.rb'
- 'app/graphql/types/repository/blob_type.rb'
- 'ee/app/graphql/ee/types/project_type.rb'
- 'ee/app/graphql/types/admin/cloud_licenses/current_license_type.rb'
- 'ee/app/graphql/types/approval_rule_type.rb'
- 'ee/app/graphql/types/dast/profile_type.rb'
- 'ee/app/graphql/types/dora/performance_score_connection_type.rb'
- 'ee/app/graphql/types/group_release_stats_type.rb'
- 'ee/app/graphql/types/requirements_management/requirement_type.rb'

View File

@ -1 +1 @@
57543875e2fd0991e262ff6691310b9c16297d1b
8928e3f4f4c02fb33f3e15e129649830f17f0ff9

View File

@ -734,3 +734,5 @@ gem 'duo_api', '~> 1.3' # rubocop:todo Gemfile/MissingFeatureCategory
gem 'gitlab-sdk', '~> 0.3.0', feature_category: :application_instrumentation
gem 'openbao_client', path: 'gems/openbao_client' # rubocop:todo Gemfile/MissingFeatureCategory
gem 'paper_trail', '~> 15.0' # rubocop:todo Gemfile/MissingFeatureCategory

View File

@ -486,6 +486,7 @@
{"name":"pact","version":"1.64.0","platform":"ruby","checksum":"0bdd848888580db7f29a7d8789b861b8067370c0ac0eb36ffc4bb7ff3f5f6ea8"},
{"name":"pact-mock_service","version":"3.11.2","platform":"ruby","checksum":"42d9e54546a10229d7915da5383daeb322764c2876a84b4ea521f53c6f1fba51"},
{"name":"pact-support","version":"1.20.0","platform":"ruby","checksum":"41c343a3124fb379684b9ad9f1a0766c5fa18d3b78d433a52e5552d8b9475871"},
{"name":"paper_trail","version":"15.1.0","platform":"ruby","checksum":"0dbccd97e9d26c54aaea256d2566eaa040a3535601f49a62d79187e77d9ba9f9"},
{"name":"parallel","version":"1.24.0","platform":"ruby","checksum":"5bf38efb9b37865f8e93d7a762727f8c5fc5deb19949f4040c76481d5eee9397"},
{"name":"parser","version":"3.3.3.0","platform":"ruby","checksum":"a2e23c90918d9b7e866b18dca2b6835f227769dd2fa8e59c5841f3389cf53eeb"},
{"name":"parslet","version":"1.8.2","platform":"ruby","checksum":"08d1ab3721cd3f175bfbee8788b2ddff71f92038f2d69bd65454c22bb9fbd98a"},

View File

@ -1394,6 +1394,9 @@ GEM
diff-lcs (~> 1.5)
expgen (~> 0.1)
rainbow (~> 3.1.1)
paper_trail (15.1.0)
activerecord (>= 6.1)
request_store (~> 1.4)
parallel (1.24.0)
parser (3.3.3.0)
ast (~> 2.4.1)
@ -2208,6 +2211,7 @@ DEPENDENCIES
org-ruby (~> 0.9.12)
os (~> 1.1, >= 1.1.4)
pact (~> 1.64)
paper_trail (~> 15.0)
parallel (~> 1.19)
parser (= 3.3.3.0)
parslet (~> 1.8)

View File

@ -1,12 +1,19 @@
<!-- eslint-disable vue/multi-word-component-names -->
<script>
import { GlLoadingIcon, GlIcon, GlIntersectionObserver, GlTooltipDirective } from '@gitlab/ui';
import {
GlCard,
GlLoadingIcon,
GlIcon,
GlIntersectionObserver,
GlTooltipDirective,
} from '@gitlab/ui';
import { n__, __ } from '~/locale';
import Timeago from '~/vue_shared/components/time_ago_tooltip.vue';
import { DESIGN_ROUTE_NAME } from '../../router/constants';
export default {
components: {
GlCard,
GlLoadingIcon,
GlIntersectionObserver,
GlIcon,
@ -129,69 +136,75 @@ export default {
params: { id: filename },
query: $route.query,
}"
class="card js-design-list-item design-list-item gl-mb-0 gl-cursor-pointer gl-text-default hover:gl-text-default"
class="gl-text-default hover:gl-text-default"
>
<div
class="card-body gl-relative gl-flex gl-items-center gl-justify-center gl-overflow-hidden gl-rounded-t-base gl-p-0"
<gl-card
class="js-design-list-item design-list-item gl-mb-0"
header-class="gl-p-0 gl-flex gl-grow gl-items-center gl-justify-center gl-overflow-hidden gl-relative gl-rounded-t-base"
body-class="gl-p-0 gl-flex gl-w-full gl-bg-default gl-py-3 gl-px-4 gl-rounded-base"
>
<div
v-if="icon.name"
data-testid="design-event"
class="gl-absolute gl-right-3 gl-top-3 gl-mr-1"
>
<span :title="icon.tooltip" :aria-label="icon.tooltip">
<gl-icon
:name="icon.name"
:size="16"
:class="icon.classes"
data-testid="design-status-icon"
:data-qa-status="icon.name"
/>
</span>
</div>
<gl-intersection-observer
class="gl-grow"
data-testid="design-image"
:data-qa-filename="filename"
@appear="onAppear"
>
<gl-loading-icon v-if="showLoadingSpinner" size="lg" />
<gl-icon
v-else-if="showImageErrorIcon"
name="media-broken"
class="text-secondary"
:size="32"
/>
<img
v-show="showImage"
:src="imageLink"
:alt="filename"
class="design-img gl-mx-auto gl-block gl-max-h-full gl-w-auto gl-max-w-full"
:data-testid="`design-img-${id}`"
@load="onImageLoad"
@error="onImageError"
/>
</gl-intersection-observer>
</div>
<div class="card-footer gl-flex gl-w-full gl-bg-white gl-px-4 gl-py-3">
<div class="str-truncated-100 gl-flex gl-flex-col" data-testid="design-file-name">
<span
v-gl-tooltip
class="str-truncated-100 gl-font-semibold"
:data-testid="`design-img-filename-${id}`"
:title="filename"
>{{ filename }}</span
<template #header>
<div
v-if="icon.name"
data-testid="design-event"
class="gl-absolute gl-top-3 gl-right-3 gl-mr-1"
>
<span v-if="updatedAt" class="str-truncated-100">
{{ __('Updated') }} <timeago :time="updatedAt" tooltip-placement="bottom" />
</span>
</div>
<div v-if="notesCount" class="gl-ml-auto gl-flex gl-items-center gl-text-gray-500">
<gl-icon name="comments" class="gl-ml-2" />
<span :aria-label="notesLabel" class="gl-ml-2">
{{ notesCount }}
</span>
</div>
</div>
<span :title="icon.tooltip" :aria-label="icon.tooltip">
<gl-icon
:name="icon.name"
:size="16"
:class="icon.classes"
data-testid="design-status-icon"
:data-qa-status="icon.name"
/>
</span>
</div>
<gl-intersection-observer
class="gl-flex gl-grow gl-items-center gl-justify-center"
data-testid="design-image"
:data-qa-filename="filename"
@appear="onAppear"
>
<gl-loading-icon v-if="showLoadingSpinner" size="md" />
<gl-icon
v-else-if="showImageErrorIcon"
name="media-broken"
class="text-secondary"
:size="32"
/>
<img
v-show="showImage"
:src="imageLink"
:alt="filename"
class="gl-block gl-mx-auto gl-max-w-full gl-max-h-full gl-w-auto design-img"
:data-testid="`design-img-${id}`"
@load="onImageLoad"
@error="onImageError"
/>
</gl-intersection-observer>
</template>
<template #default>
<div class="gl-flex gl-flex-col str-truncated-100" data-testid="design-file-name">
<span
v-gl-tooltip
class="gl-font-semibold str-truncated-100"
:data-testid="`design-img-filename-${id}`"
:title="filename"
>{{ filename }}</span
>
<span v-if="updatedAt" class="str-truncated-100">
{{ __('Updated') }} <timeago :time="updatedAt" tooltip-placement="bottom" />
</span>
</div>
<div v-if="notesCount" class="gl-ml-auto gl-flex gl-items-center gl-gap-2 gl-text-subtle">
<gl-icon name="comments" />
<span :aria-label="notesLabel">
{{ notesCount }}
</span>
</div>
</template>
</gl-card>
</router-link>
</template>

View File

@ -83,18 +83,18 @@ export default {
@select="routeToVersion"
>
<template #list-item="{ item }">
<span class="gl-flex gl-items-center">
<gl-avatar :alt="getAuthorName(item.author)" :size="32" :src="getAvatarUrl(item)" />
<span class="gl-flex gl-items-center gl-gap-3">
<gl-avatar
:alt="getAuthorName(item.author)"
:size="32"
:src="getAvatarUrl(item)"
class="gl-self-start"
/>
<span class="gl-flex gl-flex-col">
<span class="gl-font-bold">{{ versionText(item) }}</span>
<span v-if="item.author" class="gl-mt-1 gl-text-gray-600">
<span v-if="item.author" class="gl-text-sm gl-text-subtle gl-mt-1">
<span class="gl-block">{{ getAuthorName(item.author) }}</span>
<time-ago
v-if="item.createdAt"
class="text-1"
:time="item.createdAt"
tooltip-placement="bottom"
/>
<time-ago v-if="item.createdAt" :time="item.createdAt" tooltip-placement="bottom" />
</span>
</span>
</span>

View File

@ -1,6 +1,6 @@
<!-- eslint-disable vue/multi-word-component-names -->
<script>
import { GlLoadingIcon, GlButton, GlAlert, GlLink, GlSprintf } from '@gitlab/ui';
import { GlButton, GlAlert, GlLink, GlSprintf } from '@gitlab/ui';
import { GlBreakpointInstance } from '@gitlab/ui/dist/utils';
import VueDraggable from 'vuedraggable';
import permissionsQuery from 'shared_queries/design_management/design_permissions.query.graphql';
@ -8,6 +8,7 @@ import getDesignListQuery from 'shared_queries/design_management/get_design_list
import { getFilename, validateImageName } from '~/lib/utils/file_upload';
import { __, s__ } from '~/locale';
import DesignDropzone from '~/vue_shared/components/upload_dropzone/upload_dropzone.vue';
import CrudComponent from '~/vue_shared/components/crud_component.vue';
import DeleteButton from '../components/delete_button.vue';
import DesignDestroyer from '../components/design_destroyer.vue';
import Design from '../components/list/item.vue';
@ -46,11 +47,11 @@ export const i18n = {
export default {
components: {
GlLoadingIcon,
GlAlert,
GlButton,
GlSprintf,
GlLink,
CrudComponent,
UploadButton,
Design,
DesignDestroyer,
@ -353,37 +354,37 @@ export default {
<template>
<div
data-testid="designs-root"
class="gl-mt-4"
:class="{ 'gl-new-card': showToolbar }"
@mouseenter="toggleOnPasteListener"
@mouseleave="toggleOffPasteListener"
>
<gl-alert
v-if="uploadError"
variant="danger"
class="gl-mb-3"
data-testid="design-update-alert"
@dismiss="unsetUpdateError"
<crud-component
:title="s__('DesignManagement|Designs')"
class="!gl-mt-3"
:class="{ 'gl-bg-transparent gl-border-0': !showToolbar }"
:header-class="{ 'gl-hidden': !showToolbar }"
:body-class="{
'!gl-my-0': showToolbar && !isLoading,
'!gl-m-0 !gl-p-0': !showToolbar && !isLoading,
}"
:is-loading="isLoading && !error"
is-collapsible
data-testid="design-toolbar-wrapper"
>
{{ uploadError }}
</gl-alert>
<header v-if="showToolbar" class="gl-new-card-header" data-testid="design-toolbar-wrapper">
<div class="gl-flex gl-w-full gl-flex-wrap gl-items-center gl-justify-between gl-gap-3">
<div class="gl-flex gl-items-center">
<span class="gl-mr-3 gl-font-bold">{{ s__('DesignManagement|Designs') }}</span>
<design-version-dropdown />
</div>
<template v-if="showToolbar" #title>
<design-version-dropdown />
</template>
<template v-if="showToolbar" #actions>
<div
v-if="canCreateDesign"
v-show="hasDesigns"
class="gl-flex gl-items-center"
class="gl-flex gl-items-center gl-gap-3"
data-testid="design-selector-toolbar"
>
<gl-button
v-if="isLatestVersion"
category="tertiary"
size="small"
class="gl-mr-3"
data-testid="select-all-designs-button"
@click="toggleDesignsSelection"
>{{ selectAllButtonText }}
@ -398,7 +399,6 @@ export default {
v-if="isLatestVersion"
:is-deleting="loading"
button-variant="default"
button-class="gl-mr-3"
button-size="small"
data-testid="archive-button"
:loading="loading"
@ -415,111 +415,114 @@ export default {
@upload="onUploadDesign"
/>
</div>
</div>
</header>
<div
:class="{
'gl-mx-5': showToolbar,
'gl-new-card-body !gl-mx-3': hasDesigns,
}"
>
<gl-loading-icon v-if="isLoading" size="sm" class="gl-py-4" />
<gl-alert v-else-if="error" variant="danger" :dismissible="false">
{{ $options.i18n.designLoadingError }}
</gl-alert>
<header
v-else-if="isDesignCollectionCopying"
class="card"
data-testid="design-collection-is-copying"
>
<div class="card-header design-card-header gl-border-b-0">
<div class="card-title gl-my-0 gl-flex gl-h-7 gl-items-center">
{{
s__(
'DesignManagement|Your designs are being copied and are on their way… Please refresh to update.',
)
}}
</div>
</div>
</header>
<vue-draggable
v-else
:value="designs"
:disabled="!isLatestVersion || isReorderingInProgress || isMobile"
v-bind="$options.dragOptions"
tag="ol"
draggable=".js-design-tile"
class="list-unstyled row"
@start="isDraggingDesign = true"
@end="isDraggingDesign = false"
@change="reorderDesigns"
@input="onDesignMove"
>
<li
v-for="design in designs"
:key="design.id"
class="col-md-6 col-lg-3 js-design-tile gl-mt-5 gl-bg-transparent gl-shadow-none"
>
<design-dropzone
:display-as-card="hasDesigns"
:enable-drag-behavior="isDraggingDesign"
v-bind="$options.dropzoneProps"
@change="onExistingDesignDropzoneChange($event, design.filename)"
@error="onDesignDropzoneError"
>
<design
v-bind="design"
:is-uploading="isDesignToBeSaved(design.filename)"
class="gl-bg-white"
/>
<template #upload-text="{ openFileUpload }">
<gl-sprintf :message="$options.i18n.dropzoneDescriptionText">
<template #link="{ content }">
<gl-link @click.stop="openFileUpload">
{{ content }}
</gl-link>
</template>
</gl-sprintf>
</template>
</design-dropzone>
</template>
<input
v-if="canSelectDesign(design.filename)"
:checked="isDesignSelected(design.filename)"
type="checkbox"
class="design-checkbox gl-absolute gl-left-6 gl-top-4 gl-ml-2"
data-testid="design-checkbox"
:data-qa-design="design.filename"
@change="changeSelectedDesigns(design.filename)"
/>
</li>
<template #header>
<gl-alert
v-if="uploadError"
variant="danger"
class="gl-mt-3"
data-testid="design-update-alert"
@dismiss="unsetUpdateError"
>
{{ uploadError }}
</gl-alert>
<div>
<gl-alert v-if="error" variant="danger" :dismissible="false">
{{ $options.i18n.designLoadingError }}
</gl-alert>
<span
v-else-if="isDesignCollectionCopying"
class="gl-inline-block gl-py-4 gl-text-subtle"
data-testid="design-collection-is-copying"
>
{{
s__(
'DesignManagement|Your designs are being copied and are on their way… Please refresh to update.',
)
}}
</span>
<vue-draggable
v-else
:value="designs"
:disabled="!isLatestVersion || isReorderingInProgress || isMobile"
v-bind="$options.dragOptions"
tag="ol"
draggable=".js-design-tile"
class="list-unstyled row"
@start="isDraggingDesign = true"
@end="isDraggingDesign = false"
@change="reorderDesigns"
@input="onDesignMove"
>
<li
v-if="canCreateDesign"
:class="designDropzoneWrapperClass"
data-testid="design-dropzone-wrapper"
v-for="design in designs"
:key="design.id"
class="col-md-6 col-lg-3 gl-mt-5 gl-bg-transparent gl-shadow-none js-design-tile"
>
<design-dropzone
:enable-drag-behavior="isDraggingDesign"
:class="{ 'design-list-item': !isDesignListEmpty }"
:display-as-card="hasDesigns"
:enable-drag-behavior="isDraggingDesign"
v-bind="$options.dropzoneProps"
data-testid="design-dropzone-content"
@change="onUploadDesign"
@change="onExistingDesignDropzoneChange($event, design.filename)"
@error="onDesignDropzoneError"
>
<design
v-bind="design"
:is-uploading="isDesignToBeSaved(design.filename)"
class="gl-bg-white"
/>
<template #upload-text="{ openFileUpload }">
<gl-sprintf :message="$options.i18n.dropzoneDescriptionText">
<template #link="{ content }">
<gl-link @click.stop="openFileUpload">{{ content }}</gl-link>
<gl-link @click.stop="openFileUpload">
{{ content }}
</gl-link>
</template>
</gl-sprintf>
</template>
</design-dropzone>
<input
v-if="canSelectDesign(design.filename)"
:checked="isDesignSelected(design.filename)"
type="checkbox"
class="design-checkbox gl-absolute gl-top-4 gl-left-6 gl-ml-2"
data-testid="design-checkbox"
:data-qa-design="design.filename"
@change="changeSelectedDesigns(design.filename)"
/>
</li>
</template>
</vue-draggable>
</div>
<router-view :key="$route.fullPath" />
<template #header>
<li
v-if="canCreateDesign"
:class="designDropzoneWrapperClass"
data-testid="design-dropzone-wrapper"
>
<design-dropzone
:enable-drag-behavior="isDraggingDesign"
:class="{ 'design-list-item': !isDesignListEmpty }"
:display-as-card="hasDesigns"
v-bind="$options.dropzoneProps"
data-testid="design-dropzone-content"
@change="onUploadDesign"
@error="onDesignDropzoneError"
>
<template #upload-text="{ openFileUpload }">
<gl-sprintf :message="$options.i18n.dropzoneDescriptionText">
<template #link="{ content }">
<gl-link @click.stop="openFileUpload">{{ content }}</gl-link>
</template>
</gl-sprintf>
</template>
</design-dropzone>
</li>
</template>
</vue-draggable>
</div>
<router-view :key="$route.fullPath" />
</crud-component>
</div>
</template>

View File

@ -34,7 +34,7 @@ export default {
css: {
label: [
'gl-font-base',
'gl-text-base',
'gl-font-normal',
'gl-leading-normal',
'gl-shadow-inner-1-gray-200',
@ -76,22 +76,22 @@ export default {
};
</script>
<template>
<section class="gl-display-flex gl-bg-white gl-m-3">
<div class="gl-display-flex gl-flex-direction-column">
<label :for="stableWeightId" :class="$options.css.label" class="gl-rounded-top-left-base">
<section class="gl-m-3 gl-flex gl-bg-white">
<div class="gl-flex gl-flex-col">
<label :for="stableWeightId" :class="$options.css.label" class="gl-rounded-tl-base">
{{ $options.translations.stableLabel }}
</label>
<gl-collapsible-listbox
:id="stableWeightId"
:selected="stableWeight"
:items="$options.ingressOptions"
class="gl-min-w-full gl-text-black-normal"
toggle-class="gl-min-w-full gl-rounded-top-left-none! gl-rounded-top-right-none! gl-rounded-bottom-right-none!"
class="gl-min-w-full gl-text-default"
toggle-class="gl-min-w-full !gl-rounded-tl-none !gl-rounded-tr-none !gl-rounded-br-none"
@select="changeStable"
/>
</div>
<div class="gl-display-flex gl-display-flex gl-flex-direction-column">
<label :for="canaryWeightId" :class="$options.css.label" class="gl-rounded-top-right-base">{{
<div class="gl-flex gl-flex-col">
<label :for="canaryWeightId" :class="$options.css.label" class="gl-rounded-tr-base">{{
$options.translations.canaryLabel
}}</label>
<gl-collapsible-listbox
@ -99,7 +99,7 @@ export default {
:selected="canaryWeight"
:items="$options.ingressOptions"
class="gl-min-w-full"
toggle-class="gl-min-w-full gl-rounded-top-left-none! gl-rounded-top-right-none! gl-rounded-bottom-right-none!"
toggle-class="gl-min-w-full !gl-rounded-tl-none !gl-rounded-tr-none !gl-rounded-br-none"
@select="changeCanary"
/>
</div>

View File

@ -38,11 +38,11 @@ export default {
};
</script>
<template>
<div data-testid="deployment-commit" class="gl-display-flex gl-align-items-center">
<div data-testid="deployment-commit" class="gl-flex gl-items-center">
<gl-avatar-link v-gl-tooltip :title="commitAuthor" :href="commitAuthorPath">
<gl-avatar :size="16" :src="commitAuthorAvatar" />
</gl-avatar-link>
<gl-link v-gl-tooltip :title="commitTitle" :href="commitPath" class="gl-ml-3 gl-str-truncated">
<gl-link v-gl-tooltip :title="commitTitle" :href="commitPath" class="gl-str-truncated gl-ml-3">
{{ commitTitle }}
</gl-link>
</div>

View File

@ -145,7 +145,7 @@ export default {
<div class="deploy-board-information gl-w-full">
<section class="deploy-board-status">
<span v-gl-tooltip :title="instanceIsCompletedText">
<span ref="percentage" class="gl-text-center gl-text-default gl-text-lg"
<span ref="percentage" class="gl-text-center gl-text-lg gl-text-default"
>{{ deployBoardData.completion }}%</span
>
<span class="text text-center text-secondary">{{ __('Complete') }}</span>
@ -153,15 +153,15 @@ export default {
</section>
<section class="deploy-board-instances">
<div class="gl-font-base text-secondary">
<div class="text-secondary gl-text-base">
<span class="deploy-board-instances-text"
>{{ instanceTitle }} ({{ instanceCount }})</span
>
<span ref="legend-icon" data-testid="legend-tooltip-target">
<gl-icon class="gl-text-blue-500 gl-ml-2" name="question-o" />
<gl-icon class="gl-ml-2 gl-text-blue-500" name="question-o" />
</span>
<gl-tooltip :target="() => $refs['legend-icon']" boundary="#content-body">
<div class="deploy-board-legend gl-flex gl-flex-direction-column">
<div class="deploy-board-legend gl-flex gl-flex-col">
<div
v-for="status in statuses"
:key="status.text"
@ -174,7 +174,7 @@ export default {
</gl-tooltip>
</div>
<div class="deploy-board-instances-container gl-flex flex-wrap flex-row">
<div class="deploy-board-instances-container flex-wrap flex-row gl-flex">
<template v-for="(instance, i) in deployBoardData.instances">
<instance-component
:key="i"

View File

@ -152,28 +152,28 @@ export default {
tags: __('Tags'),
},
headerClasses: [
'gl-display-flex',
'gl-align-items-flex-start',
'gl-md-align-items-center',
'gl-justify-content-space-between',
'gl-flex',
'gl-items-start',
'md:gl-items-center',
'gl-justify-between',
'gl-pr-6',
],
headerDetailsClasses: [
'gl-display-flex',
'gl-flex-direction-column',
'gl-md-flex-direction-row',
'gl-align-items-flex-start',
'gl-md-align-items-center',
'gl-font-sm',
'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-display-flex',
'gl-flex',
'gl-gap-x-3',
'gl-mr-0',
'gl-md-mr-5',
'md:gl-mr-5',
'gl-mb-3',
'gl-md-mb-0',
'md:gl-mb-0',
],
};
</script>
@ -193,11 +193,11 @@ export default {
</gl-badge>
<gl-badge v-if="latest" variant="info">{{ $options.i18n.latestBadge }}</gl-badge>
</div>
<div class="gl-display-flex gl-align-items-center gl-gap-x-5">
<div class="gl-flex gl-items-center gl-gap-x-5">
<div
v-if="iid"
v-gl-tooltip
class="gl-display-flex"
class="gl-flex"
:title="$options.i18n.deploymentId"
:aria-label="$options.i18n.deploymentId"
>
@ -207,7 +207,7 @@ export default {
<div
v-if="shortSha"
data-testid="deployment-commit-sha"
class="gl-font-monospace gl-display-flex gl-align-items-center"
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">
@ -223,7 +223,7 @@ export default {
<time-ago-tooltip
v-if="displayTimeAgo"
:time="displayTimeAgo"
class="gl-display-flex"
class="gl-flex"
data-testid="deployment-timestamp"
>
<template #default="{ timeAgo }">
@ -240,61 +240,57 @@ export default {
</div>
<commit v-if="commit" :commit="commit" class="gl-mt-3" />
<div class="gl-mt-3"><slot name="approval"></slot></div>
<div
class="gl-display-flex gl-md-align-items-center gl-mt-5 gl-flex-direction-column gl-md-flex-direction-row gl-pr-4 gl-md-pr-0"
>
<div v-if="user" class="gl-display-flex gl-flex-direction-column gl-md-max-w-15p">
<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-gray-500">{{ $options.i18n.triggerer }}</span>
<gl-link :href="userPath" class="gl-font-monospace gl-mt-3">
<gl-link :href="userPath" class="gl-mt-3 gl-font-monospace">
<gl-truncate :text="username" with-tooltip />
</gl-link>
</div>
<div
class="gl-display-flex gl-flex-direction-column gl-md-pl-7 gl-md-max-w-15p gl-mt-4 gl-md-mt-0"
>
<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-gray-500" :class="{ 'gl-ml-3': !deployable }">
{{ $options.i18n.job }}
</span>
<gl-link v-if="jobPath" :href="jobPath" class="gl-font-monospace gl-mt-3">
<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-font-monospace gl-mt-3">
<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-font-monospace gl-mt-3" variant="info">
<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-display-flex gl-flex-direction-column gl-md-pl-7 gl-md-max-w-15p gl-mt-4 gl-md-mt-0"
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-gray-500">{{ $options.i18n.branch }}</span>
<gl-link :href="refPath" class="gl-font-monospace gl-mt-3">
<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-display-flex gl-flex-direction-column gl-md-pl-7 gl-md-max-w-15p gl-mt-4 gl-md-mt-0"
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-gray-500">{{ $options.i18n.tags }}</span>
<gl-loading-icon
v-if="$apollo.queries.tags.loading"
class="gl-font-monospace gl-mt-3"
class="gl-mt-3 gl-font-monospace"
size="sm"
inline
/>
<div v-if="hasTags" class="gl-display-flex gl-flex-direction-row">
<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-font-monospace gl-mt-3 gl-mr-3"
class="gl-mr-3 gl-mt-3 gl-font-monospace"
>
{{ tag.name }}<span v-if="ndx + 1 < tags.length">, </span>
</gl-link>
<div v-if="tags.length > 5" class="gl-font-monospace gl-mt-3 gl-mr-3">...</div>
<div v-if="tags.length > 5" class="gl-mr-3 gl-mt-3 gl-font-monospace">...</div>
</div>
</div>
</div>

View File

@ -45,7 +45,7 @@ export default {
</script>
<template>
<gl-empty-state
class="gl-max-w-limited gl-mx-auto"
class="gl-mx-auto gl-max-w-limited"
:title="title"
:svg-path="$options.emptyEntironmentsSvgPath"
>

View File

@ -82,7 +82,7 @@ export default {
<gl-icon
ref="informationIcon"
name="information-o"
class="gl-text-blue-600 gl-hover-cursor-pointer"
class="gl-text-blue-600 hover:gl-cursor-pointer"
/>
<gl-popover
:target="() => $refs.informationIcon.$el"
@ -105,7 +105,7 @@ export default {
</gl-sprintf>
</li>
<li class="gl-list-none">
<div class="gl-display-flex align-items-start">
<div class="align-items-start gl-flex">
<pre
:id="modalInfoCopyId"
class="gl-w-full"

View File

@ -105,8 +105,8 @@ export default {
data-testid="manual-action-link"
>
<template #list-item>
<span class="gl-flex-grow-1">{{ item.text }}</span>
<span v-if="item.scheduledAt" class="gl-text-gray-500 gl-float-right">
<span class="gl-grow">{{ item.text }}</span>
<span v-if="item.scheduledAt" class="gl-float-right gl-text-gray-500">
<gl-icon name="clock" />
{{ remainingTime(item) }}
</span>

View File

@ -34,7 +34,7 @@ export default {
text: s__('Environments|Delete environment'),
extraAttrs: {
variant: 'danger',
class: 'gl-text-red-500!',
class: '!gl-text-red-500',
},
},
};

View File

@ -103,9 +103,9 @@ export default {
<template>
<div
:class="{ 'gl-pb-5': !visible }"
class="gl-border-b-solid gl-border-gray-100 gl-border-1 gl-pt-3"
class="gl-border-1 gl-border-gray-100 gl-pt-3 gl-border-b-solid"
>
<div class="gl-w-full gl-display-flex gl-align-items-center gl-px-3">
<div class="gl-flex gl-w-full gl-items-center gl-px-3">
<gl-button
class="gl-mr-4 gl-fill-current gl-text-gray-500"
:aria-label="label"
@ -126,12 +126,12 @@ export default {
:key="environment.name"
:environment="environment"
:class="{ 'gl-mt-5': isFirstEnvironment(index) }"
class="gl-border-gray-100 gl-border-t-solid gl-border-1 gl-pt-3"
class="gl-border-1 gl-border-gray-100 gl-pt-3 gl-border-t-solid"
in-folder
/>
<div
v-if="isMessageShowing"
class="gl-border-gray-100 gl-border-t-solid gl-border-1 gl-py-5 gl-bg-gray-10 gl-text-center"
class="gl-border-1 gl-border-gray-100 gl-bg-gray-10 gl-py-5 gl-text-center gl-border-t-solid"
data-testid="environment-folder-message-element"
>
<gl-sprintf :message="$options.i18n.message">

View File

@ -203,7 +203,7 @@ export default {
</script>
<template>
<div>
<h1 class="page-title gl-font-size-h-display">
<h1 class="page-title gl-text-size-h-display">
{{ title }}
</h1>
<div class="row col-12">

View File

@ -654,7 +654,7 @@ export default {
<span
v-if="!isFolder && deploymentHasUser"
class="text-break-word gl-inline-flex gl-align-items-center"
class="text-break-word gl-inline-flex gl-items-center"
>
<gl-sprintf :message="s__('Environments|by %{avatar}')">
<template #avatar>
@ -740,10 +740,10 @@ export default {
</div>
<div
v-if="upcomingDeployment"
class="gl-w-full gl-display-flex gl-flex-direction-row gl-md-flex-direction-column! gl-justify-content-end"
class="gl-flex gl-w-full gl-flex-row gl-justify-end md:!gl-flex-col"
data-testid="upcoming-deployment-content"
>
<div class="gl-display-flex gl-align-items-center">
<div class="gl-flex gl-items-center">
<span class="gl-mr-2">{{ upcomingDeploymentInternalId }}</span>
<gl-link
v-if="upcomingDeployment.deployable"
@ -757,7 +757,7 @@ export default {
</div>
<span
v-if="upcomingDeployment.user"
class="text-break-word gl-inline-flex gl-align-items-center gl-mt-2"
class="text-break-word gl-mt-2 gl-inline-flex gl-items-center"
>
<gl-sprintf :message="s__('Environments|by %{avatar}')">
<template #avatar>

View File

@ -135,7 +135,7 @@ export default {
<template v-if="shouldRenderSelectButton" #footer>
<gl-button
category="tertiary"
class="gl-justify-content-start! gl-border-t-1! gl-border-t-solid gl-border-t-gray-200 gl-pl-7! gl-rounded-top-left-none! gl-rounded-top-right-none!"
class="!gl-justify-start !gl-rounded-tl-none !gl-rounded-tr-none !gl-border-t-1 gl-border-t-gray-200 !gl-pl-7 gl-border-t-solid"
:class="{ 'gl-mt-3': !filteredNamespacesList.length }"
@click="onSelect(searchTerm)"
>

View File

@ -319,7 +319,7 @@ export default {
<environment-item
v-for="environment in environments"
:key="environment.name"
class="gl-mb-3 gl-border-gray-100 gl-border-1 gl-border-b-solid"
class="gl-mb-3 gl-border-1 gl-border-gray-100 gl-border-b-solid"
:environment="environment.latest"
@change="refetchEnvironments"
/>

View File

@ -90,8 +90,8 @@ export default {
<div>
<deploy-freeze-alert :name="environment.name" />
<header class="top-area gl-justify-content-between gl-border-none">
<div class="gl-display-flex gl-flex-grow-1 gl-align-items-center">
<h1 class="page-title gl-font-size-h-display">
<div class="gl-flex gl-grow gl-items-center">
<h1 class="page-title gl-text-size-h-display">
{{ environment.name }}
</h1>
<p

View File

@ -172,7 +172,7 @@ export default {
'gl-border-t-solid',
'gl-border-1',
'gl-py-5',
'gl-md-pl-7',
'md:gl-pl-7',
'gl-bg-gray-10',
],
deployBoardClasses: [
@ -180,20 +180,15 @@ export default {
'gl-border-t-solid',
'gl-border-1',
'gl-py-4',
'gl-md-pl-7',
'md:gl-pl-7',
'gl-bg-gray-10',
],
};
</script>
<template>
<div>
<div
class="gl-px-3 gl-pt-3 gl-pb-5 gl-display-flex gl-justify-content-space-between gl-align-items-center"
>
<div
:class="{ 'gl-ml-7': inFolder }"
class="gl-min-w-0 gl-mr-4 gl-display-flex gl-align-items-center"
>
<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"
@ -205,7 +200,7 @@ export default {
<gl-link
v-gl-tooltip
:href="environment.environmentPath"
class="gl-text-blue-500 gl-text-truncate"
class="gl-truncate gl-text-blue-500"
:class="{ 'gl-font-bold': visible }"
:title="name"
>
@ -219,8 +214,8 @@ export default {
>{{ tier }}</gl-badge
>
</div>
<div class="gl-display-flex gl-align-items-center">
<p v-if="canShowAutoStopDate" class="gl-font-sm gl-text-gray-700 gl-mr-5 gl-mb-0">
<div class="gl-flex gl-items-center">
<p v-if="canShowAutoStopDate" class="gl-mb-0 gl-mr-5 gl-text-sm gl-text-gray-700">
<gl-sprintf :message="$options.i18n.autoStopIn">
<template #time>
<time-ago-tooltip :time="environment.autoStopAt" css-class="gl-font-bold" />
@ -342,8 +337,8 @@ export default {
class="gl-pl-4"
/>
</div>
<div v-if="hasOpenedAlert" class="gl-bg-gray-10 gl-md-px-7">
<environment-alert :environment="environment" class="gl-pl-4 gl-py-5" />
<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>

View File

@ -77,11 +77,7 @@ export default {
<template #modal-title>
<gl-sprintf :message="s__('Environments|Stopping %{environmentName}')">
<template #environmentName>
<span
v-gl-tooltip
:title="environment.name"
class="gl-text-truncate gl-ml-2 gl-mr-2 gl-flex-grow-1"
>
<span v-gl-tooltip :title="environment.name" class="gl-ml-2 gl-mr-2 gl-grow gl-truncate">
{{ environment.name }}?
</span>
</template>

View File

@ -170,9 +170,9 @@ export default {
<div class="gl-relative gl-min-h-6">
<div
v-if="isLoading"
class="gl-absolute gl-top-0 gl-left-0 gl-w-full gl-h-full gl-z-200 gl-bg-gray-10 gl-opacity-3"
class="gl-absolute gl-left-0 gl-top-0 gl-z-200 gl-h-full gl-w-full gl-bg-gray-10 gl-opacity-3"
></div>
<gl-loading-icon v-if="isLoading" size="lg" class="gl-absolute gl-top-1/2 gl-left-1/2" />
<gl-loading-icon v-if="isLoading" size="lg" class="gl-absolute gl-left-1/2 gl-top-1/2" />
<div v-if="isDeploymentTableShown">
<deployments-table :deployments="deployments" />
<pagination :page-info="pageInfo" :disabled="isPaginationDisabled" />

View File

@ -152,7 +152,7 @@ export default {
<logs-viewer v-else-if="logLines" :log-lines="logLines" :highlighted-line="highlightedLineHash"
><template #header-details
><div class="gl-p-3 gl-ml-auto">
><div class="gl-ml-auto gl-p-3">
<span v-for="(item, index) of headerData" :key="index" class="gl-mr-4">
<gl-icon :name="item.icon" class="gl-mr-2" />{{ item.label }}: {{ item.value }}</span
>

View File

@ -273,10 +273,8 @@ export default {
};
</script>
<template>
<div v-if="clusterAgent" class="gl-p-5 gl-bg-gray-10 -gl-mt-3">
<div
class="gl-display-flex gl-flex-wrap gl-justify-content-space-between gl-align-items-center"
>
<div v-if="clusterAgent" class="-gl-mt-3 gl-bg-gray-10 gl-p-5">
<div class="gl-flex gl-flex-wrap gl-items-center gl-justify-between">
<kubernetes-agent-info :cluster-agent="clusterAgent" class="gl-mb-2 gl-mr-5 gl-grow" />
<kubernetes-status-bar
ref="status_bar"
@ -346,7 +344,7 @@ export default {
@close="closeDetailsDrawer"
>
<template #title>
<h2 class="gl-font-bold gl-m-0 gl-break-anywhere">
<h2 class="gl-m-0 gl-font-bold gl-break-anywhere">
{{ selectedItem.name }}
</h2>
</template>

View File

@ -238,7 +238,7 @@ export default {
<gl-popover :target="fluxBadgeId" :title="syncStatusBadge.popoverTitle">
<gl-sprintf :message="syncStatusBadge.popoverText">
<template #link="{ content }">
<gl-link :href="syncStatusBadge.popoverLink" class="gl-font-sm">{{
<gl-link :href="syncStatusBadge.popoverLink" class="gl-text-sm">{{
content
}}</gl-link></template
>

View File

@ -114,7 +114,7 @@ export default {
}}</gl-alert>
<div
class="gl-flex gl-items-start gl-overflow-x-auto gl-overflow-y-hidden kubernetes-tree-view"
class="kubernetes-tree-view gl-flex gl-items-start gl-overflow-x-auto gl-overflow-y-hidden"
>
<kubernetes-tree-item
v-if="hasFluxKustomization"
@ -130,7 +130,7 @@ export default {
class="gl-relative"
>
<div
class="connector gl-border-1 gl-border-t-solid gl-border-gray-200 gl-absolute gl-z-0 gl-top-1/2 gl-right-1/2"
class="connector gl-absolute gl-right-1/2 gl-top-1/2 gl-z-0 gl-border-1 gl-border-gray-200 gl-border-t-solid"
:class="{
'gl-border-l-solid': !isLast(index),
}"

View File

@ -36,11 +36,11 @@ export default {
</script>
<template>
<div
class="gl-border-1 gl-border-solid gl-border-gray-200 gl-rounded gl-p-3 gl-bg-white gl-flex gl-w-28 gl-z-1 gl-relative"
class="gl-rounded gl-relative gl-z-1 gl-flex gl-w-28 gl-border-1 gl-border-solid gl-border-gray-200 gl-bg-white gl-p-3"
>
<gl-icon :name="kindIcon" data-testid="resource-kind-icon" />
<div class="gl-ml-4">
<span class="gl-text-secondary gl-block gl-mb-2">{{ kind }}:</span>
<span class="gl-mb-2 gl-block gl-text-secondary">{{ kind }}:</span>
<div class="gl-flex gl-items-center">
<span class="gl-line-clamp-1 gl-break-all" :title="name">{{ name }}</span>
<gl-icon

View File

@ -9,56 +9,56 @@ export const ENVIRONMENT_DETAILS_TABLE_FIELDS = [
label: __('Status'),
columnClass: 'gl-w-2/20',
tdClass: '!gl-align-middle',
thClass: 'gl-border-t-none!',
thClass: '!gl-border-t-0',
},
{
key: 'id',
label: __('ID'),
columnClass: 'gl-w-1/20',
tdClass: '!gl-align-middle',
thClass: 'gl-border-t-none!',
thClass: '!gl-border-t-0',
},
{
key: 'triggerer',
label: __('Triggerer'),
columnClass: 'gl-w-2/20',
tdClass: '!gl-align-middle',
thClass: 'gl-border-t-none!',
thClass: '!gl-border-t-0',
},
{
key: 'commit',
label: __('Commit'),
columnClass: 'gl-w-4/20',
tdClass: '!gl-align-middle',
thClass: 'gl-border-t-none!',
thClass: '!gl-border-t-0',
},
{
key: 'job',
label: __('Job'),
columnClass: 'gl-w-3/20',
tdClass: '!gl-align-middle',
thClass: 'gl-border-t-none!',
thClass: '!gl-border-t-0',
},
{
key: 'created',
label: __('Created'),
columnClass: 'gl-w-2/20',
tdClass: '!gl-align-middle gl-whitespace-nowrap',
thClass: 'gl-border-t-none!',
thClass: '!gl-border-t-0',
},
{
key: 'deployed',
label: __('Deployed'),
columnClass: 'gl-w-2/20',
tdClass: '!gl-align-middle gl-whitespace-nowrap',
thClass: 'gl-border-t-none!',
thClass: '!gl-border-t-0',
},
{
key: 'actions',
label: __('Actions'),
columnClass: 'gl-w-3/20',
tdClass: '!gl-align-middle gl-whitespace-nowrap',
thClass: 'gl-border-t-none!',
thClass: '!gl-border-t-0',
},
];

View File

@ -59,7 +59,7 @@ export default {
};
</script>
<template>
<div v-if="isPaginationVisible" class="gl-flex gl-justify-center gl-items-center">
<div v-if="isPaginationVisible" class="gl-flex gl-items-center gl-justify-center">
<gl-keyset-pagination
v-bind="pageInfo"
:prev-button-link="previousLink"

View File

@ -223,7 +223,7 @@ export default {
<div
v-for="n in lastRowCount"
:key="`skeleton-box-${n}`"
class="gl-border-gray-100 gl-border-t-solid gl-border-1 gl-py-5 gl-md-pl-7"
class="gl-border-1 gl-border-gray-100 gl-py-5 gl-border-t-solid md:gl-pl-7"
>
<gl-skeleton-loader :lines="2" />
</div>
@ -242,7 +242,7 @@ export default {
:id="environment.name"
:key="index"
:environment="environment"
class="gl-border-gray-100 gl-border-t-solid gl-border-1 gl-pt-3"
class="gl-border-1 gl-border-gray-100 gl-pt-3 gl-border-t-solid"
in-folder
/>
</div>

View File

@ -121,7 +121,7 @@ class Projects::IssuesController < Projects::ApplicationController
build_params = issue_params.merge(
merge_request_to_resolve_discussions_of: params[:merge_request_to_resolve_discussions_of],
discussion_to_resolve: params[:discussion_to_resolve],
observability_links: { metrics: params[:observability_metric_details], logs: params[:observability_log_details] },
observability_links: { metrics: params[:observability_metric_details], logs: params[:observability_log_details], tracing: params[:observability_trace_details] },
confidential: !!Gitlab::Utils.to_boolean(issue_params[:confidential])
)
service = ::Issues::BuildService.new(container: project, current_user: current_user, params: build_params)

View File

@ -22,7 +22,6 @@ module Types
description: 'Name of the pipeline.'
field :sha, GraphQL::Types::String, null: true,
method: :sha,
description: "SHA of the pipeline's commit." do
argument :format,
type: Types::ShaFormatEnum,
@ -188,13 +187,13 @@ module Types
field :triggered_by_path, GraphQL::Types::String, null: true, description: "The path that triggered this pipeline"
field :source, GraphQL::Types::String, null: true, method: :source, description: "The source of the pipeline"
field :source, GraphQL::Types::String, null: true, description: "The source of the pipeline"
field :child, GraphQL::Types::Boolean, null: false, method: :child?, description: "If the pipeline is a child or not"
field :latest, GraphQL::Types::Boolean, null: false, method: :latest?, calls_gitaly: true, description: "If the pipeline is the latest one or not"
field :ref_text, GraphQL::Types::String, null: false, method: :ref_text, description: "The reference text from the presenter", calls_gitaly: true
field :ref_text, GraphQL::Types::String, null: false, description: "The reference text from the presenter", calls_gitaly: true
field :merge_request, Types::MergeRequestType, null: true, description: "The MR which the Pipeline is attached to"

View File

@ -15,13 +15,11 @@ module Types
description: 'Architecture provided by the runner manager.',
method: :architecture
field :contacted_at, Types::TimeType, null: true,
description: 'Timestamp of last contact from the runner manager.',
method: :contacted_at
description: 'Timestamp of last contact from the runner manager.'
field :created_at, Types::TimeType, null: true,
description: 'Timestamp of creation of the runner manager.'
field :executor_name, GraphQL::Types::String, null: true,
description: 'Executor last advertised by the runner.',
method: :executor_name
description: 'Executor last advertised by the runner.'
field :id, ::Types::GlobalIDType[::Ci::RunnerManager], null: false,
description: 'ID of the runner manager.'
field :ip_address, GraphQL::Types::String, null: true,

View File

@ -24,8 +24,7 @@ module Types
field :admin_url, GraphQL::Types::String, null: true,
description: 'Admin URL of the runner. Only available for administrators.'
field :contacted_at, Types::TimeType, null: true,
description: 'Timestamp of last contact from this runner.',
method: :contacted_at
description: 'Timestamp of last contact from this runner.'
field :created_at, Types::TimeType, null: true,
description: 'Timestamp of creation of this runner.'
field :created_by, Types::UserType, null: true,
@ -100,8 +99,7 @@ module Types
field :tag_list, [GraphQL::Types::String], null: true,
description: 'Tags associated with the runner.'
field :token_expires_at, Types::TimeType, null: true,
description: 'Runner token expiration time.',
method: :token_expires_at
description: 'Runner token expiration time.'
markdown_field :maintenance_note_html, null: true

View File

@ -13,8 +13,7 @@ module Types
field :path,
GraphQL::Types::String,
description: 'Path for this tag.',
hash_key: :path
description: 'Path for this tag.'
field :web_path,
GraphQL::Types::String,

View File

@ -58,6 +58,10 @@ module Types
Types::Import::SourceUserStatusEnum,
null: false,
description: 'Status of the mapping.'
field :reassignment_error,
GraphQL::Types::String,
description: 'Error message if reassignment failed.'
end
end
end

View File

@ -162,7 +162,7 @@ module Types
field :timelogs, Types::TimelogType.connection_type, null: false,
description: 'Timelogs on the issue.'
field :project_id, GraphQL::Types::Int, null: true, method: :project_id,
field :project_id, GraphQL::Types::Int, null: true,
description: 'ID of the issue project.'
field :customer_relations_contacts, Types::CustomerRelations::ContactType.connection_type, null: true,

View File

@ -13,10 +13,10 @@ module Types
null: true, description: 'Path to the details page of the model version.', method: :path
field :package_path, GraphQL::Types::String,
null: true, description: 'Path to the package of the model version.', method: :package_path
null: true, description: 'Path to the package of the model version.'
field :import_path, GraphQL::Types::String,
null: true, description: 'File upload path for the machine learning model.', method: :import_path
null: true, description: 'File upload path for the machine learning model.'
end
# rubocop: enable Graphql/AuthorizeTypes
end

View File

@ -10,13 +10,11 @@ module Types
field :ahead, GraphQL::Types::Int,
null: true,
calls_gitaly: true,
method: :ahead,
description: 'Number of commits ahead of upstream.'
field :behind, GraphQL::Types::Int,
null: true,
calls_gitaly: true,
method: :behind,
description: 'Number of commits behind upstream.'
field :is_syncing, GraphQL::Types::Boolean,

View File

@ -53,7 +53,7 @@ module Types
field :raw_blob, GraphQL::Types::String, null: true, method: :data,
description: 'Raw content of the blob.'
field :base64_encoded_blob, GraphQL::Types::String, null: true, method: :base64_encoded_blob,
field :base64_encoded_blob, GraphQL::Types::String, null: true,
alpha: { milestone: '17.1' }, description: 'Content of blob is encoded base64. Returns `null` if the `unicode_escaped_data` feature flag is disabled.'
field :raw_text_blob, GraphQL::Types::String, null: true, method: :text_only_data,
@ -62,7 +62,7 @@ module Types
field :stored_externally, GraphQL::Types::Boolean, null: true, method: :stored_externally?,
description: "Whether the blob's content is stored externally (for instance, in LFS)."
field :external_storage, GraphQL::Types::String, null: true, method: :external_storage,
field :external_storage, GraphQL::Types::String, null: true,
description: "External storage being used, if enabled (for instance, 'LFS')."
field :edit_blob_path, GraphQL::Types::String, null: true,

View File

@ -3,7 +3,7 @@
module StatAnchorsHelper
def stat_anchor_attrs(anchor)
{}.tap do |attrs|
attrs[:class] = %w[nav-link gl-flex gl-items-center] << extra_classes(anchor)
attrs[:class] = %w[nav-link] << extra_classes(anchor)
attrs[:itemprop] = anchor.itemprop if anchor.itemprop
attrs[:data] = anchor.data if anchor.data
end

View File

@ -19,6 +19,8 @@ module Ci
include EachBatch
include FastDestroyAll::Helpers
self.primary_key = :id
MAX_OPEN_MERGE_REQUESTS_REFS = 4
PROJECT_ROUTE_AND_NAMESPACE_ROUTE = {

View File

@ -68,7 +68,7 @@ module Integrations
# - close/s/d
# - closing
issue_finder = %r{(?:https://app\.asana\.com/\d+/\w+/(\w+)|#(\w+))}i
proceded_keyword_finder = %r{(fix\w*|clos[ei]\w*+)}i
proceded_keyword_finder = %r{(fix\w*|clos[ei]\w*)\s*\z}i
message.split(issue_finder).each_slice(2) do |prepended_text, task_id|
next unless task_id

View File

@ -5,6 +5,5 @@ feature_category: package_registry
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/159861
milestone: '17.3'
queued_migration_version: 20240718085345
# Replace with the approximate date you think it's best to ensure the completion of this BBM.
finalize_after: '2024-08-19'
finalized_by: # version of the migration that finalized this BBM
finalized_by: 20240816092254

View File

@ -0,0 +1,19 @@
# frozen_string_literal: true
class AddReassignmentErrorToImportSourceUser < Gitlab::Database::Migration[2.2]
milestone '17.4'
disable_ddl_transaction! # For `add_text_limit`
def up
with_lock_retries do
add_column :import_source_users, :reassignment_error, :text, if_not_exists: true
end
add_text_limit :import_source_users, :reassignment_error, 255
end
def down
remove_column :import_source_users, :reassignment_error, if_exists: true
end
end

View File

@ -0,0 +1,17 @@
# frozen_string_literal: true
class DropIndexOnComponentVersionsByComponentId < Gitlab::Database::Migration[2.2]
milestone '17.4'
disable_ddl_transaction!
INDEX_NAME = 'index_sbom_component_versions_on_component_id'
def up
remove_concurrent_index_by_name :sbom_component_versions, INDEX_NAME
end
def down
add_concurrent_index :sbom_component_versions, :component_id, name: INDEX_NAME
end
end

View File

@ -0,0 +1,23 @@
# frozen_string_literal: true
class FinalizeDeletePackagesComposerCacheFileRecords < Gitlab::Database::Migration[2.2]
milestone '17.4'
restrict_gitlab_migration gitlab_schema: :gitlab_main
disable_ddl_transaction!
MIGRATION = 'DeletePackagesComposerCacheFileRecords'
def up
ensure_batched_background_migration_is_finished(
job_class_name: MIGRATION,
table_name: :packages_composer_cache_files,
column_name: :id,
job_arguments: [],
finalize: true
)
end
def down
# no-op
end
end

View File

@ -0,0 +1,74 @@
# frozen_string_literal: true
class SwapPrimaryKeyForCiPipelinesToIncludePartitionId < Gitlab::Database::Migration[2.2]
include Gitlab::Database::PartitioningMigrationHelpers
milestone '17.4'
disable_ddl_transaction!
TABLE_NAME = :ci_pipelines
PRIMARY_KEY = :ci_pipelines_pkey
OLD_INDEX_NAME = :index_ci_pipelines_on_id
NEW_INDEX_NAME = :index_ci_pipelines_on_id_and_partition_id
def up
swap_primary_key(TABLE_NAME, PRIMARY_KEY, NEW_INDEX_NAME)
end
def down
add_concurrent_index(TABLE_NAME, :id, unique: true, name: OLD_INDEX_NAME)
add_concurrent_index(TABLE_NAME, [:id, :partition_id], unique: true, name: NEW_INDEX_NAME)
unswap_primary_key(TABLE_NAME, PRIMARY_KEY, OLD_INDEX_NAME)
recreate_partitioned_foreign_keys
end
private
def recreate_partitioned_foreign_keys
add_partitioned_fk(:ci_pipelines, :fk_262d4c2d19_p,
columns: [:auto_canceled_by_partition_id, :auto_canceled_by_id], on_delete: :nullify)
add_partitioned_fk(:ci_pipeline_chat_data, :fk_64ebfab6b3_p)
add_partitioned_fk(:ci_sources_pipelines, :fk_d4e29af7d7_p, columns: [:source_partition_id, :source_pipeline_id])
add_partitioned_fk(:ci_sources_pipelines, :fk_e1bad85861_p)
add_partitioned_fk(:ci_sources_projects, :fk_rails_10a1eb379a_p)
add_partitioned_fk(:ci_pipeline_metadata, :fk_rails_50c1e9ea10_p)
add_partitioned_fk(:ci_pipeline_messages, :fk_rails_8d3b04e3e1_p)
add_partitioned_fk(:ci_pipelines_config, :fk_rails_906c9a2533_p)
add_partitioned_fk(:ci_pipeline_artifacts, :fk_rails_a9e811a466_p)
add_partitioned_fk(:ci_daily_build_group_report_results, :fk_rails_ee072d13b3_p,
columns: [:partition_id, :last_pipeline_id])
add_routing_table_fk(:p_ci_builds, :fk_87f4cefcda_p,
columns: [:upstream_pipeline_partition_id, :upstream_pipeline_id])
add_routing_table_fk(:p_ci_builds, :fk_a2141b1522_p,
columns: [:auto_canceled_by_partition_id, :auto_canceled_by_id],
on_delete: :nullify)
add_routing_table_fk(:p_ci_builds, :fk_d3130c9a7f_p,
columns: [:partition_id, :commit_id])
add_routing_table_fk(:p_ci_pipeline_variables, :fk_f29c5f4380_p)
add_routing_table_fk(:p_ci_stages, :fk_fb57e6cc56_p)
add_routing_table_fk(:p_ci_builds_execution_configs, :fk_rails_c26408d02c_p)
end
def add_partitioned_fk(source_table, name, column: :pipeline_id, columns: nil, on_delete: :cascade)
add_concurrent_foreign_key(source_table, :ci_pipelines,
column: columns || [:partition_id, column],
target_column: [:partition_id, :id],
reverse_lock_order: true,
on_update: :cascade,
on_delete: on_delete,
name: name)
end
def add_routing_table_fk(source_table, name, columns: nil, on_delete: :cascade)
add_concurrent_partitioned_foreign_key(source_table, :ci_pipelines,
column: columns || [:partition_id, :pipeline_id],
target_column: [:partition_id, :id],
reverse_lock_order: true,
on_update: :cascade,
on_delete: on_delete,
name: name)
end
end

View File

@ -0,0 +1 @@
714fc32a8c01858b39c9a1c5b351186befa3b6573bfd5e4dccd2e772493e0079

View File

@ -0,0 +1 @@
47b8ca66ee1e5ae057c53ea6b8834c30d38eb6b336f95d369ec93847c689bedd

View File

@ -0,0 +1 @@
cb5d108547a460ac052b064f1ed8d67c0391868a499903e6491ddac42a5dbfc6

View File

@ -0,0 +1 @@
b4281c835c83a3a35561abb06f0d818bf53a021f2a68abcff4304d5ce2f6e2ce

View File

@ -11564,6 +11564,8 @@ CREATE TABLE import_source_users (
source_hostname text NOT NULL,
import_type text NOT NULL,
reassigned_by_user_id bigint,
reassignment_error text,
CONSTRAINT check_05708218cd CHECK ((char_length(reassignment_error) <= 255)),
CONSTRAINT check_0d7295a307 CHECK ((char_length(import_type) <= 255)),
CONSTRAINT check_199c28ec54 CHECK ((char_length(source_username) <= 255)),
CONSTRAINT check_562655155f CHECK ((char_length(source_name) <= 255)),
@ -23189,7 +23191,7 @@ ALTER TABLE ONLY ci_pipelines_config
ADD CONSTRAINT ci_pipelines_config_pkey PRIMARY KEY (pipeline_id);
ALTER TABLE ONLY ci_pipelines
ADD CONSTRAINT ci_pipelines_pkey PRIMARY KEY (id);
ADD CONSTRAINT ci_pipelines_pkey PRIMARY KEY (id, partition_id);
ALTER TABLE ONLY ci_platform_metrics
ADD CONSTRAINT ci_platform_metrics_pkey PRIMARY KEY (id);
@ -27212,8 +27214,6 @@ CREATE INDEX index_ci_pipelines_on_ci_ref_id_and_more ON ci_pipelines USING btre
CREATE INDEX index_ci_pipelines_on_external_pull_request_id ON ci_pipelines USING btree (external_pull_request_id) WHERE (external_pull_request_id IS NOT NULL);
CREATE UNIQUE INDEX index_ci_pipelines_on_id_and_partition_id ON ci_pipelines USING btree (id, partition_id);
CREATE INDEX index_ci_pipelines_on_merge_request_id ON ci_pipelines USING btree (merge_request_id) WHERE (merge_request_id IS NOT NULL);
CREATE INDEX index_ci_pipelines_on_pipeline_schedule_id_and_id ON ci_pipelines USING btree (pipeline_schedule_id, id);
@ -29650,8 +29650,6 @@ CREATE INDEX index_saml_providers_on_member_role_id ON saml_providers USING btre
CREATE UNIQUE INDEX index_saved_replies_on_name_text_pattern_ops ON saved_replies USING btree (user_id, name text_pattern_ops);
CREATE INDEX index_sbom_component_versions_on_component_id ON sbom_component_versions USING btree (component_id);
CREATE UNIQUE INDEX index_sbom_component_versions_on_component_id_and_version ON sbom_component_versions USING btree (component_id, version);
CREATE UNIQUE INDEX index_sbom_components_on_component_type_name_and_purl_type ON sbom_components USING btree (name, purl_type, component_type);

View File

@ -24258,6 +24258,7 @@ IDE settings and feature flags.
| <a id="importsourceuserplaceholderuser"></a>`placeholderUser` | [`UserCore`](#usercore) | Placeholder user associated with the import source user. |
| <a id="importsourceuserreassigntouser"></a>`reassignToUser` | [`UserCore`](#usercore) | User that contributions are reassigned to. |
| <a id="importsourceuserreassignedbyuser"></a>`reassignedByUser` | [`UserCore`](#usercore) | User that did the reassignment. |
| <a id="importsourceuserreassignmenterror"></a>`reassignmentError` | [`String`](#string) | Error message if reassignment failed. |
| <a id="importsourceusersourcehostname"></a>`sourceHostname` | [`String!`](#string) | Source instance hostname. |
| <a id="importsourceusersourcename"></a>`sourceName` | [`String`](#string) | Name of user in the source instance. |
| <a id="importsourceusersourceuseridentifier"></a>`sourceUserIdentifier` | [`String!`](#string) | ID of the user in the source instance. |

View File

@ -33,7 +33,7 @@ For example, your generated `.gitmodules` configuration might look like the foll
```ini
[submodule "project"]
path = project
url = git@gitlab.com:secret-group/project.git
url = git@gitlab.com:group/project.git
```
In this case, use the [`GIT_SUBMODULE_FORCE_HTTPS`](runners/configure_runners.md#rewrite-submodule-urls-to-https) variable
@ -44,7 +44,7 @@ Alternatively, if you also use HTTPS locally, you can configure an HTTPS URL:
```ini
[submodule "project"]
path = project
url = https://gitlab.com/secret-group/project.git
url = https://gitlab.com/group/project.git
```
You do not need to configure additional variables in this case, but you need to use a

View File

@ -52,15 +52,18 @@ DETAILS:
- <i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [Watch overview](https://youtu.be/ds7SG1wgcVM)
- [View documentation](../project/repository/code_suggestions/index.md).
### Code explanation in the IDE
### Code explanation
DETAILS:
**Tier: GitLab.com and Self-managed:** For a limited time, Premium or Ultimate. In the future, Premium with GitLab Duo Pro or Ultimate with [GitLab Duo Pro or Enterprise](../../subscriptions/subscription-add-ons.md). **GitLab Dedicated:** GitLab Duo Pro or Enterprise.
**Tier: GitLab.com and Self-managed:** Premium or Ultimate for a limited time. In the future, Premium with GitLab Duo Pro or Ultimate with [GitLab Duo Pro or Enterprise](../../subscriptions/subscription-add-ons.md). **GitLab Dedicated:** GitLab Duo Pro or Enterprise.
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
- Helps you understand the selected code by explaining it more clearly.
- LLM: Anthropic: [Claude 3 Haiku](https://console.cloud.google.com/vertex-ai/publishers/anthropic/model-garden/claude-3-haiku)
- View documentation for [explaining code in the IDE](../gitlab_duo_chat/examples.md#explain-code-in-the-ide).
- LLM: Anthropic [Claude 3.5 Sonnet](https://console.cloud.google.com/vertex-ai/publishers/anthropic/model-garden/claude-3-5-sonnet)
- View documentation for explaining code in:
- [The IDE](../gitlab_duo_chat/examples.md#explain-code).
- [A file](../../user/project/repository/code_explain.md).
- [A merge request](../../user/project/merge_requests/changes.md#explain-code-in-a-merge-request).
### Test generation
@ -181,19 +184,6 @@ DETAILS:
- LLM: Anthropic [Claude Instant 1.2](https://docs.anthropic.com/en/docs/about-claude/models#legacy-models)
- [View documentation](experiments.md#summarize-an-issue-with-issue-description-generation).
### Code explanation in a file or merge request
DETAILS:
**Tier:** Premium or Ultimate for a limited time. In the future, Premium with GitLab Duo Pro or Ultimate [GitLab Duo Pro or Enterprise](../../subscriptions/subscription-add-ons.md).
**Offering:** GitLab.com
**Status:** Experiment
- Helps you understand the selected code by explaining it more clearly.
- LLM: Anthropic: [Claude 3 Haiku](https://console.cloud.google.com/vertex-ai/publishers/anthropic/model-garden/claude-3-haiku)
- View documentation for explaining code in:
- [A file](../../user/project/repository/code_explain.md).
- [A merge request](../../user/project/merge_requests/changes.md#explain-code-in-a-merge-request).
### Code review summary
DETAILS:

View File

@ -58,7 +58,7 @@ And you can ask GitLab Duo Chat to explain code:
- `Provide a clear explanation of the given Ruby code: def sum(a, b) a + b end. Describe what this code does and how it works.`
Alternatively, you can use the [`/explain` command](examples.md#explain-code-in-the-ide) to explain the selected code in your editor.
Alternatively, you can use the [`/explain` command](examples.md#explain-code) to explain the selected code in your editor.
## Ask about CI/CD
@ -128,12 +128,12 @@ DETAILS:
[Learn more](../application_security/vulnerabilities/index.md#explaining-a-vulnerability).
## Explain code in the IDE
## Explain code
DETAILS:
**Tier: GitLab.com and Self-managed:** Premium or Ultimate for a limited time. In the future, Premium with GitLab Duo Pro or Ultimate with [GitLab Duo Pro or Enterprise](../../subscriptions/subscription-add-ons.md). **GitLab Dedicated:** GitLab Duo Pro or Enterprise.
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
**Editors:** Web IDE, VS Code, JetBrains IDEs
**Editors:** GitLab UI, Web IDE, VS Code, JetBrains IDEs
**LLMs:** Anthropic: [`claude-3-5-sonnet-20240620`](https://console.cloud.google.com/vertex-ai/publishers/anthropic/model-garden/claude-3-5-sonnet)
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/429915) for GitLab.com in GitLab 16.7.
@ -307,7 +307,7 @@ Use the following commands to quickly accomplish specific tasks.
| /clear | [Delete all conversations permanently and clear the chat window](#delete-or-reset-the-conversation) |
| /reset | [Start a new conversation, but keep the previous conversations visible in the chat window](#delete-or-reset-the-conversation) |
| /tests | [Write tests](#write-tests-in-the-ide) |
| /explain | [Explain code](../gitlab_duo_chat/examples.md#explain-code-in-the-ide) |
| /explain | [Explain code](../gitlab_duo_chat/examples.md#explain-code) |
| /vulnerability_explain | [Explain current vulnerability](../gitlab_duo/index.md#vulnerability-explanation) |
| /refactor | [Refactor the code](../gitlab_duo_chat/examples.md#refactor-code-in-the-ide) |
| /troubleshoot | [Troubleshoot failed CI/CD jobs with root cause analysis](#troubleshoot-failed-cicd-jobs-with-root-cause-analysis) |

View File

@ -82,7 +82,7 @@ For more information about slash commands, refer to the documentation:
- [/tests](../gitlab_duo_chat/examples.md#write-tests-in-the-ide)
- [/refactor](../gitlab_duo_chat/examples.md#refactor-code-in-the-ide)
- [/fix](../gitlab_duo_chat/examples.md#fix-code-in-the-ide)
- [/explain](../gitlab_duo_chat/examples.md#explain-code-in-the-ide)
- [/explain](../gitlab_duo_chat/examples.md#explain-code)
## `Error M4001`

View File

@ -222,11 +222,11 @@ To change how a merge request shows changed lines:
## Explain code in a merge request
DETAILS:
**Tier:** Premium or Ultimate for a limited time. In the future, Premium with GitLab Duo Pro or Ultimate [GitLab Duo Pro or Enterprise](../../../subscriptions/subscription-add-ons.md).
**Offering:** GitLab.com
**Status:** Experiment
**Tier: GitLab.com and Self-managed:** Premium or Ultimate for a limited time. In the future, Premium with GitLab Duo Pro or Ultimate with [GitLab Duo Pro or Enterprise](../../../subscriptions/subscription-add-ons.md). **GitLab Dedicated:** GitLab Duo Pro or Enterprise.
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
> - Introduced in GitLab 15.11 as an [experiment](../../../policy/experiment-beta-support.md#experiment) on GitLab.com.
> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/429915) in GitLab 16.8.
If you spend a lot of time trying to understand code that others have created, or
you struggle to understand code written in a language you are not familiar with,
@ -261,7 +261,7 @@ We cannot guarantee that the large language model produces results that are corr
You can also explain code in:
- A [file](../../../user/project/repository/code_explain.md).
- The [IDE](../../../user/gitlab_duo_chat/examples.md#explain-code-in-the-ide).
- The [IDE](../../../user/gitlab_duo_chat/examples.md#explain-code).
## Expand or collapse comments

View File

@ -1,17 +1,17 @@
---
stage: Create
group: Code Review
group: Code Creation
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
# Explain code in a file
DETAILS:
**Tier:** For a limited time, Premium and Ultimate. In the future, [GitLab Duo Pro or Enterprise](../../../subscriptions/subscription-add-ons.md).
**Offering:** GitLab.com
**Status:** Experiment
**Tier: GitLab.com and Self-managed:** Premium or Ultimate for a limited time. In the future, Premium with GitLab Duo Pro or Ultimate with [GitLab Duo Pro or Enterprise](../../../subscriptions/subscription-add-ons.md). **GitLab Dedicated:** GitLab Duo Pro or Enterprise.
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
> - Introduced in GitLab 15.11 as an [experiment](../../../policy/experiment-beta-support.md#experiment) on GitLab.com.
> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/429915) in GitLab 16.8.
If you spend a lot of time trying to understand code that others have created, or
you struggle to understand code written in a language you are not familiar with,
@ -42,4 +42,4 @@ We cannot guarantee that the large language model produces results that are corr
You can also explain code in:
- A [merge request](../../../user/project/merge_requests/changes.md#explain-code-in-a-merge-request).
- The [IDE](../../../user/gitlab_duo_chat/examples.md#explain-code-in-the-ide).
- The [IDE](../../../user/gitlab_duo_chat/examples.md#explain-code).

View File

@ -7,14 +7,14 @@ module Gitlab
module Validators
class SchemaValidator
SUPPORTED_VERSIONS = {
cluster_image_scanning: %w[15.0.0 15.0.1 15.0.2 15.0.4 15.0.5 15.0.6 15.0.7 15.1.0 15.1.1 15.1.2 15.1.3 15.1.4],
container_scanning: %w[15.0.0 15.0.1 15.0.2 15.0.4 15.0.5 15.0.6 15.0.7 15.1.0 15.1.1 15.1.2 15.1.3 15.1.4],
coverage_fuzzing: %w[15.0.0 15.0.1 15.0.2 15.0.4 15.0.5 15.0.6 15.0.7 15.1.0 15.1.1 15.1.2 15.1.3 15.1.4],
dast: %w[15.0.0 15.0.1 15.0.2 15.0.4 15.0.5 15.0.6 15.0.7 15.1.0 15.1.1 15.1.2 15.1.3 15.1.4],
api_fuzzing: %w[15.0.0 15.0.1 15.0.2 15.0.4 15.0.5 15.0.6 15.0.7 15.1.0 15.1.1 15.1.2 15.1.3 15.1.4],
dependency_scanning: %w[15.0.0 15.0.1 15.0.2 15.0.4 15.0.5 15.0.6 15.0.7 15.1.0 15.1.1 15.1.2 15.1.3 15.1.4],
sast: %w[15.0.0 15.0.1 15.0.2 15.0.4 15.0.5 15.0.6 15.0.7 15.1.0 15.1.1 15.1.2 15.1.3 15.1.4],
secret_detection: %w[15.0.0 15.0.1 15.0.2 15.0.4 15.0.5 15.0.6 15.0.7 15.1.0 15.1.1 15.1.2 15.1.3 15.1.4]
cluster_image_scanning: %w[15.0.0 15.0.1 15.0.2 15.0.4 15.0.5 15.0.6 15.0.7 15.1.0 15.1.1 15.1.2 15.1.3 15.1.4 15.2.0],
container_scanning: %w[15.0.0 15.0.1 15.0.2 15.0.4 15.0.5 15.0.6 15.0.7 15.1.0 15.1.1 15.1.2 15.1.3 15.1.4 15.2.0],
coverage_fuzzing: %w[15.0.0 15.0.1 15.0.2 15.0.4 15.0.5 15.0.6 15.0.7 15.1.0 15.1.1 15.1.2 15.1.3 15.1.4 15.2.0],
dast: %w[15.0.0 15.0.1 15.0.2 15.0.4 15.0.5 15.0.6 15.0.7 15.1.0 15.1.1 15.1.2 15.1.3 15.1.4 15.2.0],
api_fuzzing: %w[15.0.0 15.0.1 15.0.2 15.0.4 15.0.5 15.0.6 15.0.7 15.1.0 15.1.1 15.1.2 15.1.3 15.1.4 15.2.0],
dependency_scanning: %w[15.0.0 15.0.1 15.0.2 15.0.4 15.0.5 15.0.6 15.0.7 15.1.0 15.1.1 15.1.2 15.1.3 15.1.4 15.2.0],
sast: %w[15.0.0 15.0.1 15.0.2 15.0.4 15.0.5 15.0.6 15.0.7 15.1.0 15.1.1 15.1.2 15.1.3 15.1.4 15.2.0],
secret_detection: %w[15.0.0 15.0.1 15.0.2 15.0.4 15.0.5 15.0.6 15.0.7 15.1.0 15.1.1 15.1.2 15.1.3 15.1.4 15.2.0]
}.freeze
VERSIONS_TO_REMOVE_IN_18_0 = %w[].freeze

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -8461,6 +8461,9 @@ msgstr ""
msgid "BillingPlans|Free guest users"
msgstr ""
msgid "BillingPlans|Get the most out of GitLab with Ultimate and GitLab Duo Enterprise"
msgstr ""
msgid "BillingPlans|Have a question? We're here to help."
msgstr ""
@ -8470,6 +8473,9 @@ msgstr ""
msgid "BillingPlans|Includes"
msgstr ""
msgid "BillingPlans|Introducing GitLab Duo Enterprise"
msgstr ""
msgid "BillingPlans|Learn more about each plan by reading our %{faq_link}, or start a free 30-day trial of GitLab.com Ultimate."
msgstr ""
@ -8497,6 +8503,9 @@ msgstr ""
msgid "BillingPlans|No credit card required"
msgstr ""
msgid "BillingPlans|Not ready to trial the full suite of GitLab and GitLab Duo features? Start a free trial of GitLab Duo Pro instead."
msgstr ""
msgid "BillingPlans|Not the group you're looking for? %{all_groups_link}"
msgstr ""
@ -8527,6 +8536,12 @@ msgstr ""
msgid "BillingPlans|See all %{plan_name} features"
msgstr ""
msgid "BillingPlans|Start a GitLab Duo Enterprise trial to try all end-to-end AI capabilities from GitLab. You can try it for free for %{days} days, no credit card required."
msgstr ""
msgid "BillingPlans|Start a free GitLab Duo Enterprise Trial"
msgstr ""
msgid "BillingPlans|Start a free GitLab Duo Pro trial"
msgstr ""
@ -8536,6 +8551,15 @@ msgstr ""
msgid "BillingPlans|Start a free Ultimate trial. No credit card required."
msgstr ""
msgid "BillingPlans|Start an Ultimate trial with GitLab Duo Enterprise to try the complete set of features from GitLab. GitLab Duo Enterprise gives you access to the full product offering from GitLab, including AI-powered features."
msgstr ""
msgid "BillingPlans|Start an Ultimate trial with GitLab Duo Enterprise to try the complete set of features from GitLab. GitLab Duo Enterprise gives you access to the full product offering from GitLab, including AI-powered features. You can try it for free, no credit card required."
msgstr ""
msgid "BillingPlans|Start free trial of GitLab Ultimate and GitLab Duo Enterprise"
msgstr ""
msgid "BillingPlans|Static Application Security Testing"
msgstr ""
@ -8563,6 +8587,9 @@ msgstr ""
msgid "BillingPlans|Trusted by"
msgstr ""
msgid "BillingPlans|Try GitLab Duo Pro"
msgstr ""
msgid "BillingPlans|Ultimate"
msgstr ""

View File

@ -391,7 +391,6 @@ tests = [
spec/db/docs_spec.rb
spec/lib/gitlab/database/dictionary_spec.rb
spec/lib/gitlab/database/no_new_tables_with_gitlab_main_schema_spec.rb
spec/lib/gitlab/database/no_new_tables_with_gitlab_pm_schema_spec.rb
spec/lib/gitlab/database/sharding_key_spec.rb
]
}

View File

@ -2,7 +2,7 @@
FactoryBot.define do
factory :ci_catalog_resource, class: 'Ci::Catalog::Resource' do
project factory: [:project]
project
trait :published do
state { :published }

View File

@ -8,7 +8,7 @@ FactoryBot.define do
sequence(:name) { |n| "agent-#{n}" }
trait :in_group do
project factory: [:project, :in_group]
association :project, :in_group
end
end
end

View File

@ -85,7 +85,7 @@ FactoryBot.define do
end
factory :project_imported_event do
project factory: [:project, :with_import_url]
association :project, :with_import_url
action { :created }
end
end

View File

@ -3,6 +3,6 @@
FactoryBot.define do
factory :group_deploy_token do
group
association :deploy_token, factory: [:deploy_token, :group]
association :deploy_token, :group
end
end

View File

@ -11,7 +11,7 @@ FactoryBot.define do
end
trait :repository do
association :project, factory: [:project, :repository]
association :project, :repository
end
trait :none do

View File

@ -223,7 +223,7 @@ FactoryBot.define do
end
trait :with_namespace_settings do
namespace factory: [:namespace, :with_namespace_settings]
association :namespace, :with_namespace_settings
end
trait :with_avatar do
@ -626,7 +626,7 @@ FactoryBot.define do
end
trait :in_group do
namespace factory: [:group]
namespace factory: :group
end
trait :in_subgroup do

View File

@ -27,7 +27,7 @@ FactoryBot.define do
end
trait :create_branch_on_repository do
association :project, factory: [:project, :repository]
association :project, :repository
transient do
repository_branch_name { name }

View File

@ -11,13 +11,16 @@ exports[`Design management list item component when item appears in view after i
exports[`Design management list item component with notes renders item with multiple comments 1`] = `
<a
class="card design-list-item gl-cursor-pointer gl-mb-0 gl-text-default hover:gl-text-default js-design-list-item"
class="gl-text-default hover:gl-text-default"
>
<div
class="card-body gl-flex gl-items-center gl-justify-center gl-overflow-hidden gl-p-0 gl-relative gl-rounded-t-base"
<gl-card-stub
bodyclass="gl-p-0 gl-flex gl-w-full gl-bg-default gl-py-3 gl-px-4 gl-rounded-base"
class="design-list-item gl-mb-0 js-design-list-item"
footerclass=""
headerclass="gl-p-0 gl-flex gl-grow gl-items-center gl-justify-center gl-overflow-hidden gl-relative gl-rounded-t-base"
>
<gl-intersection-observer-stub
class="gl-grow"
class="gl-flex gl-grow gl-items-center gl-justify-center"
data-qa-filename="test"
data-testid="design-image"
>
@ -28,10 +31,6 @@ exports[`Design management list item component with notes renders item with mult
src="null"
/>
</gl-intersection-observer-stub>
</div>
<div
class="card-footer gl-bg-white gl-flex gl-px-4 gl-py-3 gl-w-full"
>
<div
class="gl-flex gl-flex-col str-truncated-100"
data-testid="design-file-name"
@ -56,34 +55,35 @@ exports[`Design management list item component with notes renders item with mult
</span>
</div>
<div
class="gl-flex gl-items-center gl-ml-auto gl-text-gray-500"
class="gl-flex gl-gap-2 gl-items-center gl-ml-auto gl-text-subtle"
>
<gl-icon-stub
class="gl-ml-2"
name="comments"
size="16"
variant="current"
/>
<span
aria-label="2 comments"
class="gl-ml-2"
>
2
</span>
</div>
</div>
</gl-card-stub>
</a>
`;
exports[`Design management list item component with notes renders item with single comment 1`] = `
<a
class="card design-list-item gl-cursor-pointer gl-mb-0 gl-text-default hover:gl-text-default js-design-list-item"
class="gl-text-default hover:gl-text-default"
>
<div
class="card-body gl-flex gl-items-center gl-justify-center gl-overflow-hidden gl-p-0 gl-relative gl-rounded-t-base"
<gl-card-stub
bodyclass="gl-p-0 gl-flex gl-w-full gl-bg-default gl-py-3 gl-px-4 gl-rounded-base"
class="design-list-item gl-mb-0 js-design-list-item"
footerclass=""
headerclass="gl-p-0 gl-flex gl-grow gl-items-center gl-justify-center gl-overflow-hidden gl-relative gl-rounded-t-base"
>
<gl-intersection-observer-stub
class="gl-grow"
class="gl-flex gl-grow gl-items-center gl-justify-center"
data-qa-filename="test"
data-testid="design-image"
>
@ -94,10 +94,6 @@ exports[`Design management list item component with notes renders item with sing
src="null"
/>
</gl-intersection-observer-stub>
</div>
<div
class="card-footer gl-bg-white gl-flex gl-px-4 gl-py-3 gl-w-full"
>
<div
class="gl-flex gl-flex-col str-truncated-100"
data-testid="design-file-name"
@ -122,21 +118,19 @@ exports[`Design management list item component with notes renders item with sing
</span>
</div>
<div
class="gl-flex gl-items-center gl-ml-auto gl-text-gray-500"
class="gl-flex gl-gap-2 gl-items-center gl-ml-auto gl-text-subtle"
>
<gl-icon-stub
class="gl-ml-2"
name="comments"
size="16"
variant="current"
/>
<span
aria-label="1 comment"
class="gl-ml-2"
>
1
</span>
</div>
</div>
</gl-card-stub>
</a>
`;

View File

@ -19,6 +19,7 @@ import uploadDesignMutation from '~/design_management/graphql/mutations/upload_d
import Index, { i18n } from '~/design_management/pages/index.vue';
import createRouter from '~/design_management/router';
import { DESIGNS_ROUTE_NAME } from '~/design_management/router/constants';
import CrudComponent from '~/vue_shared/components/crud_component.vue';
import * as utils from '~/design_management/utils/design_management_utils';
import {
EXISTING_DESIGN_DROP_MANY_FILES_MESSAGE,
@ -165,7 +166,13 @@ describe('Design management index page', () => {
},
mocks: { $apollo },
router,
stubs: { DesignDestroyer, ApolloMutation, VueDraggable, ...stubs },
stubs: {
CrudComponent,
DesignDestroyer,
ApolloMutation,
VueDraggable,
...stubs,
},
attachTo: document.body,
provide: {
projectPath: 'project-path',

View File

@ -19,6 +19,7 @@ RSpec.describe GitlabSchema.types['ImportSourceUser'], feature_category: :import
sourceUserIdentifier
sourceUsername
status
reassignmentError
]
expect(described_class).to have_graphql_fields(*expected_fields)

View File

@ -9,14 +9,20 @@ RSpec.describe Gitlab::BackgroundMigration::BackfillOrDropCiPipelineOnProjectId,
let(:project_id_for_merge_request) { 140 }
let(:project_id_for_unaffected_pipeline) { 1 }
let!(:pipeline_with_nothing) { table(:ci_pipelines, database: :ci).create!(id: 1, partition_id: 100) }
let!(:pipeline_with_builds) { table(:ci_pipelines, database: :ci).create!(id: 2, partition_id: 100) }
let!(:pipeline_with_nothing) do
table(:ci_pipelines, primary_key: :id, database: :ci).create!(id: 1, partition_id: 100)
end
let!(:pipeline_with_builds) do
table(:ci_pipelines, primary_key: :id, database: :ci).create!(id: 2, partition_id: 100)
end
let!(:pipeline_with_merge_request) do
table(:ci_pipelines, database: :ci).create!(id: 3, partition_id: 100, merge_request_id: 1)
table(:ci_pipelines, primary_key: :id, database: :ci).create!(id: 3, partition_id: 100, merge_request_id: 1)
end
let!(:untouched_pipeline) do
table(:ci_pipelines, database: :ci)
table(:ci_pipelines, primary_key: :id, database: :ci)
.create!(id: 4, partition_id: 100, project_id: project_id_for_unaffected_pipeline)
end
@ -72,7 +78,10 @@ RSpec.describe Gitlab::BackgroundMigration::BackfillOrDropCiPipelineOnProjectId,
end
context 'when associations are invalid as well' do
let!(:pipeline_with_bad_build) { table(:ci_pipelines, database: :ci).create!(id: 5, partition_id: 100) }
let!(:pipeline_with_bad_build) do
table(:ci_pipelines, primary_key: :id, database: :ci).create!(id: 5, partition_id: 100)
end
let!(:bad_build) { table(:p_ci_builds, database: :ci).create!(partition_id: 100, commit_id: 5) }
it 'deletes pipeline if associations do not have project_id' do

View File

@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Gitlab::BackgroundMigration::BackfillPartitionIdCiDailyBuildGroupReportResult, feature_category: :ci_scaling do
let(:ci_pipelines_table) { table(:ci_pipelines, database: :ci) }
let(:ci_pipelines_table) { table(:ci_pipelines, primary_key: :id, database: :ci) }
let(:ci_daily_build_group_report_results_table) { table(:ci_daily_build_group_report_results, database: :ci) }
let!(:pipeline_1) { ci_pipelines_table.create!(id: 1, partition_id: 100, project_id: 1) }
let!(:pipeline_2) { ci_pipelines_table.create!(id: 2, partition_id: 101, project_id: 1) }

View File

@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe Gitlab::BackgroundMigration::BackfillPartitionIdCiPipelineArtifact,
feature_category: :continuous_integration do
let(:ci_pipelines_table) { table(:ci_pipelines, database: :ci) }
let(:ci_pipelines_table) { table(:ci_pipelines, primary_key: :id, database: :ci) }
let(:ci_pipeline_artifacts_table) { table(:ci_pipeline_artifacts, database: :ci) }
let!(:pipeline_100) { ci_pipelines_table.create!(id: 1, partition_id: 100, project_id: 1) }
let!(:pipeline_101) { ci_pipelines_table.create!(id: 2, partition_id: 101, project_id: 1) }

View File

@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe Gitlab::BackgroundMigration::BackfillPartitionIdCiPipelineChatData,
feature_category: :continuous_integration do
let(:ci_pipelines_table) { table(:ci_pipelines, database: :ci) }
let(:ci_pipelines_table) { table(:ci_pipelines, primary_key: :id, database: :ci) }
let(:ci_pipeline_chat_data_table) { table(:ci_pipeline_chat_data, database: :ci) }
let!(:pipeline1) { ci_pipelines_table.create!(id: 1, partition_id: 100, project_id: 1) }
let!(:pipeline2) { ci_pipelines_table.create!(id: 2, partition_id: 101, project_id: 1) }

View File

@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Gitlab::BackgroundMigration::BackfillPartitionIdCiPipelineConfig, feature_category: :continuous_integration do
let(:ci_pipelines_table) { table(:ci_pipelines, database: :ci) }
let(:ci_pipelines_table) { table(:ci_pipelines, primary_key: :id, database: :ci) }
let(:ci_pipeline_config_table) { table(:ci_pipelines_config, database: :ci) }
let!(:pipeline_1) { ci_pipelines_table.create!(id: 1, partition_id: 100, project_id: 1) }
let!(:pipeline_2) { ci_pipelines_table.create!(id: 2, partition_id: 101, project_id: 1) }

View File

@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Gitlab::BackgroundMigration::BackfillPartitionIdCiPipelineMessage, feature_category: :ci_scaling do
let(:ci_pipelines_table) { table(:ci_pipelines, database: :ci) }
let(:ci_pipelines_table) { table(:ci_pipelines, primary_key: :id, database: :ci) }
let(:ci_pipeline_messages_table) { table(:ci_pipeline_messages, database: :ci) }
let!(:pipeline_1) { ci_pipelines_table.create!(id: 1, partition_id: 100, project_id: 1) }
let!(:pipeline_2) { ci_pipelines_table.create!(id: 2, partition_id: 101, project_id: 1) }

View File

@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Gitlab::BackgroundMigration::BackfillPartitionIdCiPipelineMetadata, feature_category: :continuous_integration do
let(:ci_pipelines_table) { table(:ci_pipelines, database: :ci) }
let(:ci_pipelines_table) { table(:ci_pipelines, primary_key: :id, database: :ci) }
let(:ci_pipeline_metadata_table) { table(:ci_pipeline_metadata, database: :ci) }
let!(:pipeline_100) { ci_pipelines_table.create!(id: 1, partition_id: 100, project_id: 1) }
let!(:pipeline_101) { ci_pipelines_table.create!(id: 2, partition_id: 101, project_id: 1) }

View File

@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Gitlab::BackgroundMigration::BackfillUpstreamPipelinePartitionIdOnPCiBuilds, feature_category: :continuous_integration do
let(:pipelines_table) { table(:ci_pipelines, database: :ci) { |t| t.primary_key = :id } }
let(:pipelines_table) { table(:ci_pipelines, primary_key: :id, database: :ci) }
let(:jobs_table) { partitioned_table(:p_ci_builds, database: :ci) }

View File

@ -6,7 +6,7 @@ RSpec.describe Gitlab::BackgroundMigration::QueueBackfillAutocancelPartitionIdOn
feature_category: :ci_scaling,
migration: :gitlab_ci,
schema: 20240704155541 do
let(:ci_pipelines_table) { table(:ci_pipelines, database: :ci) }
let(:ci_pipelines_table) { table(:ci_pipelines, primary_key: :id, database: :ci) }
let!(:pipeline_1) { ci_pipelines_table.create!(partition_id: 100) }
let!(:pipeline_3) { ci_pipelines_table.create!(partition_id: 101) }

View File

@ -13,7 +13,7 @@ RSpec.describe Gitlab::BackgroundMigration::UpdateCiPipelineArtifactsUnknownLock
let(:namespaces) { table(:namespaces) }
let(:projects) { table(:projects) }
let(:pipelines) { table(:ci_pipelines, database: :ci) }
let(:pipelines) { table(:ci_pipelines, primary_key: :id, database: :ci) }
let(:pipeline_artifacts) { table(:ci_pipeline_artifacts, database: :ci) }
let(:namespace) { namespaces.create!(name: 'name', path: 'path') }

View File

@ -1,44 +0,0 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'new tables with gitlab_pm schema', feature_category: :vulnerability_management do
# During the decomposition of the gitlab_sec DB, we will be dropping the gitlab_pm schema
# As part of this process, starting from milestone 17.3, it will be a mandatory requirement that
# all newly created tables are associated gitlab_sec.
# Any attempt to set the `gitlab_pm` schema for a new table will result in a failure of this spec.
# Specific tables can be exempted from this requirement, and such tables must be added to the `exempted_tables` list.
let!(:exempted_tables) do
[]
end
let!(:starting_from_milestone) { 17.3 }
it 'only allows exempted tables to have `gitlab_pm` as its schema, after milestone 17.3', :aggregate_failures do
tables_having_gitlab_pm_schema(starting_from_milestone: starting_from_milestone).each do |table_name|
expect(exempted_tables).to include(table_name), error_message(table_name)
end
end
private
def error_message(table_name)
<<~HEREDOC
The table `#{table_name}` has been added with `gitlab_pm` schema.
Starting from GitLab #{starting_from_milestone}, we expect new tables to use the `gitlab_sec` schema.
Please see issue https://gitlab.com/gitlab-org/gitlab/-/issues/472608 to understand why this change is being enforced.
HEREDOC
end
def tables_having_gitlab_pm_schema(starting_from_milestone:)
gitlab_pm_schema_tables.filter_map do |entry|
entry.table_name if entry.milestone_greater_than_or_equal_to?(starting_from_milestone)
end
end
def gitlab_pm_schema_tables
::Gitlab::Database::Dictionary.entries.find_all_by_schema('gitlab_pm')
end
end

View File

@ -0,0 +1,24 @@
# frozen_string_literal: true
require 'spec_helper'
require_migration!
RSpec.describe FinalizeDeletePackagesComposerCacheFileRecords, feature_category: :package_registry, migration_version: 20240816092254 do
describe '#up' do
it 'ensures the migration is completed for self-managed instances' do
QueueDeletePackagesComposerCacheFileRecords.new.up
migration = Gitlab::Database::BackgroundMigration::BatchedMigration.where(
job_class_name: 'DeletePackagesComposerCacheFileRecords',
table_name: 'packages_composer_cache_files'
).first
expect(migration.status).not_to eq(6) # finalized
migrate!
expect(migration.reload.status).to eq(6)
QueueDeletePackagesComposerCacheFileRecords.new.down
end
end
end

View File

@ -4,7 +4,10 @@ require 'spec_helper'
require_migration!
RSpec.describe BackfillNullProjectBuildRecords, migration: :gitlab_ci, feature_category: :database do
let!(:pipeline_with_project) { table(:ci_pipelines, database: :ci).create!(project_id: 10, partition_id: 100) }
let!(:pipeline_with_project) do
table(:ci_pipelines, primary_key: :id, database: :ci).create!(project_id: 10, partition_id: 100)
end
let(:builds_table) { table(:p_ci_builds, database: :ci) }
let!(:build_to_be_backfilled) do
builds_table.create!(name: "backfilled", commit_id: pipeline_with_project.id, partition_id: 100)

View File

@ -139,7 +139,9 @@ RSpec.describe Integrations::Asana, feature_category: :integrations do
let(:message) do
<<-EOF
minor bigfix, refactoring, fixed #123 and Closes #456 work on #789
ref https://app.asana.com/19292/956299/42 and closing https://app.asana.com/19292/956299/12
ref https://app.asana.com/19292/956299/42 and closing https://app.asana.com/19292/956299/12,
bug fixing and worked on #11, will be fixed
in #222
EOF
end
@ -169,6 +171,18 @@ RSpec.describe Integrations::Asana, feature_category: :integrations do
expect(Gitlab::HTTP_V2).to receive(:put)
.with("https://app.asana.com/api/1.0/tasks/12", completed_message).once.and_return(asana_task_5)
asana_task_5 = double(double(data: { gid: 11 }))
expect(Gitlab::HTTP_V2).to receive(:post)
.with("https://app.asana.com/api/1.0/tasks/11/stories", anything).once.and_return(asana_task_5)
expect(Gitlab::HTTP_V2).not_to receive(:put)
.with("https://app.asana.com/api/1.0/tasks/11", completed_message)
asana_task_6 = double(double(data: { gid: 222 }))
expect(Gitlab::HTTP_V2).to receive(:post)
.with("https://app.asana.com/api/1.0/tasks/222/stories", anything).once.and_return(asana_task_6)
expect(Gitlab::HTTP_V2).not_to receive(:put)
.with("https://app.asana.com/api/1.0/tasks/222", completed_message)
execute_integration
end
end

View File

@ -82,9 +82,6 @@ related_epic_links:
requirements_management_test_reports:
idx_test_reports_on_issue_id_created_at_and_id:
- index_requirements_management_test_reports_on_issue_id
sbom_component_versions:
index_sbom_component_versions_on_component_id_and_version:
- index_sbom_component_versions_on_component_id
search_namespace_index_assignments:
index_search_namespace_index_assignments_uniqueness_index_type:
- index_search_namespace_index_assignments_on_namespace_id

View File

@ -11,10 +11,11 @@ module MigrationsHelpers
Gitlab::Database.database_base_models[database_name] || Gitlab::Database.database_base_models[:main]
end
def table(name, database: nil)
def table(name, database: nil, primary_key: nil)
Class.new(active_record_base(database: database)) do
self.table_name = name
self.inheritance_column = :_type_disabled
self.primary_key = primary_key if primary_key.present?
def self.name
table_name.singularize.camelcase

View File

@ -159,7 +159,6 @@ mapping:
- 'spec/db/docs_spec.rb'
- 'spec/lib/gitlab/database/dictionary_spec.rb'
- 'spec/lib/gitlab/database/no_new_tables_with_gitlab_main_schema_spec.rb'
- 'spec/lib/gitlab/database/no_new_tables_with_gitlab_pm_schema_spec.rb'
- 'spec/lib/gitlab/database/sharding_key_spec.rb'
# See https://gitlab.com/gitlab-org/quality/engineering-productivity/master-broken-incidents/-/issues/1360