Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
115c175a7d
commit
0636ab91ee
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -122,6 +122,8 @@ export default {
|
|||
:icon="badge.icon"
|
||||
v-bind="$attrs"
|
||||
>
|
||||
{{ badge.label }}
|
||||
<span class="gl-truncate">
|
||||
{{ badge.label }}
|
||||
</span>
|
||||
</gl-badge>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -334,8 +334,6 @@ export default {
|
|||
v-model="currentPage"
|
||||
:per-page="clustersPerPage"
|
||||
:total-items="totalClusters"
|
||||
:prev-text="__('Prev')"
|
||||
:next-text="__('Next')"
|
||||
align="center"
|
||||
/>
|
||||
</section>
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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 }}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
.commit-title {
|
||||
margin: 0;
|
||||
color: var(--gl-text-color);
|
||||
color: var(--gl-text-color-default);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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%);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@
|
|||
|
||||
i,
|
||||
a {
|
||||
color: var(--gl-text-color, $gl-text-color);
|
||||
color: var(--gl-text-color-default);
|
||||
}
|
||||
|
||||
img {
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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-'
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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')
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 |
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1 @@
|
|||
4676a59779081ea366775cd96b1983520c6bf139e92c4ada4e6059eb3b7ed56f
|
||||
|
|
@ -0,0 +1 @@
|
|||
5f9eae6817962776ac40c7644122617cd042fb48af5db9d987367c710e8397d8
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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**.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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. |
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
|
|
|||
|
|
@ -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:
|
||||

|
||||
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**:
|
||||
|
||||

|
||||
|
||||
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...**:
|
||||
|
||||

|
||||
|
||||
1. In the configuration menu, select the icon in the **Environment Variables** field.
|
||||
|
||||

|
||||
|
||||
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**.
|
||||
|
|
@ -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:
|
||||

|
||||
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**:
|
||||
|
||||

|
||||
|
||||
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...**:
|
||||
|
||||

|
||||
|
||||
1. In the configuration menu, select the icon in the **Environment Variables** field.
|
||||
|
||||

|
||||
|
||||
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 -->
|
||||
|
|
|
|||
|
|
@ -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 |
|
||||
|---------------------------|-------------------|----------|
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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. |
|
||||
|
|
|
|||
|
|
@ -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 ""
|
||||
|
||||
|
|
|
|||
|
|
@ -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|
|
||||
|
|
|
|||
|
|
@ -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 "$@"
|
||||
|
|
@ -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__) }
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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 = {} } = {}) => {
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -98,8 +98,6 @@ describe('FollowersTab', () => {
|
|||
value: defaultPropsData.page,
|
||||
totalItems: defaultPropsData.totalItems,
|
||||
perPage: DEFAULT_PER_PAGE,
|
||||
prevText: Follow.i18n.prev,
|
||||
nextText: Follow.i18n.next,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -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') },
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Reference in New Issue