Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2024-07-25 15:11:46 +00:00
parent 115c175a7d
commit 0636ab91ee
115 changed files with 1081 additions and 461 deletions

View File

@ -4,7 +4,7 @@ include:
inputs:
cng_path: 'build/CNG-mirror'
- project: 'gitlab-org/quality/pipeline-common'
ref: '8.18.4'
ref: '8.18.5'
file: ci/base.gitlab-ci.yml
stages:

View File

@ -7,7 +7,7 @@ include:
inputs:
cng_path: 'charts/components/images'
- project: 'gitlab-org/quality/pipeline-common'
ref: '8.18.4'
ref: '8.18.5'
file: ci/base.gitlab-ci.yml
stages:

View File

@ -3904,7 +3904,6 @@ Layout/LineLength:
- 'spec/presenters/packages/helm/index_presenter_spec.rb'
- 'spec/presenters/packages/nuget/package_metadata_presenter_spec.rb'
- 'spec/presenters/packages/nuget/packages_metadata_presenter_spec.rb'
- 'spec/presenters/packages/nuget/search_results_presenter_spec.rb'
- 'spec/presenters/projects/security/configuration_presenter_spec.rb'
- 'spec/presenters/prometheus_alert_presenter_spec.rb'
- 'spec/presenters/snippet_blob_presenter_spec.rb'

View File

@ -172,10 +172,6 @@ export default {
v-model="currentPage"
:per-page="$options.PAGE_SIZE"
:total-items="activeAccessTokens.length"
:prev-text="__('Prev')"
:next-text="__('Next')"
:label-next-page="__('Go to next page')"
:label-prev-page="__('Go to previous page')"
align="center"
class="gl-mt-5"
/>

View File

@ -114,10 +114,6 @@ export default {
v-model="currentPage"
:per-page="$options.PAGE_SIZE"
:total-items="inactiveAccessTokens.length"
:prev-text="__('Prev')"
:next-text="__('Next')"
:label-next-page="__('Go to next page')"
:label-prev-page="__('Go to previous page')"
align="center"
class="gl-mt-5"
/>

View File

@ -51,10 +51,6 @@ export default {
:per-page="pagination.perPage"
:total-items="pagination.totalItems"
:link-gen="paginationLinkGenerator"
:prev-text="__('Prev')"
:next-text="__('Next')"
:label-next-page="__('Go to next page')"
:label-prev-page="__('Go to previous page')"
align="center"
class="gl-mt-3"
/>

View File

@ -30,10 +30,6 @@ export default {
),
delete: __('Delete deploy key'),
edit: __('Edit deploy key'),
pagination: {
next: __('Next'),
prev: __('Prev'),
},
modal: {
title: __('Are you sure?'),
body: __('Are you sure you want to delete this deploy key?'),
@ -289,8 +285,6 @@ export default {
v-model="page"
:per-page="$options.DEFAULT_PER_PAGE"
:total-items="totalItems"
:next-text="$options.i18n.pagination.next"
:prev-text="$options.i18n.pagination.prev"
align="center"
class="gl-mt-5"
/>

View File

@ -165,10 +165,6 @@ export default {
v-model="currentPage"
:per-page="$options.PAGE_SIZE"
:total-items="badges.length"
:prev-text="__('Prev')"
:next-text="__('Next')"
:label-next-page="__('Go to next page')"
:label-prev-page="__('Go to previous page')"
align="center"
class="gl-mt-5"
/>

View File

@ -34,12 +34,8 @@ export default {
<template>
<div class="gl-display-flex gl-flex-wrap gl-gap-2">
<runner-status-badge
:contacted-at="contactedAt"
:status="status"
class="gl-max-w-full gl-text-truncate"
/>
<runner-paused-badge v-if="paused" class="gl-max-w-full gl-text-truncate" />
<runner-status-badge :contacted-at="contactedAt" :status="status" />
<runner-paused-badge v-if="paused" />
<slot :runner="runner" name="runner-job-status-badge"></slot>
</div>
</template>

View File

@ -24,7 +24,7 @@ export default {
</script>
<template>
<div v-gl-tooltip="tooltip" class="gl-display-inline-block gl-text-secondary gl-mb-3 gl-mr-4">
<div v-gl-tooltip="tooltip" class="gl-inline-block gl-text-secondary gl-mb-3 gl-mr-4">
<gl-icon v-if="icon" :name="icon" :size="12" />
<!-- display tooltip as a label for screen readers and make it unavailable for copying -->
<span class="gl-sr-only gl-select-none">{{ tooltip }}</span>

View File

@ -45,10 +45,12 @@ export default {
<gl-badge
v-if="badge"
v-bind="$attrs"
class="gl-max-w-full gl-text-truncate gl-bg-transparent!"
class="!gl-bg-transparent"
variant="muted"
:class="badge.classes"
>
{{ badge.label }}
<span class="gl-truncate">
{{ badge.label }}
</span>
</gl-badge>
</template>

View File

@ -122,6 +122,8 @@ export default {
:icon="badge.icon"
v-bind="$attrs"
>
{{ badge.label }}
<span class="gl-truncate">
{{ badge.label }}
</span>
</gl-badge>
</template>

View File

@ -30,8 +30,8 @@ export default {
},
},
methods: {
onResize() {
const { scrollWidth, offsetWidth } = this.$el;
onResize({ target }) {
const { scrollWidth, offsetWidth } = target;
this.overflowing = scrollWidth > offsetWidth;
},
},
@ -41,10 +41,11 @@ export default {
<template>
<gl-badge
v-gl-tooltip="tooltip"
v-gl-resize-observer="onResize"
class="gl-display-inline-block gl-max-w-full gl-text-truncate"
class="gl-inline-block gl-overflow-hidden"
:variant="$options.RUNNER_TAG_BADGE_VARIANT"
>
{{ tag }}
<span v-gl-resize-observer="onResize" class="gl-truncate">
{{ tag }}
</span>
</gl-badge>
</template>

View File

@ -16,6 +16,6 @@ export default {
</script>
<template>
<span v-if="tagList && tagList.length">
<runner-tag v-for="tag in tagList" :key="tag" class="gl-display-inline gl-mr-1" :tag="tag" />
<runner-tag v-for="tag in tagList" :key="tag" class="gl-mr-1" :tag="tag" />
</span>
</template>

View File

@ -49,10 +49,6 @@ export default {
uploadLabel: __('Upload File'),
uploadingLabel: __('Uploading...'),
noFilesMessage: __('There are no secure files yet.'),
pagination: {
next: __('Next'),
prev: __('Prev'),
},
uploadErrorMessages: {
duplicate: __('A file with this name already exists.'),
tooLarge: __('File too large. Secure Files must be less than %{limit} MB.'),
@ -281,8 +277,6 @@ export default {
v-model="page"
:per-page="$options.DEFAULT_PER_PAGE"
:total-items="totalItems"
:next-text="$options.i18n.pagination.next"
:prev-text="$options.i18n.pagination.prev"
align="center"
class="gl-mt-5"
/>

View File

@ -334,8 +334,6 @@ export default {
v-model="currentPage"
:per-page="clustersPerPage"
:total-items="totalClusters"
:prev-text="__('Prev')"
:next-text="__('Next')"
align="center"
/>
</section>

View File

@ -1,6 +1,13 @@
import applyGitLabUIConfig from '@gitlab/ui/dist/config';
import { __, s__, n__ } from '~/locale';
import { NEXT, PREV } from '~/vue_shared/components/pagination/constants';
import {
PREV,
NEXT,
LABEL_FIRST_PAGE,
LABEL_PREV_PAGE,
LABEL_NEXT_PAGE,
LABEL_LAST_PAGE,
} from '~/vue_shared/components/pagination/constants';
applyGitLabUIConfig({
translations: {
@ -12,7 +19,15 @@ applyGitLabUIConfig({
'GlKeysetPagination.prevText': PREV,
'GlKeysetPagination.navigationLabel': s__('Pagination|Pagination'),
'GlKeysetPagination.nextText': NEXT,
'GlPagination.labelFirstPage': LABEL_FIRST_PAGE,
'GlPagination.labelLastPage': LABEL_LAST_PAGE,
'GlPagination.labelNextPage': LABEL_NEXT_PAGE,
'GlPagination.labelPage': s__('Pagination|Go to page %{page}'),
'GlPagination.labelPrevPage': LABEL_PREV_PAGE,
'GlPagination.nextText': NEXT,
'GlPagination.prevText': PREV,
'GlCollapsibleListbox.srOnlyResultsLabel': (count) => n__('%d result', '%d results', count),
},
});

View File

@ -1,7 +1,7 @@
<script>
import { GlIcon, GlLoadingIcon, GlPagination } from '@gitlab/ui';
import { createAlert } from '~/alert';
import { s__, __ } from '~/locale';
import { s__ } from '~/locale';
import { captureException } from '~/sentry/sentry_browser_wrapper';
import pageInfoQuery from '~/graphql_shared/client/page_info.query.graphql';
import NavigationTabs from '~/vue_shared/components/navigation_tabs.vue';
@ -89,10 +89,6 @@ export default {
},
i18n: {
loading: s__('DeployKeys|Loading deploy keys'),
prevPage: __('Go to previous page'),
nextPage: __('Go to next page'),
next: __('Next'),
prev: __('Prev'),
},
computed: {
tabs() {
@ -204,10 +200,6 @@ export default {
:total-items="pageInfo.total"
:per-page="pageInfo.perPage"
:value="currentPage"
:next="$options.i18n.next"
:prev="$options.i18n.prev"
:label-previous-page="$options.i18n.prevPage"
:label-next-page="$options.i18n.nextPage"
@next="moveNext()"
@previous="movePrevious()"
@input="moveToPage"

View File

@ -85,10 +85,6 @@ export default {
cleanUpEnvsButtonLabel: s__('Environments|Clean up environments'),
active: __('Active'),
stopped: __('Stopped'),
prevPage: __('Go to previous page'),
nextPage: __('Go to next page'),
next: __('Next'),
prev: __('Prev'),
searchPlaceholder: s__('Environments|Search by environment name'),
},
modalId: 'enable-review-app-info',
@ -339,10 +335,6 @@ export default {
:total-items="totalItems"
:per-page="itemsPerPage"
:value="page"
:next="$options.i18n.next"
:prev="$options.i18n.prev"
:label-previous-page="$options.prevPage"
:label-next-page="$options.nextPage"
@next="movePage('next')"
@previous="movePage('previous')"
@input="moveToPage"

View File

@ -46,10 +46,6 @@ export default {
:per-page="pagination.perPage"
:total-items="pagination.totalItems"
:link-gen="paginationLinkGenerator"
:prev-text="__('Prev')"
:next-text="__('Next')"
:label-next-page="__('Go to next page')"
:label-prev-page="__('Go to previous page')"
align="center"
/>
</template>

View File

@ -8,14 +8,9 @@ import {
GlEmptyState,
} from '@gitlab/ui';
import { DEFAULT_PER_PAGE } from '~/api';
import { NEXT, PREV } from '~/vue_shared/components/pagination/constants';
import { isCurrentUser } from '~/lib/utils/common_utils';
export default {
i18n: {
prev: PREV,
next: NEXT,
},
components: {
GlAvatarLabeled,
GlAvatarLink,
@ -112,8 +107,6 @@ export default {
:value="page"
:total-items="totalItems"
:per-page="perPage"
:prev-text="$options.i18n.prev"
:next-text="$options.i18n.next"
@input="$emit('pagination-input', $event)"
/>
</div>

View File

@ -79,7 +79,7 @@ export default {
<template>
<div class="well-segment">
<gl-icon :name="refIcon" :size="14" class="gl-ml-2 gl-mr-3" />
<gl-icon :name="refIcon" class="gl-ml-2 gl-mr-3" />
<span data-testid="title" class="gl-mr-2">{{ namespace }}</span>
<gl-badge
v-for="ref in tippingRefs"

View File

@ -1,13 +1,5 @@
<script>
import { GlPagination } from '@gitlab/ui';
import {
PREV,
NEXT,
LABEL_FIRST_PAGE,
LABEL_PREV_PAGE,
LABEL_NEXT_PAGE,
LABEL_LAST_PAGE,
} from '~/vue_shared/components/pagination/constants';
export default {
components: {
@ -53,12 +45,6 @@ export default {
return this.pageInfo.nextPage || this.pageInfo.previousPage;
},
},
prevText: PREV,
nextText: NEXT,
labelFirstPage: LABEL_FIRST_PAGE,
labelPrevPage: LABEL_PREV_PAGE,
labelNextPage: LABEL_NEXT_PAGE,
labelLastPage: LABEL_LAST_PAGE,
};
</script>
<template>
@ -71,13 +57,7 @@ export default {
:per-page="pageInfo.perPage"
:total-items="pageInfo.total"
:prev-page="pageInfo.previousPage"
:prev-text="$options.prevText"
:next-page="pageInfo.nextPage"
:next-text="$options.nextText"
:label-first-page="$options.labelFirstPage"
:label-prev-page="$options.labelPrevPage"
:label-next-page="$options.labelNextPage"
:label-last-page="$options.labelLastPage"
@input="change"
/>
</template>

View File

@ -1,13 +1,5 @@
<script>
import { GlPagination } from '@gitlab/ui';
import {
PREV,
NEXT,
LABEL_FIRST_PAGE,
LABEL_PREV_PAGE,
LABEL_NEXT_PAGE,
LABEL_LAST_PAGE,
} from '~/vue_shared/components/pagination/constants';
export default {
components: {
@ -28,12 +20,6 @@ export default {
const baseProps = {
...this.$attrs,
value: this.pageInfo.page,
prevText: PREV,
nextText: NEXT,
labelFirstPage: LABEL_FIRST_PAGE,
labelPrevPage: LABEL_PREV_PAGE,
labelNextPage: LABEL_NEXT_PAGE,
labelLastPage: LABEL_LAST_PAGE,
};
if (this.pageInfo.total) {

View File

@ -107,7 +107,7 @@ export default {
class="gl-py-5 gl-pl-8"
:class="{ 'gl-border-b': borderBottom(idx) }"
>
<div class="-gl-mt-1 gl-pl-4 gl-pb-2 gl-font-bold">
<div class="-gl-mt-1 gl-pb-2 gl-pl-4 gl-font-bold">
{{ easyButton.description }}
<gl-accordion :header-level="3" class="gl-pt-3">
<gl-accordion-item
@ -131,17 +131,17 @@ export default {
</p>
<template v-if="registrationToken">
<h5 class="gl-mb-3">{{ $options.i18n.runnerRegistrationToken }}</h5>
<div class="gl-display-flex">
<pre class="gl-bg-gray gl-flex-grow-1 gl-whitespace-pre-line">{{ registrationToken }}</pre>
<div class="gl-flex">
<pre class="gl-bg-gray gl-grow gl-whitespace-pre-line">{{ registrationToken }}</pre>
<modal-copy-button
:title="$options.i18n.copyInstructions"
:text="registrationToken"
css-classes="gl-align-self-start gl-ml-2 gl-mt-2"
css-classes="gl-self-start gl-ml-2 gl-mt-2"
category="tertiary"
/>
</div>
</template>
<footer class="gl-display-flex gl-justify-content-end gl-pt-3 gl-gap-3">
<footer class="gl-flex gl-justify-end gl-gap-3 gl-pt-3">
<gl-button @click="onClose()">{{ $options.i18n.close }}</gl-button>
<gl-button variant="confirm" @click="onOk()">
{{ $options.i18n.deployRunnerInAws }}

View File

@ -109,7 +109,7 @@ export default {
</h5>
<gl-collapsible-listbox v-model="selectedArchName" class="gl-mb-3" :items="listboxItems" />
<div class="sm:gl-flex gl-align-items-center gl-mb-3">
<div class="gl-mb-3 gl-items-center sm:gl-flex">
<h5>{{ $options.i18n.downloadInstallBinary }}</h5>
<gl-button
v-if="binaryUrl"
@ -124,38 +124,34 @@ export default {
</div>
<template v-if="instructions">
<div class="gl-display-flex">
<pre
class="gl-bg-gray gl-flex-grow-1 gl-whitespace-pre-line"
data-testid="binary-instructions"
>{{ instructions.installInstructions }}</pre
>
<div class="gl-flex">
<pre class="gl-bg-gray gl-grow gl-whitespace-pre-line" data-testid="binary-instructions">{{
instructions.installInstructions
}}</pre>
<modal-copy-button
:title="$options.i18n.copyInstructions"
:text="instructions.installInstructions"
:modal-id="$options.modalId"
css-classes="gl-align-self-start gl-ml-2 gl-mt-2"
css-classes="gl-self-start gl-ml-2 gl-mt-2"
category="tertiary"
/>
</div>
<h5 class="gl-mb-3">{{ $options.i18n.registerRunnerCommand }}</h5>
<div class="gl-display-flex">
<pre
class="gl-bg-gray gl-flex-grow-1 gl-whitespace-pre-line"
data-testid="register-command"
>{{ registerInstructionsWithToken }}</pre
>
<div class="gl-flex">
<pre class="gl-bg-gray gl-grow gl-whitespace-pre-line" data-testid="register-command">{{
registerInstructionsWithToken
}}</pre>
<modal-copy-button
:title="$options.i18n.copyInstructions"
:text="registerInstructionsWithToken"
:modal-id="$options.modalId"
css-classes="gl-align-self-start gl-ml-2 gl-mt-2"
css-classes="gl-self-start gl-ml-2 gl-mt-2"
category="tertiary"
/>
</div>
</template>
<footer class="gl-display-flex gl-justify-content-end gl-pt-3">
<footer class="gl-flex gl-justify-end gl-pt-3">
<gl-button @click="onClose()">{{ __('Close') }}</gl-button>
</footer>
</div>

View File

@ -29,7 +29,7 @@ export default {
<gl-icon name="external-link" />
{{ $options.I18N_VIEW_INSTRUCTIONS }}
</gl-button>
<footer class="gl-display-flex gl-justify-content-end gl-pt-3">
<footer class="gl-flex gl-justify-end gl-pt-3">
<gl-button @click="onClose()">{{ __('Close') }}</gl-button>
</footer>
</div>

View File

@ -29,7 +29,7 @@ export default {
<gl-icon name="external-link" />
{{ $options.I18N_VIEW_INSTRUCTIONS }}
</gl-button>
<footer class="gl-display-flex gl-justify-content-end gl-pt-3">
<footer class="gl-flex gl-justify-end gl-pt-3">
<gl-button @click="onClose()">{{ __('Close') }}</gl-button>
</footer>
</div>

View File

@ -1,7 +1,7 @@
<script>
import { GlButton, GlDisclosureDropdown, GlLabel } from '@gitlab/ui';
import fuzzaldrinPlus from 'fuzzaldrin-plus';
import { difference } from 'lodash';
import { difference, unionBy } from 'lodash';
import { WORKSPACE_GROUP, WORKSPACE_PROJECT } from '~/issues/constants';
import { __, n__ } from '~/locale';
import WorkItemSidebarDropdownWidget from '~/work_items/components/shared/work_item_sidebar_dropdown_widget.vue';
@ -16,6 +16,14 @@ import updateNewWorkItemMutation from '../graphql/update_new_work_item.mutation.
import { i18n, I18N_WORK_ITEM_ERROR_FETCHING_LABELS, TRACKING_CATEGORY_SHOW } from '../constants';
import { isLabelsWidget, newWorkItemId, newWorkItemFullPath } from '../utils';
function formatLabelForListbox(label) {
return {
text: label.title || label.text,
value: label.id || label.value,
color: label.color,
};
}
export default {
components: {
DropdownContentsCreateView,
@ -63,6 +71,8 @@ export default {
createdLabelId: undefined,
removeLabelIds: [],
addLabelIds: [],
labelsCache: [],
labelsToShowAtTopOfTheListbox: [],
};
},
computed: {
@ -103,20 +113,15 @@ export default {
return this.searchLabels;
},
labelsList() {
const visibleLabels =
this.visibleLabels?.map(({ id, title, color }) => ({
value: id,
text: title,
color,
})) || [];
const visibleLabels = this.visibleLabels?.map(formatLabelForListbox) || [];
if (this.searchTerm || this.itemValues.length === 0) {
return visibleLabels;
}
const selectedLabels = visibleLabels.filter(({ value }) => this.itemValues.includes(value));
const selectedLabels = this.labelsToShowAtTopOfTheListbox.map(formatLabelForListbox) || [];
const unselectedLabels = visibleLabels.filter(
({ value }) => !this.itemValues.includes(value),
({ value }) => !this.labelsToShowAtTopOfTheListbox.find((l) => l.id === value),
);
return [
@ -146,6 +151,22 @@ export default {
return this.isGroup ? WORKSPACE_GROUP : WORKSPACE_PROJECT;
},
},
watch: {
searchTerm(newVal, oldVal) {
if (newVal === '' && oldVal !== '') {
const selectedIds = [...this.itemValues, ...this.addLabelIds].filter(
(x) => !this.removeLabelIds.includes(x),
);
this.labelsToShowAtTopOfTheListbox = this.labelsCache.filter(({ id }) =>
selectedIds.includes(id),
);
}
},
localLabels(newVal) {
this.labelsToShowAtTopOfTheListbox = newVal;
},
},
apollo: {
workItem: {
query: workItemByIidQuery,
@ -158,6 +179,11 @@ export default {
update(data) {
return data.workspace?.workItem || {};
},
result({ data }) {
const labels =
data?.workspace?.workItem?.widgets?.find(isLabelsWidget)?.labels?.nodes || [];
this.labelsCache = unionBy(this.labelsCache, labels, 'id');
},
skip() {
return !this.workItemIid;
},
@ -181,6 +207,10 @@ export default {
update(data) {
return data.workspace?.labels?.nodes;
},
result({ data }) {
const labels = data?.workspace?.labels?.nodes || [];
this.labelsCache = unionBy(this.labelsCache, labels, 'id');
},
error() {
this.$emit('error', I18N_WORK_ITEM_ERROR_FETCHING_LABELS);
},

View File

@ -30,14 +30,14 @@
right: $gl-padding;
max-width: 300px;
width: auto;
background: $white;
border: 1px solid $gray-100;
box-shadow: 0 1px 2px 0 rgba($black, 0.1);
background: var(--gl-background-color-default);
border: 1px solid var(--gl-border-color-default);
box-shadow: 0 1px 2px 0 var(--gl-shadow-color-default);
border-radius: $gl-border-radius-base;
z-index: 999;
&.preview {
position: static;
.gl-broadcast-message.banner {
color: $gl-text-color;
}
}

View File

@ -247,7 +247,7 @@
min-height: $height;
background: var(--white, $white);
border: 1px solid var(--gl-border-color-default);
color: var(--gl-text-color, $gl-text-color);
color: var(--gl-text-color-default);
padding: $grid-size;
}

View File

@ -9,7 +9,7 @@
&:hover {
background-color: var(--gray-50, $gray-50);
border: 1px solid $dropdown-toggle-active-border-color;
color: var(--gl-text-color, $gl-text-color);
color: var(--gl-text-color-default);
}
}

View File

@ -61,7 +61,7 @@
.header-content {
a {
color: var(--gl-text-color, $gl-text-color);
color: var(--gl-text-color-heading);
&:hover {
color: var(--blue-600, $blue-600);

View File

@ -29,7 +29,7 @@
&.ci-disabled,
&.ci-scheduled,
&.ci-manual {
color: var(--gl-text-color, $gl-text-color);
color: var(--gl-text-color-default);
border-color: currentColor;
&:not(span):hover {

View File

@ -19,7 +19,7 @@
.commit-title {
margin: 0;
color: var(--gl-text-color);
color: var(--gl-text-color-default);
}
}

View File

@ -56,7 +56,7 @@
color: var(--gray-500, $gl-text-color-secondary);
a {
color: var(--gl-text-color, $gl-text-color);
color: var(--gl-text-color-default);
}
// stylelint-disable-next-line gitlab/no-gl-class

View File

@ -172,6 +172,6 @@
background-color: var(--gray-10, $gray-10);
text-align: right;
padding: $gl-padding-top $gl-padding;
color: var(--gl-text-color, $gl-text-color);
color: var(--gl-text-color-default);
}
}

View File

@ -495,7 +495,7 @@
}
.mr-state-widget {
color: var(--gl-text-color, $gl-text-color);
color: var(--gl-text-color-default);
.commit-message-edit {
border-radius: $gl-border-radius-base;
@ -547,7 +547,7 @@
}
.ci-widget {
color: var(--gl-text-color, $gl-text-color);
color: var(--gl-text-color-default);
display: flex;
align-items: center;
justify-content: space-between;
@ -726,11 +726,11 @@
}
.stop-env-container {
color: var(--gl-text-color, $gl-text-color);
color: var(--gl-text-color-default);
float: right;
a {
color: var(--gl-text-color, $gl-text-color);
color: var(--gl-text-color-default);
}
}
}
@ -810,7 +810,7 @@
}
.mr-version-controls {
color: var(--gl-text-color, $gl-text-color);
color: var(--gl-text-color-default);
.mr-version-menus-container {
display: flex;
@ -854,7 +854,7 @@
}
.dropdown-title {
color: var(--gl-text-color, $gl-text-color);
color: var(--gl-text-color-strong);
}
}

View File

@ -28,10 +28,6 @@
.build-state {
padding: 20px 2px;
.build-name {
font-weight: $gl-font-weight-normal;
}
.stage {
color: var(--gray-500, $gray-500);
font-weight: $gl-font-weight-normal;
@ -57,21 +53,6 @@
margin-top: $gl-padding;
}
.build-name {
width: 196px;
a {
font-weight: $gl-font-weight-bold;
color: var(--gl-text-color, $gl-text-color);
text-decoration: none;
&:focus,
&:hover {
text-decoration: underline;
}
}
}
.build-actions {
width: 70px;
text-align: right;

View File

@ -130,7 +130,7 @@
}
.project-stat-value {
color: var(--gl-text-color, $gl-text-color);
color: var(--gl-text-color-default);
}
.icon {
@ -153,7 +153,7 @@
margin-bottom: 7px;
h5 {
color: var(--gl-text-color, $gl-text-color);
color: var(--gl-text-color-heading);
}
}

View File

@ -115,7 +115,7 @@
margin: 0;
a {
color: var(--gl-text-color, $gl-text-color);
color: var(--gl-text-color-default);
}
.dropdown-menu {
@ -264,7 +264,7 @@
.project-row {
.description p {
margin-bottom: 0;
color: var(--gl-text-color-secondary, $gl-text-color-secondary);
color: var(--gl-text-color-subtle);
@include str-truncated(100%);
}
}

View File

@ -164,7 +164,7 @@ $language-filter-max-height: 20rem;
.dropdown-header {
// Necessary because deprecatedJQueryDropdown doesn't support a second style of headers
font-weight: $gl-font-weight-bold;
color: var(--gl-text-color, $gl-text-color);
color: var(--gl-text-color-strong);
font-size: $gl-font-size;
line-height: 16px;
}
@ -199,7 +199,7 @@ $language-filter-max-height: 20rem;
}
.search-input {
color: var(--gl-text-color, $gl-text-color);
color: var(--gl-text-color-default);
transition: color ease-in-out $default-transition-duration;
}

View File

@ -73,7 +73,7 @@
.todo-body {
p {
display: inline;
color: var(--gl-text-color, $gl-text-color);
color: var(--gl-text-color-default);
}
pre.code.highlight {
@ -86,7 +86,7 @@
border-radius: $gl-border-radius-base;
display: inline-flex;
background: var(--gray-50, $gray-50);
color: var(--gl-text-color, $gl-text-color);
color: var(--gl-text-color-default);
}
// stylelint-disable-next-line gitlab/no-gl-class

View File

@ -161,7 +161,7 @@
i,
a {
color: var(--gl-text-color, $gl-text-color);
color: var(--gl-text-color-default);
}
img {

View File

@ -10,8 +10,6 @@
--dark-icon-color-orange-1: #665349;
--dark-icon-color-orange-2: #b37a5d;
--gl-text-color: #{$gray-900};
--svg-status-bg: #{$white};
}

View File

@ -15,5 +15,6 @@
data: { id: @id,
expire_date: @expire_date,
dismissal_path: @dismissal_path,
cookie_key: @cookie_key } },
cookie_key: @cookie_key,
testid: @button_testid } },
icon_classes: 'gl-text-white')

View File

@ -9,7 +9,10 @@ module Pajamas
# @param [String] expire_date
# @param [String] cookie_key
# @param [String] dismissal_path
def initialize(message:, id:, theme:, dismissable:, expire_date:, cookie_key:, dismissal_path: nil)
# @param [String] button_testid
def initialize(
message:, id:, theme:, dismissable:, expire_date:, cookie_key:, dismissal_path: nil,
button_testid: nil)
@message = message
@id = id
@theme = theme
@ -17,6 +20,7 @@ module Pajamas
@expire_date = expire_date
@cookie_key = cookie_key
@dismissal_path = dismissal_path
@button_testid = button_testid
end
delegate :sprite_icon, to: :helpers

View File

@ -190,11 +190,12 @@ class GraphqlController < ApplicationController
disable_reference = request.headers[DISABLE_SQL_QUERY_LIMIT_HEADER]
return unless disable_reference
disable_issue, new_threshold = disable_reference.split(';')
if new_threshold
Gitlab::QueryLimiting.disable!(disable_issue, new_threshold: new_threshold&.to_i)
first, second = disable_reference.split(',')
if first.match?(/^\d+$/)
Gitlab::QueryLimiting.disable!(second, new_threshold: first&.to_i)
else
Gitlab::QueryLimiting.disable!(disable_issue)
Gitlab::QueryLimiting.disable!(first)
end
end

View File

@ -7,7 +7,8 @@ class DeployToken < ApplicationRecord
include Gitlab::Utils::StrongMemoize
AVAILABLE_SCOPES = %i[read_repository read_registry write_registry
read_package_registry write_package_registry].freeze
read_package_registry write_package_registry
read_virtual_registry].freeze
GITLAB_DEPLOY_TOKEN_NAME = 'gitlab-deploy-token'
DEPLOY_TOKEN_PREFIX = 'gldt-'

View File

@ -0,0 +1,52 @@
# frozen_string_literal: true
module VirtualRegistries
module Packages
module Maven
class CachedResponse < ApplicationRecord
include FileStoreMounter
belongs_to :group
belongs_to :upstream, class_name: 'VirtualRegistries::Packages::Maven::Upstream', inverse_of: :cached_responses
validates :group, top_level_group: true, presence: true
validates :relative_path,
:object_storage_key,
:content_type,
:downloads_count,
:size,
presence: true
validates :relative_path,
:object_storage_key,
:upstream_etag,
:content_type,
length: { maximum: 255 }
validates :downloads_count, numericality: { greater_than: 0, only_integer: true }
validates :relative_path, uniqueness: { scope: :upstream_id }
validates :file, presence: true
mount_file_store_uploader ::VirtualRegistries::CachedResponseUploader
before_validation :set_object_storage_key,
if: -> { object_storage_key.blank? && relative_path && upstream && upstream.registry }
attr_readonly :object_storage_key
private
def set_object_storage_key
self.object_storage_key = Gitlab::HashedPath.new(
'virtual_registries',
'packages',
'maven',
upstream.registry.id,
'upstream',
upstream.id,
'cached_response',
OpenSSL::Digest::SHA256.hexdigest(relative_path),
root_hash: upstream.registry.id
).to_s
end
end
end
end
end

View File

@ -9,6 +9,9 @@ module VirtualRegistries
class_name: 'VirtualRegistries::Packages::Maven::RegistryUpstream',
inverse_of: :upstream
has_one :registry, class_name: 'VirtualRegistries::Packages::Maven::Registry', through: :registry_upstream
has_many :cached_responses,
class_name: 'VirtualRegistries::Packages::Maven::CachedResponse',
inverse_of: :upstream
attr_encrypted :credentials,
mode: :per_attribute_iv,

View File

@ -0,0 +1,17 @@
# frozen_string_literal: true
module VirtualRegistries
module Packages
module Policies
class Group
attr_reader :group
delegate_missing_to :group
def initialize(group)
@group = group.root_ancestor
end
end
end
end
end

View File

@ -0,0 +1,41 @@
# frozen_string_literal: true
module VirtualRegistries
module Packages
module Policies
class GroupPolicy < ::BasePolicy
include CrudPolicyHelpers
delegate(:group) { @subject.group }
condition(:deploy_token_user, scope: :user, score: 0) { @user.is_a?(DeployToken) }
condition(:deploy_token_can_read_virtual_registry, score: 10) do
@user.read_virtual_registry && @user.has_access_to_group?(@subject.group)
end
rule { anonymous }.policy do
prevent(*create_read_update_admin_destroy(:virtual_registry))
end
rule { can?(:read_group) }.policy do
enable :read_virtual_registry
end
rule { group.maintainer }.policy do
enable :create_virtual_registry
enable :update_virtual_registry
enable :destroy_virtual_registry
end
rule { deploy_token_user & deploy_token_can_read_virtual_registry }.policy do
enable :read_virtual_registry
end
rule { deploy_token_user & ~deploy_token_can_read_virtual_registry }.policy do
prevent :read_virtual_registry
end
end
end
end
end

View File

@ -10,19 +10,19 @@ module Packages
def initialize(search)
@search = search
@package_versions = {}
end
def data
@search.results.group_by(&:name).map do |package_name, packages|
latest_version = latest_version(packages)
latest_package = packages.find { |pkg| pkg.version == latest_version }
return [] if total_count == 0
grouped_packages.map do |package_name, packages|
package_versions, latest_version, latest_package = extract_package_details(packages)
{
type: 'Package',
name: package_name,
version: latest_version,
versions: build_package_versions(packages),
versions: package_versions,
total_downloads: 0,
verified: true,
tags: tags_for(latest_package),
@ -34,19 +34,33 @@ module Packages
private
def build_package_versions(packages)
packages.map do |pkg|
{
def grouped_packages
@search
.results
.preload_nuget_metadatum
.preload_tags
.group_by(&:name)
end
def extract_package_details(packages)
package_versions = []
latest_version = nil
latest_package = nil
packages.each do |pkg|
package_versions << {
json_url: json_url_for(pkg),
downloads: 0,
version: pkg.version
}
end
end
def latest_version(packages)
versions = packages.filter_map(&:version)
sort_versions(versions).last
if sort_versions([latest_version, pkg.version]).last == pkg.version
latest_version = pkg.version
latest_package = pkg
end
end
[package_versions, latest_version, latest_package]
end
end
end

View File

@ -0,0 +1,27 @@
# frozen_string_literal: true
module VirtualRegistries
class CachedResponseUploader < GitlabUploader
include ObjectStorage::Concern
storage_location :dependency_proxy
alias_method :upload, :model
before :cache, :set_content_type
def store_dir
dynamic_segment
end
private
def set_content_type(file)
file.content_type = model.content_type
end
def dynamic_segment
model.object_storage_key
end
end
end

View File

@ -34,7 +34,7 @@
.info-well
.well-segment
.icon-container.commit-icon
= custom_icon("icon_commit")
= sprite_icon('commit')
%span.cgray= n_('parent', 'parents', @commit.parents.count)
- @commit.parents.each do |parent|
= link_to parent.short_id, project_commit_path(@project, parent), class: "commit-sha"
@ -42,7 +42,7 @@
.well-segment.merge-request-info
.icon-container
= custom_icon('mr_bold')
= sprite_icon('merge-request')
%span.commit-info.merge-requests{ 'data-project-commit-path' => merge_requests_project_commit_path(@project, @commit.id, format: :json) }
= gl_loading_icon(inline: true, css_class: 'gl-align-middle')

View File

@ -1,51 +1,11 @@
- icon_name = 'bullhorn'
- dismissable = message.dismissable?
- preview = local_assigns.fetch(:preview, false)
- dismissal_data = current_user ? { dismissal_path: broadcast_message_dismissals_path } : {}
- content = render_broadcast_message(message)
- expire_date = message.ends_at.iso8601
- cookie_key = Users::BroadcastMessageDismissal.get_cookie_key(message.id)
- dismissal_path = current_user ? broadcast_message_dismissals_path : nil
- data = { id: message.id,
expire_date: message.ends_at.iso8601,
cookie_key: Users::BroadcastMessageDismissal.get_cookie_key(message.id),
testid: 'close-button' }.merge(dismissal_data)
- if message.notification?
.broadcast-notification-message{ data: { testid: 'broadcast-notification-container' } }
= render Pajamas::BroadcastBannerComponent.new(message: content, id: message.id, theme: nil, dismissable: true, expire_date: expire_date, cookie_key: cookie_key, dismissal_path: dismissal_path, button_testid: 'close-button')
- unless message.notification?
.gl-broadcast-message.broadcast-banner-message.banner{ role: "alert",
class: "js-broadcast-notification-#{message.id} #{message.theme}", data: { testid: 'banner-broadcast-message' } }
.gl-broadcast-message-content
.gl-broadcast-message-icon
= sprite_icon(icon_name)
.gl-broadcast-message-text.js-broadcast-message-preview
- if message.message.present?
%h2.gl-sr-only
= s_("Admin message")
= render_broadcast_message(message)
- else
= yield
- if dismissable && !preview
= render Pajamas::ButtonComponent.new(category: :tertiary,
icon: 'close',
size: :small,
button_options: { class: 'gl-close-btn-color-inherit gl-broadcast-message-dismiss js-dismiss-current-broadcast-notification',
'aria-label': _('Close'),
data: data },
icon_classes: 'gl-text-white')
- else
- notification_class = "js-broadcast-notification-#{message.id}"
- notification_class << ' preview' if preview
.gl-broadcast-message.broadcast-notification-message.gl-mt-3{ role: "alert", class: notification_class, data: { testid: 'broadcast-notification-container' } }
.gl-broadcast-message-content
.gl-broadcast-message-icon
= sprite_icon(icon_name, css_class: 'vertical-align-text-top')
- if message.message.present?
%h2.gl-sr-only
= s_("Admin message")
= render_broadcast_message(message)
- else
= yield
- if !preview
= render Pajamas::ButtonComponent.new(category: :tertiary,
icon: 'close',
size: :small,
button_options: { class: 'js-dismiss-current-broadcast-notification',
'aria-label': _('Close'),
data: data })
= render Pajamas::BroadcastBannerComponent.new(message: content, id: message.id, theme: message.theme, dismissable: message.dismissable?, expire_date: expire_date, cookie_key: cookie_key, dismissal_path: dismissal_path)

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" viewBox="0 0 16 16"><path d="m5 5.563v4.875c1.024.4 1.75 1.397 1.75 2.563 0 1.519-1.231 2.75-2.75 2.75-1.519 0-2.75-1.231-2.75-2.75 0-1.166.726-2.162 1.75-2.563v-4.875c-1.024-.4-1.75-1.397-1.75-2.563 0-1.519 1.231-2.75 2.75-2.75 1.519 0 2.75 1.231 2.75 2.75 0 1.166-.726 2.162-1.75 2.563m-1 8.687c.69 0 1.25-.56 1.25-1.25 0-.69-.56-1.25-1.25-1.25-.69 0-1.25.56-1.25 1.25 0 .69.56 1.25 1.25 1.25m0-10c.69 0 1.25-.56 1.25-1.25 0-.69-.56-1.25-1.25-1.25-.69 0-1.25.56-1.25 1.25 0 .69.56 1.25 1.25 1.25"/><path d="m10.501 2c1.381.001 2.499 1.125 2.499 2.506v5.931c1.024.4 1.75 1.397 1.75 2.563 0 1.519-1.231 2.75-2.75 2.75-1.519 0-2.75-1.231-2.75-2.75 0-1.166.726-2.162 1.75-2.563v-5.931c0-.279-.225-.506-.499-.506v.926c0 .346-.244.474-.569.271l-2.952-1.844c-.314-.196-.325-.507 0-.71l2.952-1.844c.314-.196.569-.081.569.271v.93m1.499 12.25c.69 0 1.25-.56 1.25-1.25 0-.69-.56-1.25-1.25-1.25-.69 0-1.25.56-1.25 1.25 0 .69.56 1.25 1.25 1.25"/></svg>

Before

Width:  |  Height:  |  Size: 1005 B

View File

@ -0,0 +1,12 @@
---
table_name: virtual_registries_packages_maven_cached_responses
classes:
- VirtualRegistries::Packages::Maven::CachedResponse
feature_categories:
- virtual_registry
description: Cached response from a Maven upstream. Contains references to an object storage file.
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157055
milestone: '17.3'
gitlab_schema: gitlab_main_cell
sharding_key:
group_id: namespaces

View File

@ -0,0 +1,9 @@
# frozen_string_literal: true
class AddReadVirtualRegistryToDeployTokens < Gitlab::Database::Migration[2.2]
milestone '17.3'
def change
add_column :deploy_tokens, :read_virtual_registry, :boolean, default: false, null: false
end
end

View File

@ -0,0 +1,48 @@
# frozen_string_literal: true
class CreateVirtualRegistriesPackagesMavenCachedResponses < Gitlab::Database::Migration[2.2]
milestone '17.3'
disable_ddl_transaction!
TABLE_NAME = :virtual_registries_packages_maven_cached_responses
def up
with_lock_retries do
create_table TABLE_NAME, if_not_exists: true do |t|
t.references :group,
null: false,
index: { name: 'index_virtual_reg_pkgs_maven_cached_responses_on_group_id' },
foreign_key: { to_table: :namespaces, on_delete: :cascade }
t.references :upstream,
null: false,
index: false,
foreign_key: { to_table: :virtual_registries_packages_maven_upstreams, on_delete: :nullify }
t.datetime_with_timezone :upstream_checked_at, null: false, default: -> { 'NOW()' }
t.datetime_with_timezone :downloaded_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 :downloads_count, null: false, default: 1
t.text :relative_path, null: false, limit: 255
t.text :file, null: false, limit: 255
t.text :object_storage_key, null: false, limit: 255
t.text :upstream_etag, limit: 255
t.text :content_type, limit: 255, null: false, default: 'application/octet-stream'
end
end
add_concurrent_index(
TABLE_NAME,
[:upstream_id, :relative_path],
unique: true,
name: 'idx_vregs_pkgs_mvn_cached_resp_on_uniq_upstrm_id_and_rel_path'
)
constraint = check_constraint_name(TABLE_NAME.to_s, 'downloads_count', 'positive')
add_check_constraint(TABLE_NAME, 'downloads_count > 0', constraint)
end
def down
drop_table TABLE_NAME
end
end

View File

@ -0,0 +1 @@
4676a59779081ea366775cd96b1983520c6bf139e92c4ada4e6059eb3b7ed56f

View File

@ -0,0 +1 @@
5f9eae6817962776ac40c7644122617cd042fb48af5db9d987367c710e8397d8

View File

@ -9678,7 +9678,8 @@ CREATE TABLE deploy_tokens (
write_registry boolean DEFAULT false NOT NULL,
read_package_registry boolean DEFAULT false NOT NULL,
write_package_registry boolean DEFAULT false NOT NULL,
creator_id bigint
creator_id bigint,
read_virtual_registry boolean DEFAULT false NOT NULL
);
CREATE SEQUENCE deploy_tokens_id_seq
@ -18931,6 +18932,39 @@ CREATE SEQUENCE value_stream_dashboard_counts_id_seq
ALTER SEQUENCE value_stream_dashboard_counts_id_seq OWNED BY value_stream_dashboard_counts.id;
CREATE TABLE virtual_registries_packages_maven_cached_responses (
id bigint NOT NULL,
group_id bigint NOT NULL,
upstream_id bigint NOT NULL,
upstream_checked_at timestamp with time zone DEFAULT now() NOT NULL,
downloaded_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,
downloads_count integer DEFAULT 1 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,
CONSTRAINT check_28c64d513d CHECK ((char_length(object_storage_key) <= 255)),
CONSTRAINT check_30b7e853d9 CHECK ((char_length(upstream_etag) <= 255)),
CONSTRAINT check_68b105cda6 CHECK ((char_length(file) <= 255)),
CONSTRAINT check_731cd48dbf CHECK ((char_length(content_type) <= 255)),
CONSTRAINT check_c2aad543bf CHECK ((downloads_count > 0)),
CONSTRAINT check_d35a8e931f CHECK ((char_length(relative_path) <= 255))
);
CREATE SEQUENCE virtual_registries_packages_maven_cached_responses_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE virtual_registries_packages_maven_cached_responses_id_seq OWNED BY virtual_registries_packages_maven_cached_responses.id;
CREATE TABLE virtual_registries_packages_maven_registries (
id bigint NOT NULL,
group_id bigint NOT NULL,
@ -21652,6 +21686,8 @@ ALTER TABLE ONLY users_statistics ALTER COLUMN id SET DEFAULT nextval('users_sta
ALTER TABLE ONLY value_stream_dashboard_counts ALTER COLUMN id SET DEFAULT nextval('value_stream_dashboard_counts_id_seq'::regclass);
ALTER TABLE ONLY virtual_registries_packages_maven_cached_responses ALTER COLUMN id SET DEFAULT nextval('virtual_registries_packages_maven_cached_responses_id_seq'::regclass);
ALTER TABLE ONLY virtual_registries_packages_maven_registries ALTER COLUMN id SET DEFAULT nextval('virtual_registries_packages_maven_registries_id_seq'::regclass);
ALTER TABLE ONLY virtual_registries_packages_maven_registry_upstreams ALTER COLUMN id SET DEFAULT nextval('virtual_registries_packages_maven_registry_upstreams_id_seq'::regclass);
@ -24366,6 +24402,9 @@ ALTER TABLE ONLY value_stream_dashboard_counts
ALTER TABLE ONLY verification_codes
ADD CONSTRAINT verification_codes_pkey PRIMARY KEY (created_at, visitor_id_code, code, phone);
ALTER TABLE ONLY virtual_registries_packages_maven_cached_responses
ADD CONSTRAINT virtual_registries_packages_maven_cached_responses_pkey PRIMARY KEY (id);
ALTER TABLE ONLY virtual_registries_packages_maven_registries
ADD CONSTRAINT virtual_registries_packages_maven_registries_pkey PRIMARY KEY (id);
@ -26026,6 +26065,8 @@ CREATE INDEX idx_user_credit_card_validations_on_similar_to_meta_data ON user_cr
CREATE INDEX idx_user_details_on_provisioned_by_group_id_user_id ON user_details USING btree (provisioned_by_group_id, user_id);
CREATE UNIQUE INDEX idx_vregs_pkgs_mvn_cached_resp_on_uniq_upstrm_id_and_rel_path ON virtual_registries_packages_maven_cached_responses USING btree (upstream_id, relative_path);
CREATE INDEX idx_vuln_reads_for_filtering ON vulnerability_reads USING btree (project_id, state, dismissal_reason, severity DESC, vulnerability_id DESC NULLS LAST);
CREATE UNIQUE INDEX idx_vuln_signatures_uniqueness_signature_sha ON vulnerability_finding_signatures USING btree (finding_id, algorithm_type, signature_sha);
@ -29676,6 +29717,8 @@ CREATE UNIQUE INDEX index_verification_codes_on_phone_and_visitor_id_code ON ONL
COMMENT ON INDEX index_verification_codes_on_phone_and_visitor_id_code IS 'JiHu-specific index';
CREATE INDEX index_virtual_reg_pkgs_maven_cached_responses_on_group_id ON virtual_registries_packages_maven_cached_responses USING btree (group_id);
CREATE INDEX index_virtual_reg_pkgs_maven_reg_upstreams_on_group_id ON virtual_registries_packages_maven_registry_upstreams USING btree (group_id);
CREATE INDEX index_virtual_reg_pkgs_maven_upstreams_on_group_id ON virtual_registries_packages_maven_upstreams USING btree (group_id);
@ -33574,6 +33617,9 @@ ALTER TABLE ONLY search_namespace_index_assignments
ALTER TABLE ONLY issue_assignment_events
ADD CONSTRAINT fk_rails_07683f8e80 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL;
ALTER TABLE ONLY virtual_registries_packages_maven_cached_responses
ADD CONSTRAINT fk_rails_0816e694a3 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
ALTER TABLE ONLY security_policies
ADD CONSTRAINT fk_rails_08722e8ac7 FOREIGN KEY (security_policy_management_project_id) REFERENCES projects(id) ON DELETE CASCADE;
@ -33646,6 +33692,9 @@ ALTER TABLE ONLY audit_events_streaming_headers
ALTER TABLE ONLY ci_sources_projects
ADD CONSTRAINT fk_rails_10a1eb379a_p FOREIGN KEY (partition_id, pipeline_id) REFERENCES ci_pipelines(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE;
ALTER TABLE ONLY virtual_registries_packages_maven_cached_responses
ADD CONSTRAINT fk_rails_1167f21441 FOREIGN KEY (upstream_id) REFERENCES virtual_registries_packages_maven_upstreams(id) ON DELETE SET NULL;
ALTER TABLE ONLY zoom_meetings
ADD CONSTRAINT fk_rails_1190f0e0fa FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;

View File

@ -143,8 +143,8 @@ You can use [Markdown](../user/markdown.md) in the description.
The member guidelines are visible to users who have the [permission](../user/permissions.md) to manage either:
- Group members at the group level.
- Project members at the project level.
- A group's members.
- A project's members.
You should add member guidelines if you manage group and project membership using either:

View File

@ -10,7 +10,7 @@ DETAILS:
**Tier:** Free, Premium, Ultimate
**Offering:** Self-managed
This is the administration documentation. For information about moderating users at the group level, see the [group-level documentation](../user/group/moderate_users.md).
This is the administration documentation. For information about moderating users in a group, see the [group documentation](../user/group/moderate_users.md).
GitLab administrators can moderate user access by approving, blocking, banning, or deactivating
users.

View File

@ -13,7 +13,7 @@ DETAILS:
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/8066) in GitLab 15.2 [with a flag](../../administration/feature_flags.md) named `git_abuse_rate_limit_feature_flag`. Disabled by default.
> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/394996) in GitLab 15.11. Feature flag `git_abuse_rate_limit_feature_flag` removed.
This is the administration documentation. For information about Git abuse rate limiting at the group level, see the [group-level documentation](../../user/group/reporting/git_abuse_rate_limit.md).
This is the administration documentation. For information about Git abuse rate limiting for a group, see the [group documentation](../../user/group/reporting/git_abuse_rate_limit.md).
Git abuse rate limiting is a feature to automatically [ban users](../../administration/moderate_users.md#ban-and-unban-users) who download, clone, or fork more than a specified number of repositories in any project in the instance in a given time frame. Banned users cannot sign in to the instance and cannot access any non-public group via HTTP or SSH. The rate limit also applies to users who authenticate with a [personal](../../user/profile/personal_access_tokens.md) or [group access token](../../user/group/settings/group_access_tokens.md).

View File

@ -57,7 +57,7 @@ more information about this offering, see [subscriptions](../../subscriptions/se
To deploy a self-hosted large language model:
1. [Set up your self-hosted model deployment infrastructure](../../administration/self_hosted_models/install_infrastructure.md) and connect it to your GitLab instance.
1. [Configure your GitLab instance to access self-hosted models](../../administration/self_hosted_models/configure_duo_features.md) using instance and group level settings.
1. [Configure your GitLab instance to access self-hosted models](../../administration/self_hosted_models/configure_duo_features.md) using instance and group settings.
## Self-hosted models compared to the default GitLab AI vendor architecture

View File

@ -23,9 +23,6 @@ these additional scopes are available for the [advanced search](#advanced-search
## Advanced search API
DETAILS:
**Tier:** Premium, Ultimate
Search for a [term](../user/search/advanced_search.md#syntax) across the entire GitLab instance.
The response depends on the requested scope.

View File

@ -379,7 +379,7 @@ Prerequisites:
You can clean up group runners that have been inactive for more than three months.
Group runners are those that were created at the group level.
Group runners are those that were created in a specific group.
1. On the left sidebar, select **Search or go to** and find your group.
1. Select **Settings > CI/CD**.

View File

@ -181,7 +181,7 @@ supports this case.
#### Authorization
Project and group level permissions exist for `read_package`, `create_package`, and `destroy_package`. Each
Project permissions and group permissions exist for `read_package`, `create_package`, and `destroy_package`. Each
endpoint should
[authorize the requesting user](https://gitlab.com/gitlab-org/gitlab/-/blob/398fef1ca26ae2b2c3dc89750f6b20455a1e5507/ee/lib/api/conan_packages.rb)
against the project or group before continuing.

View File

@ -871,6 +871,13 @@ To verify that code and its specs are well-isolated from Rails, run the spec
individually via `bin/rspec`. Don't use `bin/spring rspec` as it loads
`spec_helper` automatically.
#### Maintaining fast_spec_helper specs
There is a utility script `scripts/run-fast-specs.sh` which can be used to run
all specs which use `fast_spec_helper`, in various ways. This script is useful
to help identify `fast_spec_helper` specs which have problems, such as not
running successfully in isolation. See the script for more details.
### `subject` and `let` variables
The GitLab RSpec suite has made extensive use of `let`(along with its strict, non-lazy

View File

@ -21,8 +21,8 @@ This is a partial list of the [RSpec metadata](https://rspec.info/features/3-12/
| `:geo` | The test requires two GitLab Geo instances - a primary and a secondary - to be spun up. |
| `:gitaly_cluster` | The test runs against a GitLab instance where repositories are stored on redundant Gitaly nodes behind a Praefect node. All nodes are [separate containers](../../../administration/gitaly/praefect.md#requirements). Tests that use this tag have a longer setup time since there are three additional containers that need to be started. |
| `:github` | The test requires a GitHub personal access token. |
| `:group_saml` | The test requires a GitLab instance that has SAML SSO enabled at the group level. Interacts with an external SAML identity provider. Paired with the `:orchestrated` tag. |
| `:instance_saml` | The test requires a GitLab instance that has SAML SSO enabled at the instance level. Interacts with an external SAML identity provider. Paired with the `:orchestrated` tag. |
| `:group_saml` | The test requires a GitLab instance that has SAML SSO enabled for the group. Interacts with an external SAML identity provider. Paired with the `:orchestrated` tag. |
| `:instance_saml` | The test requires a GitLab instance that has SAML SSO enabled for the instance. Interacts with an external SAML identity provider. Paired with the `:orchestrated` tag. |
| `:integrations` | This aims to test the available [integrations](../../../user/project/integrations/index.md#available-integrations). The test requires Docker to be installed in the run context. It will provision the containers and can be run against a local instance or using the `gitlab-qa` scenario `Test::Integration::Integrations`. |
| `:issue`, `:issue_${num}` | Optional links to issues which might be related to the spec. Helps keep track of related issues and can also be used by tools that create test reports. Currently added automatically to `Allure` test report. Multiple tags can be used by adding an optional numeric suffix like `issue_1`, `issue_2` etc. |
| `:service_ping_disabled` | The test interacts with the GitLab configuration service ping at the instance level to turn Admin area setting service ping checkbox on or off. This tag will have the test run only in the `service_ping_disabled` job and must be paired with the `:orchestrated` and `:requires_admin` tags. |

View File

@ -212,7 +212,7 @@ consistency is ensured by a background job (eventually consistent).
The base query always includes the following filters:
- `stage_event_hash_id` - partition key
- `project_id` or `group_id` - depending if it's a project or group level query
- `project_id` or `group_id` - depending on whether it's a project or group query
- `end_event_timestamp` - date range filter (last 30 days)
Example: Selecting review stage duration for the GitLab project

View File

@ -69,7 +69,7 @@ If you suspect that a user account or bot account has been compromised, you shou
- [Block the user](../administration/moderate_users.md#block-a-user) to mitigate any current risk.
- Reset any credentials the user might have had access to. For example, users with at least the Maintainer role can view protected [CI/CD variables](../ci/variables/index.md) and [runner registration tokens](../security/token_overview.md#runner-registration-tokens-deprecated).
- [Reset the user's password](../security/reset_user_password.md).
- Get the user to [enable two factor authentication](../user/profile/account/two_factor_authentication.md) (2FA), and consider [enforcing 2FA at the instance or group level](../security/two_factor_authentication.md).
- Get the user to [enable two factor authentication](../user/profile/account/two_factor_authentication.md) (2FA), and consider [enforcing 2FA for an instance or group](../security/two_factor_authentication.md).
- After completing an investigation and mitigating impacts, unblock the user.
#### Event types

View File

@ -136,8 +136,8 @@ Follow these steps to configure the base domain and other settings required for
## Enable Auto DevOps and run the pipeline
While Auto DevOps is enabled by default, Auto DevOps can be disabled at both
the instance level (for self-managed instances) and the group level. Complete
While Auto DevOps is enabled by default, Auto DevOps can be disabled for both
the instance (for self-managed instances) and the group. Complete
these steps to enable Auto DevOps if it's disabled:
1. On the left sidebar, select **Search or go to** and find the application project.

View File

@ -43,9 +43,9 @@ The Auto DevOps base domain is required to use
To define the base domain, either:
- In the project, group, or instance level: go to your cluster settings and add it there.
- In the project or group level: add it as an environment variable: `KUBE_INGRESS_BASE_DOMAIN`.
- In the instance level: go to the Admin area, then **Settings > CI/CD > Continuous Integration and Delivery** and add it there.
- In the project, group, or instance: go to your cluster settings and add it there.
- In the project or group: add it as an environment variable: `KUBE_INGRESS_BASE_DOMAIN`.
- In the instance: go to the Admin area, then **Settings > CI/CD > Continuous Integration and Delivery** and add it there.
The base domain variable `KUBE_INGRESS_BASE_DOMAIN` follows the same order of precedence
as other environment [variables](../../ci/variables/index.md#cicd-variable-precedence).

View File

@ -0,0 +1,127 @@
---
stage: Monitor
group: Observability
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
---
# Tutorial: Use GitLab Observability with a Java Spring application
DETAILS:
**Tier:** Ultimate
**Offering:** GitLab.com
**Status:** Beta
> - Observability [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/124966) in GitLab 16.2 [with a flag](../../administration/feature_flags.md) named `observability_features`. Disabled by default.
FLAG:
The availability of this feature is controlled by a feature flag.
For more information, see the history.
This feature is available for testing, but not ready for production use.
In this tutorial, you'll learn how to create, configure, instrument, and monitor a Java Spring application using GitLab Observability features.
## Before you begin
To follow along this tutorial, you must have:
- A GitLab Ultimate subscription for GitLab.com
- A local installation of Ruby on Rails
- Basic knowledge of Git, Java Spring, and the core concepts of [OpenTelemetry](https://opentelemetry.io/)
## Create a GitLab project
First, create a GitLab project and a corresponding access token.
1. On the left sidebar, at the top, select **Create new** (**{plus}**) and **New project/repository**.
1. Select **Create from template**.
1. Select **Spring** and then **Use template**.
1. Enter the project details.
- In the **Project name** field, enter a name such as `test-spring-o11y`
1. Select **Create project**.
1. In the `test-sprint-o11y` project, on the left sidebar, select **Settings > Access tokens**.
1. Create a new access token with the Owner role and the `read_api` and `write_observability` scopes. Store the token value somewhere safe—you'll need it later.
## Run the application
Next, we'll run the application to ensure that it works.
1. After cloning the project from GitLab, open it in IntelliJ (or your preferred IDE).
1. Open `src/main/java/com.example.demo/DemoApplication` and run the application:
![Run application screenshot](img/java_start_application.png)
1. After initialization, the application should be available at `http://localhost:8000`. Test it out, then in the IDE select the **Stop** button.
## Add the OpenTelemetry dependencies
Use auto-instrumentation to instrument the application:
1. In the `pom.xml` file, add the required dependencies:
```xml
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk-extension-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk-extension-autoconfigure-spi</artifactId>
</dependency>
```
```xml
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-bom</artifactId>
<version>1.40.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
```
1. Update dependencies by selecting **Update Maven Changes**:
![Maven changes update UI](img/maven_changes.png)
1. Download the OpenTelemetry java agent file from the OpenTelemetry repository.
```shell
curl --location --http1.0 "https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar"
```
## Define environment variables
The OpenTelemetry autoconfigure libraries read their configuration from environment variables.
1. From the top-right menu, select **Edit Configurations...**:
![Edit configuration](img/java_edit_configuration.png)
1. In the configuration menu, select the icon in the **Environment Variables** field.
![Configuration menu](img/java_configuration_menu.png)
1. Add the following set of environment variables, replacing `{{PATH_TO_JAVA_AGENT}}`, `{{NAMESPACE_ID}}`, `{{PROJECT_ID}}`, `{{PROJECT_ACCESS_TOKEN}}` and `{{SERVICE_NAME}}` with the correct values.
- `JAVA_TOOL_OPTIONS=-javaagent:{{PATH_TO_JAVA_AGENT}}/opentelemetry-javaagent.jar`
- `OTEL_EXPORTER_OTLP_ENDPOINT=https://observe.gitlab.com/v3/{{NAMESPACE_ID}}/{{PROJECT_ID}}/ingest`
- `OTEL_EXPORTER_OTLP_HEADERS=PRIVATE-TOKEN\={{PROJECT_ACCESS_TOKEN}}`
- `OTEL_LOGS_EXPORTER=otlp`
- `OTEL_METRIC_EXPORT_INTERVAL=15000`
- `OTEL_METRICS_EXPORTER=otlp`
- `OTEL_SERVICE_NAME=example-java-application`
- `OTEL_TRACES_EXPORTER=otlp`
1. Restart the application and reload the page at `http://localhost:8000` a few times.
## View the information in GitLab
To view the exported information from your test project:
1. On the left sidebar, select **Search or go to** and find your project.
1. Select **Monitor**, then either **Logs**, **Metrics**, or **Traces**.

View File

@ -1,127 +1,11 @@
---
stage: Monitor
group: Observability
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
redirect_to: 'observability_java_tutorial.md'
remove_date: '2024-10-25'
---
# Tutorial: Use GitLab Observability with a Java Spring application
This document was moved to [another location](observability_java_tutorial.md).
DETAILS:
**Tier:** Ultimate
**Offering:** GitLab.com
**Status:** Beta
> - Observability [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/124966) in GitLab 16.2 [with a flag](../../administration/feature_flags.md) named `observability_features`. Disabled by default.
FLAG:
The availability of this feature is controlled by a feature flag.
For more information, see the history.
This feature is available for testing, but not ready for production use.
In this tutorial, you'll learn how to create, configure, instrument, and monitor a Java Spring application using GitLab Observability features.
## Before you begin
To follow along this tutorial, you must have:
- A GitLab Ultimate subscription for GitLab.com
- A local installation of Ruby on Rails
- Basic knowledge of Git, Java Spring, and the core concepts of [OpenTelemetry](https://opentelemetry.io/)
## Create a GitLab project
First, create a GitLab project and a corresponding access token.
1. On the left sidebar, at the top, select **Create new** (**{plus}**) and **New project/repository**.
1. Select **Create from template**.
1. Select **Spring** and then **Use template**.
1. Enter the project details.
- In the **Project name** field, enter a name such as `test-spring-o11y`
1. Select **Create project**.
1. In the `test-sprint-o11y` project, on the left sidebar, select **Settings > Access tokens**.
1. Create a new access token with the Owner role and the `read_api` and `write_observability` scopes. Store the token value somewhere safe—you'll need it later.
## Run the application
Next, we'll run the application to ensure that it works.
1. After cloning the project from GitLab, open it in IntelliJ (or your preferred IDE).
1. Open `src/main/java/com.example.demo/DemoApplication` and run the application:
![Run application screenshot](img/java_start_application.png)
1. After initialization, the application should be available at `http://localhost:8000`. Test it out, then in the IDE select the **Stop** button.
## Add the OpenTelemetry dependencies
Use auto-instrumentation to instrument the application:
1. In the `pom.xml` file, add the required dependencies:
```xml
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk-extension-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk-extension-autoconfigure-spi</artifactId>
</dependency>
```
```xml
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-bom</artifactId>
<version>1.40.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
```
1. Update dependencies by selecting **Update Maven Changes**:
![Maven changes update UI](img/maven_changes.png)
1. Download the OpenTelemetry java agent file from the OpenTelemetry repository.
```shell
curl --location --http1.0 "https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar"
```
## Define environment variables
The OpenTelemetry autoconfigure libraries read their configuration from environment variables.
1. From the top-right menu, select **Edit Configurations...**:
![Edit configuration](img/java_edit_configuration.png)
1. In the configuration menu, select the icon in the **Environment Variables** field.
![Configuration menu](img/java_configuration_menu.png)
1. Add the following set of environment variables, replacing `{{PATH_TO_JAVA_AGENT}}`, `{{NAMESPACE_ID}}`, `{{PROJECT_ID}}`, `{{PROJECT_ACCESS_TOKEN}}` and `{{SERVICE_NAME}}` with the correct values.
- `JAVA_TOOL_OPTIONS=-javaagent:{{PATH_TO_JAVA_AGENT}}/opentelemetry-javaagent.jar`
- `OTEL_EXPORTER_OTLP_ENDPOINT=https://observe.gitlab.com/v3/{{NAMESPACE_ID}}/{{PROJECT_ID}}/ingest`
- `OTEL_EXPORTER_OTLP_HEADERS=PRIVATE-TOKEN\={{PROJECT_ACCESS_TOKEN}}`
- `OTEL_LOGS_EXPORTER=otlp`
- `OTEL_METRIC_EXPORT_INTERVAL=15000`
- `OTEL_METRICS_EXPORTER=otlp`
- `OTEL_SERVICE_NAME=example-java-application`
- `OTEL_TRACES_EXPORTER=otlp`
1. Restart the application and reload the page at `http://localhost:8000` a few times.
## View the information in GitLab
To view the exported information from your test project:
1. On the left sidebar, select **Search or go to** and find your project.
1. Select **Monitor**, then either **Logs**, **Metrics**, or **Traces**.
<!-- This redirect file can be deleted after <2024-10-25>. -->
<!-- Redirects that point to other docs in the same project expire in three months. -->
<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->

View File

@ -248,7 +248,7 @@ and use it to automatically:
## DORA metrics availability
The table below provides an overview of the DORA metrics' availability at project and group level:
The table below provides an overview of the DORA metrics' availability in projects and groups:
| Metric | Level | Comments |
|---------------------------|-------------------|----------|

View File

@ -157,7 +157,7 @@ GitLab.com. To do so, set the CI/CD variable `SECURE_ANALYZERS_PREFIX` with the
project [container registry](../../packages/container_registry/index.md).
You can set this variable in the projects' `.gitlab-ci.yml`, or
in the GitLab UI at the project or group level. See the [GitLab CI/CD variables page](../../../ci/variables/index.md#define-a-cicd-variable-in-the-ui)
in the GitLab UI in the project or group. See the [GitLab CI/CD variables page](../../../ci/variables/index.md#define-a-cicd-variable-in-the-ui)
for more information.
#### Variables

View File

@ -172,8 +172,8 @@ Users are notified of the following events:
| Personal access tokens have been created | User | Security email, always sent. |
| Personal access tokens have expired | User | Security email, always sent. |
| Personal access token has been revoked | User | Security email, always sent. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/98911) in GitLab 15.5. |
| Group access tokens expiring soon | Group owners, maintainers, and administrators | Security email, always sent. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/367705) in GitLab 16.4. |
| Project access tokens expiring soon | Group owners, maintainers, and administrators | Security email, always sent. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/367705) in GitLab 16.4. |
| Group access tokens expiring soon | Group Owners, Maintainers, and administrators | Security email, always sent. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/367705) in GitLab 16.4. |
| Project access tokens expiring soon | Project Owners and Maintainers | Security email, always sent. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/367706) in GitLab 16.4. |
| Project access level changed | User | Sent when user project access level is changed. |
| SSH key has expired | User | Security email, always sent. |
| Two-factor authentication disabled | User | Security email, always sent. |

View File

@ -24536,9 +24536,6 @@ msgstr ""
msgid "Go to merge requests"
msgstr ""
msgid "Go to next page"
msgstr ""
msgid "Go to parent"
msgstr ""
@ -24551,9 +24548,6 @@ msgstr ""
msgid "Go to pipelines"
msgstr ""
msgid "Go to previous page"
msgstr ""
msgid "Go to project"
msgstr ""

View File

@ -17,6 +17,10 @@ module QA
end
it 'transfers a subgroup to another group', :blocking,
quarantine: {
issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/471699',
type: :investigating
},
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347692' do
Page::Group::Menu.perform(&:go_to_general_settings)
Page::Group::Settings::General.perform do |general|

97
scripts/run-fast-specs.sh Executable file
View File

@ -0,0 +1,97 @@
#!/usr/bin/env bash
# shellcheck disable=SC2059
BCyan='\033[1;36m'
BRed='\033[1;31m'
BGreen='\033[1;32m'
BBlue='\033[1;34m'
Color_Off='\033[0m'
set -o errexit
set -o pipefail
trap onexit_err ERR
# Exit handling
function onexit_err() {
local exit_status=${1:-$?}
printf "\n❌❌❌ ${BRed}Run of fast_spec_helper specs failed!${Color_Off} ❌❌❌\n"
exit "${exit_status}"
}
function print_start_message {
trap onexit_err ERR
printf "${BCyan}\nStarting run of fast_spec_helper specs...${Color_Off}\n"
}
function run_fast_spec_helper_specs {
trap onexit_err ERR
printf "\n\n${BBlue}Running specs which use fast_spec_helper and also run fast...${Color_Off}\n\n"
# TIP: Add '--format=documentation --order=stable' when debugging flaky interaction between specs
bin/rspec --tag=~uses_fast_spec_helper_but_runs_slow "${fast_spec_helper_specs[@]}"
}
function run_fast_spec_helper_specs_which_are_slow {
trap onexit_err ERR
printf "\n\n${BBlue}Running specs which use fast_spec_helper but actually run slow...${Color_Off}\n\n"
# NOTE: fails_if_sidekiq_not_configured tag is used to skip specs which require special local config for sidekiq
bin/rspec --tag=uses_fast_spec_helper_but_runs_slow --tag=~fails_if_sidekiq_not_configured "${fast_spec_helper_specs[@]}"
}
function run_all_fast_spec_helper_specs_individually {
trap onexit_err ERR
printf "\n\n${BBlue}INDIVIDUALLY running all specs which use fast_spec_helper to ensure they run in isolation (this will be SLOW! Set SPEC_FILE_TO_START_AT to skip known-good spec files)...${Color_Off}\n\n"
# NOTE: Override `SPEC_FILE_TO_START_AT` to the relative path of a specific file in order to skip specs which are already known to be passing
SPEC_FILE_TO_START_AT="${SPEC_FILE_TO_START_AT:-${fast_spec_helper_specs[0]}}"
for spec_file in "${fast_spec_helper_specs[@]}"; do
if [ "${spec_file}" = "${SPEC_FILE_TO_START_AT}" ]; then
printf "${BBlue}Starting individual spec runs at SPEC_FILE_TO_START_AT: '${SPEC_FILE_TO_START_AT}'${Color_Off}\n\n"
START_RUNNING=true
fi
if [ -n "${START_RUNNING}" ]; then
printf "${BBlue}Running spec '${spec_file}' individually:${Color_Off}\n"
bin/rspec --tag=~fails_if_sidekiq_not_configured "$spec_file"
fi
done
}
function print_success_message {
trap onexit_err ERR
printf "\n✅✅✅ ${BGreen}All executed fast_spec_helper specs passed successfully!${Color_Off} ✅✅✅\n"
}
function main {
trap onexit_err ERR
# cd to gitlab root directory
cd "$(dirname "${BASH_SOURCE[0]}")"/..
# See https://github.com/koalaman/shellcheck/wiki/SC2207 for more context on this approach of creating an array
fast_spec_helper_specs=()
while IFS='' read -r line; do
fast_spec_helper_specs+=("$line")
done < <(git grep -l -E '^require .fast_spec_helper' -- '**/*_spec.rb')
print_start_message
if [ -n "${RUN_ALL_FAST_SPECS_INDIVIDUALLY}" ]; then
run_all_fast_spec_helper_specs_individually
else
run_fast_spec_helper_specs
run_fast_spec_helper_specs_which_are_slow
fi
print_success_message
}
main "$@"

View File

@ -4,7 +4,7 @@ require 'fast_spec_helper'
require 'shellwords'
require 'rspec-parameterized'
RSpec.describe 'bin/sidekiq-cluster', :aggregate_failures do
RSpec.describe 'bin/sidekiq-cluster', :uses_fast_spec_helper_but_runs_slow, :fails_if_sidekiq_not_configured, :aggregate_failures do
using RSpec::Parameterized::TableSyntax
let(:root) { File.expand_path('../..', __dir__) }

View File

@ -5,7 +5,7 @@ require 'tempfile'
# We need to capture pid from Process.spawn and then clean up by killing the process, which requires instance variables.
# rubocop: disable RSpec/InstanceVariable
RSpec.describe 'bin/diagnostic-reports-uploader' do
RSpec.describe 'bin/diagnostic-reports-uploader', :uses_fast_spec_helper_but_runs_slow do
# This is a smoke test for 'bin/diagnostic-reports-uploader'.
# We intend to run this binary with `ruby bin/diagnostic-reports-uploader`, without preloading the entire Rails app.
# Also, we use inline gemfile, to avoid pulling full Gemfile from the main app into memory.

View File

@ -10,7 +10,8 @@ RSpec.describe Pajamas::BroadcastBannerComponent, :aggregate_failures, type: :co
dismissable: dismissable,
expire_date: expire_date,
cookie_key: cookie_key,
dismissal_path: dismissal_path
dismissal_path: dismissal_path,
button_testid: button_testid
)
end
@ -21,6 +22,7 @@ RSpec.describe Pajamas::BroadcastBannerComponent, :aggregate_failures, type: :co
let(:expire_date) { Time.now.iso8601 }
let(:cookie_key) { '_cookie_key_' }
let(:dismissal_path) { '/-/my-path' }
let(:button_testid) { 'my-close-button' }
it 'sets the correct classes' do
expect(page).to have_selector(".js-broadcast-notification-#{id}")
@ -60,4 +62,8 @@ RSpec.describe Pajamas::BroadcastBannerComponent, :aggregate_failures, type: :co
expect(page).not_to have_selector('button.js-dismiss-current-broadcast-notification')
end
end
it 'sets the button testid' do
expect(page).to have_selector("button[data-testid='#{button_testid}']")
end
end

View File

@ -682,6 +682,35 @@ RSpec.describe GraphqlController, feature_category: :integrations do
expect(GraphiQL::Rails::VERSION).to eq("1.10.0")
end
end
context 'when X_GITLAB_DISABLE_SQL_QUERY_LIMIT is set' do
let(:issue_url) { "http://some/issue/url" }
let(:limit) { 205 }
context 'and it specifies a new query limit' do
let(:header_value) { "#{limit},#{issue_url}" }
it 'respects the new query limit' do
expect(Gitlab::QueryLimiting).to receive(:disable!).with(issue_url, new_threshold: limit)
request.env['HTTP_X_GITLAB_DISABLE_SQL_QUERY_LIMIT'] = header_value
post :execute
end
end
context 'and it does not specify a new limit' do
let(:header_value) { issue_url }
it 'disables limit' do
expect(Gitlab::QueryLimiting).to receive(:disable!).with(issue_url)
request.env['HTTP_X_GITLAB_DISABLE_SQL_QUERY_LIMIT'] = header_value
post :execute
end
end
end
end
describe 'Admin Mode' do

View File

@ -1,6 +1,9 @@
# frozen_string_literal: true
require 'fast_spec_helper'
# NOTE: Do not remove the parentheses from this require statement!
# They are necessary so it doesn't match the regex in `scripts/run-fast-specs.sh`,
# and make the "fast" portion of that suite run slow.
require('fast_spec_helper') # NOTE: Do not remove the parentheses from this require statement!
PatternsList = Struct.new(:name, :patterns)

View File

@ -8,6 +8,7 @@ FactoryBot.define do
write_registry { false }
read_package_registry { false }
write_package_registry { false }
read_virtual_registry { false }
revoked { false }
expires_at { 5.days.from_now.to_datetime }
deploy_token_type { DeployToken.deploy_token_types[:project_type] }
@ -36,6 +37,7 @@ FactoryBot.define do
write_registry { true }
read_package_registry { true }
write_package_registry { true }
read_virtual_registry { true }
end
trait :dependency_proxy_scopes do

View File

@ -0,0 +1,23 @@
# frozen_string_literal: true
FactoryBot.define do
factory :virtual_registries_packages_maven_cached_response,
class: 'VirtualRegistries::Packages::Maven::CachedResponse' do
upstream { association :virtual_registries_packages_maven_upstream }
group { upstream.group }
relative_path { '/a/relative/path/test.txt' }
size { 1.kilobyte }
upstream_etag { OpenSSL::Digest.hexdigest('SHA256', 'test') }
content_type { 'text/plain' }
downloads_count { 5 }
transient do
file_fixture { 'spec/fixtures/bfg_object_map.txt' }
end
after(:build) do |entry, evaluator|
entry.upstream.registry_upstream.group = entry.group
entry.file = fixture_file_upload(evaluator.file_fixture)
end
end
end

View File

@ -62,7 +62,7 @@ describe('AbuseReportsApp', () => {
value: pagination.currentPage,
perPage: pagination.perPage,
totalItems: pagination.totalItems,
prevText: 'Prev',
prevText: 'Previous',
nextText: 'Next',
labelNextPage: 'Go to next page',
labelPrevPage: 'Go to previous page',

View File

@ -189,8 +189,6 @@ describe('DeployKeysTable', () => {
value: 1,
perPage: DEFAULT_PER_PAGE,
totalItems: responseBody.length,
nextText: DeployKeysTable.i18n.pagination.next,
prevText: DeployKeysTable.i18n.pagination.prev,
align: 'center',
});
});

View File

@ -33,13 +33,7 @@ describe('RunnerTypeBadge', () => {
expect(findBadge().props()).toMatchObject({ variant: 'muted' });
expect(findBadge().classes().sort()).toEqual(
[
...classes,
'gl-shadow-inner-1-gray-400',
'gl-max-w-full',
'gl-text-truncate',
'gl-bg-transparent!',
].sort(),
[...classes, 'gl-shadow-inner-1-gray-400', '!gl-bg-transparent'].sort(),
);
expect(findBadge().text()).toBe(text);
},

View File

@ -15,11 +15,13 @@ describe('RunnerTag', () => {
const getTooltipValue = () => getBinding(findBadge().element, 'gl-tooltip').value;
const setDimensions = ({ scrollWidth, offsetWidth }) => {
jest.spyOn(findBadge().element, 'scrollWidth', 'get').mockReturnValue(scrollWidth);
jest.spyOn(findBadge().element, 'offsetWidth', 'get').mockReturnValue(offsetWidth);
const content = findBadge().element.querySelector('span');
jest.spyOn(content, 'scrollWidth', 'get').mockReturnValue(scrollWidth);
jest.spyOn(content, 'offsetWidth', 'get').mockReturnValue(offsetWidth);
// Mock trigger resize
getBinding(findBadge().element, 'gl-resize-observer').value();
getBinding(content, 'gl-resize-observer').value({ target: content });
};
const createComponent = ({ props = {} } = {}) => {

View File

@ -41,7 +41,7 @@ describe('MembersPagination', () => {
value: mockPagination.currentPage,
perPage: mockPagination.perPage,
totalItems: mockPagination.totalItems,
prevText: 'Prev',
prevText: 'Previous',
nextText: 'Next',
labelNextPage: 'Go to next page',
labelPrevPage: 'Go to previous page',

View File

@ -98,8 +98,6 @@ describe('FollowersTab', () => {
value: defaultPropsData.page,
totalItems: defaultPropsData.totalItems,
perPage: DEFAULT_PER_PAGE,
prevText: Follow.i18n.prev,
nextText: Follow.i18n.next,
});
});

View File

@ -335,25 +335,40 @@ describe('WorkItemLabels component', () => {
});
it('shows selected labels at top of list', async () => {
const [label1, label2, label3] = mockLabels;
const label999 = {
__typename: 'Label',
id: 'gid://gitlab/Label/999',
title: 'Label 999',
description: 'Label not in the label query result',
color: '#fff',
textColor: '#000',
};
createComponent({
workItemQueryHandler: workItemQuerySuccess,
updateWorkItemMutationHandler: successAddRemoveLabelWorkItemMutationHandler,
updateWorkItemMutationHandler: jest.fn().mockResolvedValue(
updateWorkItemMutationResponseFactory({
labels: [label1, label999],
}),
),
});
updateLabels([label1Id, label3Id]);
updateLabels([label1Id, label999.id]);
showDropdown();
await waitForPromises();
const [label1, label2, label3] = mockLabels;
const selected = [
{ color: label1.color, text: label1.title, value: label1.id },
{ color: label3.color, text: label3.title, value: label3.id },
{ color: label999.color, text: label999.title, value: label999.id },
];
const unselected = [{ color: label2.color, text: label2.title, value: label2.id }];
const unselected = [
{ color: label2.color, text: label2.title, value: label2.id },
{ color: label3.color, text: label3.title, value: label3.id },
];
expect(findWorkItemSidebarDropdownWidget().props('listItems')).toEqual([
{ options: selected, text: __('Selected') },

View File

@ -7,7 +7,7 @@ require 'rspec-parameterized'
require_relative '../../../haml_lint/linter/inline_javascript'
RSpec.describe HamlLint::Linter::InlineJavaScript do # rubocop:disable RSpec/FilePath
RSpec.describe HamlLint::Linter::InlineJavaScript, :uses_fast_spec_helper_but_runs_slow do # rubocop:disable RSpec/FilePath
using RSpec::Parameterized::TableSyntax
include_context 'linter'

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