Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
e10b16bade
commit
05b3a2ebd7
|
|
@ -242,7 +242,7 @@ variables:
|
|||
RETRY_FAILED_TESTS_IN_NEW_PROCESS: "true"
|
||||
# Run with decomposed databases by default
|
||||
DECOMPOSED_DB: "true"
|
||||
SEC_DECOMPOSED_DB: "false"
|
||||
SEC_DECOMPOSED_DB: "true"
|
||||
|
||||
DOCS_REVIEW_APPS_DOMAIN: "docs.gitlab-review.app"
|
||||
DOCS_GITLAB_REPO_SUFFIX: "ee"
|
||||
|
|
|
|||
|
|
@ -115,8 +115,8 @@
|
|||
.if-merge-request-labels-run-single-db: &if-merge-request-labels-run-single-db
|
||||
if: '($CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_EVENT_TYPE != "merge_train") && $CI_MERGE_REQUEST_LABELS =~ /pipeline:run-single-db/'
|
||||
|
||||
.if-merge-request-labels-sec-decomposition: &if-merge-request-labels-sec-decomposition
|
||||
if: '($CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_EVENT_TYPE != "merge_train") && $CI_MERGE_REQUEST_LABELS =~ /sec-decomposition/'
|
||||
.if-merge-request-labels-pipeline-single-db-sec-connection: &if-merge-request-labels-pipeline-single-db-sec-connection
|
||||
if: '($CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_EVENT_TYPE != "merge_train") && $CI_MERGE_REQUEST_LABELS =~ /pipeline:single-db-sec-connection/'
|
||||
|
||||
.if-merge-request-labels-run-review-app: &if-merge-request-labels-run-review-app
|
||||
if: '($CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_EVENT_TYPE != "merge_train") && $CI_MERGE_REQUEST_LABELS =~ /pipeline:run-review-app/'
|
||||
|
|
@ -2009,7 +2009,7 @@
|
|||
rules:
|
||||
- <<: *if-default-branch-schedule-nightly
|
||||
- <<: *if-merge-request-labels-run-single-db
|
||||
- <<: *if-merge-request-labels-sec-decomposition
|
||||
- <<: *if-merge-request-labels-pipeline-single-db-sec-connection
|
||||
- <<: *if-merge-request-labels-pipeline-expedite
|
||||
when: never
|
||||
- if: '$ENABLE_RSPEC_SINGLE_DB_SEC_CONNECTION == "true"'
|
||||
|
|
@ -2025,7 +2025,7 @@
|
|||
.rails:rules:db:check-migrations-single-db-sec-connection:
|
||||
rules:
|
||||
- <<: *if-merge-request-labels-run-single-db
|
||||
- <<: *if-merge-request-labels-sec-decomposition
|
||||
- <<: *if-merge-request-labels-pipeline-single-db-sec-connection
|
||||
- <<: *if-merge-request-labels-pipeline-expedite
|
||||
when: never
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
bf5c4776481bc6ff03782dca926a29c878f5880e
|
||||
93b9e36e23c2a4e51dc2012932830b72c8f838aa
|
||||
|
|
|
|||
|
|
@ -0,0 +1,147 @@
|
|||
<script>
|
||||
import { GlButton, GlFormGroup, GlFormInput } from '@gitlab/ui';
|
||||
import validation, { initForm } from '~/vue_shared/directives/validation';
|
||||
import csrf from '~/lib/utils/csrf';
|
||||
import MultiStepFormTemplate from '~/vue_shared/components/multi_step_form_template.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GlButton,
|
||||
GlFormGroup,
|
||||
GlFormInput,
|
||||
MultiStepFormTemplate,
|
||||
},
|
||||
directives: {
|
||||
validation: validation(),
|
||||
},
|
||||
props: {
|
||||
backButtonPath: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
formPath: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
const form = initForm({
|
||||
fields: {
|
||||
bitbucket_server_url: { value: null },
|
||||
bitbucket_server_username: { value: null },
|
||||
personal_access_token: { value: null },
|
||||
},
|
||||
});
|
||||
return {
|
||||
form,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
onSubmit() {
|
||||
if (!this.form.state) {
|
||||
this.form.showValidation = true;
|
||||
return;
|
||||
}
|
||||
|
||||
this.$refs.form.submit();
|
||||
},
|
||||
},
|
||||
csrf,
|
||||
placeholders: {
|
||||
url: 'https://your-bitbucket-server.com',
|
||||
token: '8d3f016698e...',
|
||||
username: 'username',
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<form ref="form" method="post" :action="formPath" @submit.prevent="onSubmit">
|
||||
<input :value="$options.csrf.token" type="hidden" name="authenticity_token" />
|
||||
<multi-step-form-template
|
||||
:title="s__('ProjectsNew|Import repositories from Bitbucket Server')"
|
||||
:current-step="3"
|
||||
:steps-total="4"
|
||||
>
|
||||
<template #form>
|
||||
<gl-form-group
|
||||
:label="s__('ProjectsNew|Bitbucket Server URL')"
|
||||
label-for="bitbucket_server_url"
|
||||
:invalid-feedback="form.fields.bitbucket_server_url.feedback"
|
||||
data-testid="url-group"
|
||||
>
|
||||
<gl-form-input
|
||||
id="bitbucket_server_url"
|
||||
v-model="form.fields.bitbucket_server_url.value"
|
||||
v-validation:[form.showValidation]
|
||||
:validation-message="s__('ProjectsNew|Please enter a valid Bitbucket Server URL.')"
|
||||
:state="form.fields.bitbucket_server_url.state"
|
||||
name="bitbucket_server_url"
|
||||
type="url"
|
||||
required
|
||||
:placeholder="$options.placeholders.url"
|
||||
data-testid="url-input"
|
||||
/>
|
||||
</gl-form-group>
|
||||
<gl-form-group
|
||||
:label="__('Username')"
|
||||
label-for="bitbucket_server_username"
|
||||
:invalid-feedback="form.fields.bitbucket_server_username.feedback"
|
||||
data-testid="username-group"
|
||||
>
|
||||
<gl-form-input
|
||||
id="bitbucket_server_username"
|
||||
v-model="form.fields.bitbucket_server_username.value"
|
||||
v-validation:[form.showValidation]
|
||||
:validation-message="s__('ProjectsNew|Please enter a valid username.')"
|
||||
:state="form.fields.bitbucket_server_username.state"
|
||||
name="bitbucket_server_username"
|
||||
required
|
||||
:placeholder="$options.placeholders.username"
|
||||
data-testid="username-input"
|
||||
/>
|
||||
</gl-form-group>
|
||||
<gl-form-group
|
||||
:label="s__('ProjectsNew|Password/Personal access token')"
|
||||
label-for="personal_access_token"
|
||||
:invalid-feedback="form.fields.personal_access_token.feedback"
|
||||
data-testid="token-group"
|
||||
>
|
||||
<gl-form-input
|
||||
id="personal_access_token"
|
||||
v-model="form.fields.personal_access_token.value"
|
||||
v-validation:[form.showValidation]
|
||||
:validation-message="s__('ProjectsNew|Please enter a valid token.')"
|
||||
:state="form.fields.personal_access_token.state"
|
||||
name="personal_access_token"
|
||||
required
|
||||
type="password"
|
||||
:placeholder="$options.placeholders.token"
|
||||
data-testid="token-input"
|
||||
/>
|
||||
</gl-form-group>
|
||||
</template>
|
||||
<template #back>
|
||||
<gl-button
|
||||
category="primary"
|
||||
variant="default"
|
||||
:href="backButtonPath"
|
||||
data-testid="back-button"
|
||||
>
|
||||
{{ __('Go back') }}
|
||||
</gl-button>
|
||||
</template>
|
||||
<template #next>
|
||||
<gl-button
|
||||
type="submit"
|
||||
category="primary"
|
||||
variant="confirm"
|
||||
data-testid="next-button"
|
||||
@click.prevent="onSubmit"
|
||||
>
|
||||
{{ __('Next step') }}
|
||||
</gl-button>
|
||||
</template>
|
||||
</multi-step-form-template>
|
||||
</form>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
import Vue from 'vue';
|
||||
import importFromBitbucketServerApp from './import_from_bitbucket_server_app.vue';
|
||||
|
||||
export function initBitbucketServerImportProjectForm() {
|
||||
const el = document.getElementById('js-vue-import-bitbucket-server-project-root');
|
||||
|
||||
if (!el) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { backButtonPath, formPath } = el.dataset;
|
||||
|
||||
const props = { backButtonPath, formPath };
|
||||
|
||||
return new Vue({
|
||||
el,
|
||||
name: 'ImportFromBitbucketServerRoot',
|
||||
render(h) {
|
||||
return h(importFromBitbucketServerApp, { props });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
<script>
|
||||
import { GlButton, GlFormGroup, GlFormInput, GlAnimatedUploadIcon } from '@gitlab/ui';
|
||||
import { kebabCase } from 'lodash';
|
||||
import { s__ } from '~/locale';
|
||||
import validation from '~/vue_shared/directives/validation';
|
||||
import csrf from '~/lib/utils/csrf';
|
||||
import { numberToHumanSize } from '~/lib/utils/number_utils';
|
||||
|
|
@ -12,6 +13,7 @@ import NewProjectDestinationSelect from '~/projects/new_v2/components/project_de
|
|||
const feedbackMap = {
|
||||
valueMissing: {
|
||||
isInvalid: (el) => el.validity?.valueMissing,
|
||||
message: s__('ProjectsNew|Please enter a valid project name.'),
|
||||
},
|
||||
nameStartPattern: {
|
||||
isInvalid: (el) => el.validity?.patternMismatch && !START_RULE.reg.test(el.value),
|
||||
|
|
@ -167,7 +169,6 @@ export default {
|
|||
id="name"
|
||||
v-model="form.fields.name.value"
|
||||
v-validation:[form.showValidation]
|
||||
:validation-message="s__('ProjectsNew|Please enter a valid project name.')"
|
||||
:state="form.fields.name.state"
|
||||
:pattern="$options.projectNamePattern"
|
||||
name="name"
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import { setUrlFragment, visitUrlWithAlerts } from '~/lib/utils/url_utility';
|
|||
import getModelVersionQuery from '~/ml/model_registry/graphql/queries/get_model_version.query.graphql';
|
||||
import deleteModelVersionMutation from '~/ml/model_registry/graphql/mutations/delete_model_version.mutation.graphql';
|
||||
import { convertToGraphQLId, getIdFromGraphQLId } from '~/graphql_shared/utils';
|
||||
import { makeLoadVersionsErrorMessage } from '~/ml/model_registry/translations';
|
||||
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
|
||||
import timeagoMixin from '~/vue_shared/mixins/timeago';
|
||||
import ModelVersionDetail from '../components/model_version_detail.vue';
|
||||
|
|
@ -186,7 +185,12 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
handleError(error) {
|
||||
this.errorMessage = makeLoadVersionsErrorMessage(error.message);
|
||||
this.errorMessage = sprintf(
|
||||
s__('MlModelRegistry|Failed to load model version with error: %{message}'),
|
||||
{
|
||||
message: error.message,
|
||||
},
|
||||
);
|
||||
Sentry.captureException(error, {
|
||||
tags: {
|
||||
vue_component: 'show_ml_model_version',
|
||||
|
|
|
|||
|
|
@ -1,26 +1,7 @@
|
|||
<script>
|
||||
import { GlAvatarLabeled, GlLink, GlTableLite } from '@gitlab/ui';
|
||||
import { isEmpty, maxBy, range } from 'lodash';
|
||||
import { __, sprintf } from '~/locale';
|
||||
import {
|
||||
INFO_LABEL,
|
||||
ID_LABEL,
|
||||
STATUS_LABEL,
|
||||
EXPERIMENT_LABEL,
|
||||
ARTIFACTS_LABEL,
|
||||
PARAMETERS_LABEL,
|
||||
METADATA_LABEL,
|
||||
MLFLOW_ID_LABEL,
|
||||
CI_SECTION_LABEL,
|
||||
JOB_LABEL,
|
||||
CI_USER_LABEL,
|
||||
CI_MR_LABEL,
|
||||
PERFORMANCE_LABEL,
|
||||
NO_PARAMETERS_MESSAGE,
|
||||
NO_METRICS_MESSAGE,
|
||||
NO_METADATA_MESSAGE,
|
||||
NO_CI_MESSAGE,
|
||||
} from '../translations';
|
||||
import { __, s__, sprintf } from '~/locale';
|
||||
import DetailRow from './candidate_detail_row.vue';
|
||||
|
||||
export default {
|
||||
|
|
@ -39,23 +20,17 @@ export default {
|
|||
},
|
||||
},
|
||||
i18n: {
|
||||
INFO_LABEL,
|
||||
ID_LABEL,
|
||||
STATUS_LABEL,
|
||||
EXPERIMENT_LABEL,
|
||||
ARTIFACTS_LABEL,
|
||||
MLFLOW_ID_LABEL,
|
||||
CI_SECTION_LABEL,
|
||||
JOB_LABEL,
|
||||
CI_USER_LABEL,
|
||||
CI_MR_LABEL,
|
||||
PARAMETERS_LABEL,
|
||||
METADATA_LABEL,
|
||||
PERFORMANCE_LABEL,
|
||||
NO_PARAMETERS_MESSAGE,
|
||||
NO_METRICS_MESSAGE,
|
||||
NO_METADATA_MESSAGE,
|
||||
NO_CI_MESSAGE,
|
||||
ciSectionLabel: s__('MlModelRegistry|CI Info'),
|
||||
jobLabel: __('Job'),
|
||||
ciUserLabel: s__('MlModelRegistry|Triggered by'),
|
||||
ciMrLabel: __('Merge request'),
|
||||
parametersLabel: s__('MlModelRegistry|Parameters'),
|
||||
metadataLabel: s__('MlModelRegistry|Metadata'),
|
||||
performanceLabel: s__('MlModelRegistry|Performance'),
|
||||
noParametersMessage: s__('MlModelRegistry|No logged parameters'),
|
||||
noMetricsMessage: s__('MlModelRegistry|No logged metrics'),
|
||||
noMetadataMessage: s__('MlModelRegistry|No logged metadata'),
|
||||
noCiMessage: s__('MlModelRegistry|Run not linked to a CI build'),
|
||||
},
|
||||
computed: {
|
||||
info() {
|
||||
|
|
@ -104,20 +79,17 @@ export default {
|
|||
<template>
|
||||
<div>
|
||||
<section class="gl-mb-6">
|
||||
<h3 :class="$options.HEADER_CLASSES">{{ $options.i18n.CI_SECTION_LABEL }}</h3>
|
||||
<h3 :class="$options.HEADER_CLASSES">{{ $options.i18n.ciSectionLabel }}</h3>
|
||||
|
||||
<table v-if="ciJob" class="candidate-details">
|
||||
<tbody>
|
||||
<detail-row
|
||||
:label="$options.i18n.JOB_LABEL"
|
||||
:section-label="$options.i18n.CI_SECTION_LABEL"
|
||||
>
|
||||
<detail-row :label="$options.i18n.jobLabel" :section-label="$options.i18n.ciSectionLabel">
|
||||
<gl-link :href="ciJob.path">
|
||||
{{ ciJob.name }}
|
||||
</gl-link>
|
||||
</detail-row>
|
||||
|
||||
<detail-row v-if="ciJob.user" :label="$options.i18n.CI_USER_LABEL">
|
||||
<detail-row v-if="ciJob.user" :label="$options.i18n.ciUserLabel">
|
||||
<gl-avatar-labeled label="" :size="24" :src="ciJob.user.avatar">
|
||||
<gl-link :href="ciJob.user.path">
|
||||
{{ ciJob.user.name }}
|
||||
|
|
@ -125,7 +97,7 @@ export default {
|
|||
</gl-avatar-labeled>
|
||||
</detail-row>
|
||||
|
||||
<detail-row v-if="ciJob.mergeRequest" :label="$options.i18n.CI_MR_LABEL">
|
||||
<detail-row v-if="ciJob.mergeRequest" :label="$options.i18n.ciMrLabel">
|
||||
<gl-link :href="ciJob.mergeRequest.path">
|
||||
!{{ ciJob.mergeRequest.iid }} {{ ciJob.mergeRequest.title }}
|
||||
</gl-link>
|
||||
|
|
@ -133,11 +105,11 @@ export default {
|
|||
</tbody>
|
||||
</table>
|
||||
|
||||
<div v-else class="gl-text-subtle">{{ $options.i18n.NO_CI_MESSAGE }}</div>
|
||||
<div v-else class="gl-text-subtle">{{ $options.i18n.noCiMessage }}</div>
|
||||
</section>
|
||||
|
||||
<section class="gl-mb-6">
|
||||
<h3 :class="$options.HEADER_CLASSES">{{ $options.i18n.PARAMETERS_LABEL }}</h3>
|
||||
<h3 :class="$options.HEADER_CLASSES">{{ $options.i18n.parametersLabel }}</h3>
|
||||
|
||||
<table v-if="hasParameters" class="candidate-details">
|
||||
<tbody>
|
||||
|
|
@ -147,11 +119,11 @@ export default {
|
|||
</tbody>
|
||||
</table>
|
||||
|
||||
<div v-else class="gl-text-subtle">{{ $options.i18n.NO_PARAMETERS_MESSAGE }}</div>
|
||||
<div v-else class="gl-text-subtle">{{ $options.i18n.noParametersMessage }}</div>
|
||||
</section>
|
||||
|
||||
<section class="gl-mb-6">
|
||||
<h3 :class="$options.HEADER_CLASSES">{{ $options.i18n.METADATA_LABEL }}</h3>
|
||||
<h3 :class="$options.HEADER_CLASSES">{{ $options.i18n.metadataLabel }}</h3>
|
||||
|
||||
<table v-if="hasMetadata" class="candidate-details">
|
||||
<tbody>
|
||||
|
|
@ -161,11 +133,11 @@ export default {
|
|||
</tbody>
|
||||
</table>
|
||||
|
||||
<div v-else class="gl-text-subtle">{{ $options.i18n.NO_METADATA_MESSAGE }}</div>
|
||||
<div v-else class="gl-text-subtle">{{ $options.i18n.noMetadataMessage }}</div>
|
||||
</section>
|
||||
|
||||
<section class="gl-mb-6">
|
||||
<h3 :class="$options.HEADER_CLASSES">{{ $options.i18n.PERFORMANCE_LABEL }}</h3>
|
||||
<h3 :class="$options.HEADER_CLASSES">{{ $options.i18n.performanceLabel }}</h3>
|
||||
|
||||
<div v-if="hasMetrics" class="gl-overflow-x-auto">
|
||||
<gl-table-lite
|
||||
|
|
@ -176,7 +148,7 @@ export default {
|
|||
/>
|
||||
</div>
|
||||
|
||||
<div v-else class="gl-text-subtle">{{ $options.i18n.NO_METRICS_MESSAGE }}</div>
|
||||
<div v-else class="gl-text-subtle">{{ $options.i18n.noMetricsMessage }}</div>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
<script>
|
||||
import * as Sentry from '~/sentry/sentry_browser_wrapper';
|
||||
import { makeLoadVersionsErrorMessage } from '~/ml/model_registry/translations';
|
||||
import { s__ } from '~/locale';
|
||||
import { s__, sprintf } from '~/locale';
|
||||
import getModelVersionsQuery from '../graphql/queries/get_model_versions.query.graphql';
|
||||
import {
|
||||
GRAPHQL_PAGE_SIZE,
|
||||
|
|
@ -81,7 +80,13 @@ export default {
|
|||
this.$apollo.queries.modelVersions.fetchMore({});
|
||||
},
|
||||
handleError(error) {
|
||||
this.errorMessage = makeLoadVersionsErrorMessage(error.message);
|
||||
this.errorMessage = sprintf(
|
||||
s__('MlModelRegistry|Failed to load model versions with error: %{message}'),
|
||||
{
|
||||
message: error.message,
|
||||
},
|
||||
);
|
||||
|
||||
Sentry.captureException(error);
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
<script>
|
||||
import { GlButton, GlTooltipDirective as GlTooltip, GlLink } from '@gitlab/ui';
|
||||
import { convertCandidateFromGraphql } from '~/ml/model_registry/utils';
|
||||
import * as i18n from '../translations';
|
||||
import CandidateDetail from './candidate_detail.vue';
|
||||
|
||||
export default {
|
||||
|
|
@ -30,14 +29,13 @@ export default {
|
|||
navigator.clipboard.writeText(this.candidate.info.eid);
|
||||
},
|
||||
},
|
||||
i18n,
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="gl-mt-5 gl-pb-5">
|
||||
<span class="gl-font-bold">{{ $options.i18n.MLFLOW_ID_LABEL }}:</span>
|
||||
<span class="gl-font-bold">{{ s__('MlModelRegistry|MLflow run ID') }}:</span>
|
||||
<p class="gl-overflow-hidden gl-text-ellipsis gl-whitespace-nowrap">
|
||||
<gl-link :href="candidate.info.path">
|
||||
{{ candidate.info.eid }}
|
||||
|
|
|
|||
|
|
@ -1,39 +0,0 @@
|
|||
import { __, s__, sprintf } from '~/locale';
|
||||
|
||||
export const DESCRIPTION_LABEL = __('Description');
|
||||
export const NO_DESCRIPTION_PROVIDED_LABEL = s__('MlModelRegistry|No description provided');
|
||||
export const INFO_LABEL = s__('MlModelRegistry|Info');
|
||||
export const DETAILS_LABEL = s__('MlModelRegistry|Details & Metadata');
|
||||
export const ID_LABEL = s__('MlModelRegistry|ID');
|
||||
export const MLFLOW_ID_LABEL = s__('MlModelRegistry|MLflow run ID');
|
||||
export const STATUS_LABEL = s__('MlModelRegistry|Status');
|
||||
export const EXPERIMENT_LABEL = s__('MlModelRegistry|Experiment');
|
||||
export const ARTIFACTS_LABEL = s__('MlModelRegistry|Artifacts');
|
||||
export const NO_ARTIFACTS_MESSAGE = s__('MlModelRegistry|No logged artifacts.');
|
||||
export const PARAMETERS_LABEL = s__('MlModelRegistry|Parameters');
|
||||
export const PERFORMANCE_LABEL = s__('MlModelRegistry|Performance');
|
||||
export const METADATA_LABEL = s__('MlModelRegistry|Metadata');
|
||||
export const NO_PARAMETERS_MESSAGE = s__('MlModelRegistry|No logged parameters');
|
||||
export const NO_METRICS_MESSAGE = s__('MlModelRegistry|No logged metrics');
|
||||
export const NO_METADATA_MESSAGE = s__('MlModelRegistry|No logged metadata');
|
||||
export const NO_CI_MESSAGE = s__('MlModelRegistry|Run not linked to a CI build');
|
||||
export const CI_SECTION_LABEL = s__('MlModelRegistry|CI Info');
|
||||
export const JOB_LABEL = __('Job');
|
||||
export const CI_USER_LABEL = s__('MlModelRegistry|Triggered by');
|
||||
export const CI_MR_LABEL = __('Merge request');
|
||||
export const NEW_MODEL_LABEL = s__('MlModelRegistry|New model');
|
||||
export const CREATE_MODEL_LABEL = s__('MlModelRegistry|Create model');
|
||||
export const ERROR_CREATING_MODEL_LABEL = s__(
|
||||
'MlModelRegistry|An error has occurred when saving the model.',
|
||||
);
|
||||
export const CREATE_MODEL_WITH_CLIENT_LABEL = s__(
|
||||
'MlModelRegistry|Creating models is also possible through the MLflow client. %{linkStart}Follow the documentation to learn more.%{linkEnd}',
|
||||
);
|
||||
export const NAME_LABEL = __('Name');
|
||||
|
||||
export const makeLoadVersionsErrorMessage = (message) =>
|
||||
sprintf(s__('MlModelRegistry|Failed to load model versions with error: %{message}'), {
|
||||
message,
|
||||
});
|
||||
|
||||
export const CREATE_MODEL_LINK_TITLE = s__('MlModelRegistry|Create model');
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
import { initBitbucketServerImportProjectForm } from '~/import/bitbucket_server';
|
||||
|
||||
initBitbucketServerImportProjectForm();
|
||||
|
|
@ -113,7 +113,7 @@ export default {
|
|||
|
||||
<template>
|
||||
<li
|
||||
class="gl-border-t gl-border-b gl-relative -gl-mt-px gl-flex gl-gap-3 gl-px-5 gl-py-3 hover:gl-z-1 has-[>a:hover]:gl-border-blue-200 has-[>a:hover]:gl-bg-blue-50"
|
||||
class="gl-border-t gl-border-b gl-relative -gl-mt-px gl-flex gl-gap-3 gl-px-5 gl-py-3 hover:gl-z-2 has-[>a:hover]:gl-border-blue-200 has-[>a:hover]:gl-bg-blue-50"
|
||||
:data-testid="`todo-item-${todo.id}`"
|
||||
:class="{ 'gl-bg-subtle': isDone }"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ const getFeedbackForElement = (feedbackMap, el) => {
|
|||
elMessage = el.getAttribute('validation-message');
|
||||
}
|
||||
|
||||
return field?.message || elMessage || el.validationMessage;
|
||||
return elMessage || field?.message || el.validationMessage;
|
||||
};
|
||||
|
||||
const focusFirstInvalidInput = (e) => {
|
||||
|
|
|
|||
|
|
@ -10,15 +10,24 @@ class JwksController < Doorkeeper::OpenidConnect::DiscoveryController
|
|||
private
|
||||
|
||||
def payload
|
||||
load_keys.flatten.compact.uniq.map { |key_data| pem_to_jwk(key_data) }
|
||||
end
|
||||
|
||||
# overridden in EE
|
||||
def load_keys
|
||||
[
|
||||
Rails.application.credentials.openid_connect_signing_key,
|
||||
Gitlab::CurrentSettings.ci_jwt_signing_key
|
||||
].compact.map do |key_data|
|
||||
OpenSSL::PKey::RSA.new(key_data)
|
||||
::Rails.application.credentials.openid_connect_signing_key,
|
||||
::Gitlab::CurrentSettings.ci_jwt_signing_key
|
||||
]
|
||||
end
|
||||
|
||||
def pem_to_jwk(key_data)
|
||||
OpenSSL::PKey::RSA.new(key_data)
|
||||
.public_key
|
||||
.to_jwk
|
||||
.slice(:kty, :kid, :e, :n)
|
||||
.merge(use: 'sig', alg: 'RS256')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
JwksController.prepend_mod
|
||||
|
|
|
|||
|
|
@ -162,8 +162,6 @@ class Projects::PipelinesController < Projects::ApplicationController
|
|||
@stage = pipeline.stage(params[:stage])
|
||||
return not_found unless @stage
|
||||
|
||||
return unless stage_stale?
|
||||
|
||||
render json: StageSerializer
|
||||
.new(project: @project, current_user: @current_user)
|
||||
.represent(@stage, details: true, retried: params[:retried])
|
||||
|
|
@ -270,14 +268,6 @@ class Projects::PipelinesController < Projects::ApplicationController
|
|||
redirect_to url_for(safe_params.except(:scope).merge(status: safe_params[:scope])), status: :moved_permanently
|
||||
end
|
||||
|
||||
def stage_stale?
|
||||
return true if Feature.disabled?(:pipeline_stage_set_last_modified, @current_user)
|
||||
|
||||
last_modified = [@stage.updated_at.utc, @stage.statuses.maximum(:updated_at)].max
|
||||
|
||||
stale?(last_modified: last_modified, etag: @stage)
|
||||
end
|
||||
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
def pipeline
|
||||
return @pipeline if defined?(@pipeline)
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ class PagesDeployment < ApplicationRecord
|
|||
|
||||
def restore
|
||||
update_attribute(:deleted_at, nil)
|
||||
deactivate_deployments_with_same_path_prefix
|
||||
end
|
||||
|
||||
private
|
||||
|
|
@ -121,6 +122,11 @@ class PagesDeployment < ApplicationRecord
|
|||
|
||||
update_column(:upload_ready, true)
|
||||
end
|
||||
|
||||
# Stop existing active deployment with same path when a deleted one is restored
|
||||
def deactivate_deployments_with_same_path_prefix
|
||||
project.pages_deployments.active.where.not(id: id).with_path_prefix(path_prefix).each(&:deactivate)
|
||||
end
|
||||
end
|
||||
|
||||
PagesDeployment.prepend_mod
|
||||
|
|
|
|||
|
|
@ -2,27 +2,33 @@
|
|||
- header_title _("New project"), new_project_path
|
||||
- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_project_path(anchor: 'import_project')
|
||||
|
||||
= render ::Layouts::PageHeadingComponent.new('') do |c|
|
||||
- c.with_heading do
|
||||
%span.gl-inline-flex.gl-items-center.gl-gap-3
|
||||
= sprite_icon('bitbucket', size: 32)
|
||||
= _('Import repositories from Bitbucket Server')
|
||||
- c.with_description do
|
||||
= _('Enter in your Bitbucket Server URL and personal access token below')
|
||||
- if Feature.enabled?(:new_project_creation_form, @user)
|
||||
#js-vue-import-bitbucket-server-project-root{ data: {
|
||||
back_button_path: new_project_path(anchor: 'import_project'),
|
||||
form_path: configure_import_bitbucket_server_path(namespace_id: params[:namespace_id])
|
||||
} }
|
||||
- else
|
||||
= render ::Layouts::PageHeadingComponent.new('') do |c|
|
||||
- c.with_heading do
|
||||
%span.gl-inline-flex.gl-items-center.gl-gap-3
|
||||
= sprite_icon('bitbucket', size: 32)
|
||||
= _('Import repositories from Bitbucket Server')
|
||||
- c.with_description do
|
||||
= _('Enter in your Bitbucket Server URL and personal access token below')
|
||||
|
||||
= form_tag configure_import_bitbucket_server_path(namespace_id: params[:namespace_id]), method: :post do
|
||||
.form-group.row
|
||||
= label_tag :bitbucket_server_url, 'Bitbucket Server URL', class: 'col-form-label col-md-2'
|
||||
.col-md-4
|
||||
= text_field_tag :bitbucket_server_url, '', class: 'form-control gl-form-input gl-mr-3', placeholder: _('https://your-bitbucket-server'), size: 40
|
||||
.form-group.row
|
||||
= label_tag :bitbucket_server_url, 'Username', class: 'col-form-label col-md-2'
|
||||
.col-md-4
|
||||
= text_field_tag :bitbucket_server_username, '', class: 'form-control gl-form-input gl-mr-3', placeholder: _('username'), size: 40
|
||||
.form-group.row
|
||||
= label_tag :personal_access_token, 'Password/Personal access token', class: 'col-form-label col-md-2'
|
||||
.col-md-4
|
||||
= password_field_tag :personal_access_token, '', class: 'form-control gl-form-input gl-mr-3', placeholder: _('Personal access token'), size: 40
|
||||
.col-sm-12.gl-mt-5
|
||||
= render Pajamas::ButtonComponent.new(type: 'submit', variant: :confirm) do
|
||||
= _('List your Bitbucket Server repositories')
|
||||
= form_tag configure_import_bitbucket_server_path(namespace_id: params[:namespace_id]), method: :post do
|
||||
.form-group.row
|
||||
= label_tag :bitbucket_server_url, 'Bitbucket Server URL', class: 'col-form-label col-md-2'
|
||||
.col-md-4
|
||||
= text_field_tag :bitbucket_server_url, '', class: 'form-control gl-form-input gl-mr-3', placeholder: _('https://your-bitbucket-server'), size: 40
|
||||
.form-group.row
|
||||
= label_tag :bitbucket_server_url, 'Username', class: 'col-form-label col-md-2'
|
||||
.col-md-4
|
||||
= text_field_tag :bitbucket_server_username, '', class: 'form-control gl-form-input gl-mr-3', placeholder: _('username'), size: 40
|
||||
.form-group.row
|
||||
= label_tag :personal_access_token, 'Password/Personal access token', class: 'col-form-label col-md-2'
|
||||
.col-md-4
|
||||
= password_field_tag :personal_access_token, '', class: 'form-control gl-form-input gl-mr-3', placeholder: _('Personal access token'), size: 40
|
||||
.col-sm-12.gl-mt-5
|
||||
= render Pajamas::ButtonComponent.new(type: 'submit', variant: :confirm) do
|
||||
= _('List your Bitbucket Server repositories')
|
||||
|
|
|
|||
|
|
@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/386275
|
|||
milestone: '15.7'
|
||||
type: development
|
||||
group: group::project management
|
||||
default_enabled: false
|
||||
default_enabled: true
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: pipeline_stage_set_last_modified
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/138499
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/433359
|
||||
milestone: '16.7'
|
||||
type: development
|
||||
group: group::global search
|
||||
default_enabled: false
|
||||
|
|
@ -5,4 +5,4 @@ feature_category: release_evidence
|
|||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/159580
|
||||
milestone: '17.3'
|
||||
queued_migration_version: 20240716133952
|
||||
finalized_by: # version of the migration that finalized this BBM
|
||||
finalized_by: '20250218231541'
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
class DropInvalidVulnerabilitiesGdk < Gitlab::Database::Migration[2.2]
|
||||
disable_ddl_transaction!
|
||||
restrict_gitlab_migration gitlab_schema: :gitlab_main
|
||||
restrict_gitlab_migration gitlab_schema: :gitlab_sec
|
||||
milestone '16.10'
|
||||
|
||||
class Vulnerability < MigrationRecord
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RemoveVirtualRegistriesPackagesMavenCacheEntriesFileFinalPath < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.10'
|
||||
disable_ddl_transaction!
|
||||
|
||||
TABLE_NAME = :virtual_registries_packages_maven_cache_entries
|
||||
COLUMN = :file_final_path
|
||||
|
||||
def up
|
||||
remove_column TABLE_NAME, COLUMN
|
||||
end
|
||||
|
||||
def down
|
||||
add_column TABLE_NAME, COLUMN, :text, if_not_exists: true
|
||||
|
||||
add_text_limit TABLE_NAME, COLUMN, 1024
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class FinalizeHkBackfillEvidencesProjectId < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.10'
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
restrict_gitlab_migration gitlab_schema: :gitlab_main_cell
|
||||
|
||||
def up
|
||||
ensure_batched_background_migration_is_finished(
|
||||
job_class_name: 'BackfillEvidencesProjectId',
|
||||
table_name: :evidences,
|
||||
column_name: :id,
|
||||
job_arguments: [:project_id, :releases, :project_id, :release_id],
|
||||
finalize: true
|
||||
)
|
||||
end
|
||||
|
||||
def down; end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
86024c9820b87fdbdef4271787ab0aa88f10d6283399a2cef507d7d2d9e268c2
|
||||
|
|
@ -0,0 +1 @@
|
|||
9bda2b766d3aa46184d8e5a199a934e883e9bbc918318b8090ecbe2fb03efddb
|
||||
|
|
@ -6360,14 +6360,12 @@ CREATE TABLE virtual_registries_packages_maven_cache_entries (
|
|||
object_storage_key text NOT NULL,
|
||||
upstream_etag text,
|
||||
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
|
||||
file_final_path text,
|
||||
file_md5 bytea,
|
||||
file_sha1 bytea NOT NULL,
|
||||
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
|
||||
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
|
||||
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
|
||||
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
|
||||
CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
|
||||
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
|
||||
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
|
||||
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
|
||||
|
|
@ -6388,14 +6386,12 @@ CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_en
|
|||
object_storage_key text NOT NULL,
|
||||
upstream_etag text,
|
||||
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
|
||||
file_final_path text,
|
||||
file_md5 bytea,
|
||||
file_sha1 bytea NOT NULL,
|
||||
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
|
||||
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
|
||||
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
|
||||
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
|
||||
CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
|
||||
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
|
||||
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
|
||||
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
|
||||
|
|
@ -6415,14 +6411,12 @@ CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_en
|
|||
object_storage_key text NOT NULL,
|
||||
upstream_etag text,
|
||||
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
|
||||
file_final_path text,
|
||||
file_md5 bytea,
|
||||
file_sha1 bytea NOT NULL,
|
||||
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
|
||||
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
|
||||
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
|
||||
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
|
||||
CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
|
||||
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
|
||||
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
|
||||
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
|
||||
|
|
@ -6442,14 +6436,12 @@ CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_en
|
|||
object_storage_key text NOT NULL,
|
||||
upstream_etag text,
|
||||
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
|
||||
file_final_path text,
|
||||
file_md5 bytea,
|
||||
file_sha1 bytea NOT NULL,
|
||||
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
|
||||
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
|
||||
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
|
||||
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
|
||||
CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
|
||||
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
|
||||
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
|
||||
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
|
||||
|
|
@ -6469,14 +6461,12 @@ CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_en
|
|||
object_storage_key text NOT NULL,
|
||||
upstream_etag text,
|
||||
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
|
||||
file_final_path text,
|
||||
file_md5 bytea,
|
||||
file_sha1 bytea NOT NULL,
|
||||
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
|
||||
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
|
||||
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
|
||||
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
|
||||
CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
|
||||
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
|
||||
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
|
||||
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
|
||||
|
|
@ -6496,14 +6486,12 @@ CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_en
|
|||
object_storage_key text NOT NULL,
|
||||
upstream_etag text,
|
||||
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
|
||||
file_final_path text,
|
||||
file_md5 bytea,
|
||||
file_sha1 bytea NOT NULL,
|
||||
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
|
||||
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
|
||||
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
|
||||
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
|
||||
CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
|
||||
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
|
||||
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
|
||||
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
|
||||
|
|
@ -6523,14 +6511,12 @@ CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_en
|
|||
object_storage_key text NOT NULL,
|
||||
upstream_etag text,
|
||||
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
|
||||
file_final_path text,
|
||||
file_md5 bytea,
|
||||
file_sha1 bytea NOT NULL,
|
||||
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
|
||||
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
|
||||
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
|
||||
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
|
||||
CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
|
||||
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
|
||||
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
|
||||
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
|
||||
|
|
@ -6550,14 +6536,12 @@ CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_en
|
|||
object_storage_key text NOT NULL,
|
||||
upstream_etag text,
|
||||
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
|
||||
file_final_path text,
|
||||
file_md5 bytea,
|
||||
file_sha1 bytea NOT NULL,
|
||||
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
|
||||
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
|
||||
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
|
||||
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
|
||||
CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
|
||||
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
|
||||
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
|
||||
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
|
||||
|
|
@ -6577,14 +6561,12 @@ CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_en
|
|||
object_storage_key text NOT NULL,
|
||||
upstream_etag text,
|
||||
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
|
||||
file_final_path text,
|
||||
file_md5 bytea,
|
||||
file_sha1 bytea NOT NULL,
|
||||
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
|
||||
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
|
||||
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
|
||||
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
|
||||
CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
|
||||
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
|
||||
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
|
||||
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
|
||||
|
|
@ -6604,14 +6586,12 @@ CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_en
|
|||
object_storage_key text NOT NULL,
|
||||
upstream_etag text,
|
||||
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
|
||||
file_final_path text,
|
||||
file_md5 bytea,
|
||||
file_sha1 bytea NOT NULL,
|
||||
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
|
||||
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
|
||||
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
|
||||
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
|
||||
CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
|
||||
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
|
||||
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
|
||||
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
|
||||
|
|
@ -6631,14 +6611,12 @@ CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_en
|
|||
object_storage_key text NOT NULL,
|
||||
upstream_etag text,
|
||||
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
|
||||
file_final_path text,
|
||||
file_md5 bytea,
|
||||
file_sha1 bytea NOT NULL,
|
||||
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
|
||||
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
|
||||
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
|
||||
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
|
||||
CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
|
||||
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
|
||||
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
|
||||
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
|
||||
|
|
@ -6658,14 +6636,12 @@ CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_en
|
|||
object_storage_key text NOT NULL,
|
||||
upstream_etag text,
|
||||
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
|
||||
file_final_path text,
|
||||
file_md5 bytea,
|
||||
file_sha1 bytea NOT NULL,
|
||||
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
|
||||
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
|
||||
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
|
||||
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
|
||||
CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
|
||||
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
|
||||
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
|
||||
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
|
||||
|
|
@ -6685,14 +6661,12 @@ CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_en
|
|||
object_storage_key text NOT NULL,
|
||||
upstream_etag text,
|
||||
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
|
||||
file_final_path text,
|
||||
file_md5 bytea,
|
||||
file_sha1 bytea NOT NULL,
|
||||
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
|
||||
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
|
||||
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
|
||||
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
|
||||
CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
|
||||
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
|
||||
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
|
||||
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
|
||||
|
|
@ -6712,14 +6686,12 @@ CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_en
|
|||
object_storage_key text NOT NULL,
|
||||
upstream_etag text,
|
||||
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
|
||||
file_final_path text,
|
||||
file_md5 bytea,
|
||||
file_sha1 bytea NOT NULL,
|
||||
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
|
||||
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
|
||||
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
|
||||
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
|
||||
CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
|
||||
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
|
||||
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
|
||||
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
|
||||
|
|
@ -6739,14 +6711,12 @@ CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_en
|
|||
object_storage_key text NOT NULL,
|
||||
upstream_etag text,
|
||||
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
|
||||
file_final_path text,
|
||||
file_md5 bytea,
|
||||
file_sha1 bytea NOT NULL,
|
||||
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
|
||||
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
|
||||
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
|
||||
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
|
||||
CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
|
||||
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
|
||||
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
|
||||
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
|
||||
|
|
@ -6766,14 +6736,12 @@ CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_en
|
|||
object_storage_key text NOT NULL,
|
||||
upstream_etag text,
|
||||
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
|
||||
file_final_path text,
|
||||
file_md5 bytea,
|
||||
file_sha1 bytea NOT NULL,
|
||||
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
|
||||
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
|
||||
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
|
||||
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
|
||||
CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
|
||||
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
|
||||
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
|
||||
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
|
||||
|
|
@ -6793,14 +6761,12 @@ CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_en
|
|||
object_storage_key text NOT NULL,
|
||||
upstream_etag text,
|
||||
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
|
||||
file_final_path text,
|
||||
file_md5 bytea,
|
||||
file_sha1 bytea NOT NULL,
|
||||
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
|
||||
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
|
||||
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
|
||||
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
|
||||
CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
|
||||
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
|
||||
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
|
||||
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
|
||||
|
|
|
|||
|
|
@ -246,7 +246,7 @@ and use it to automatically:
|
|||
|
||||
DORA metrics are displayed in the following analytics features:
|
||||
|
||||
- [Value Streams Dashboard](value_streams_dashboard.md) includes the [DORA metrics comparison panel](value_streams_dashboard.md#devsecops-metrics-comparison-panels) and [DORA Performers score panel](value_streams_dashboard.md#dora-performers-score-panel).
|
||||
- [Value Streams Dashboard](value_streams_dashboard.md) includes the [DORA metrics comparison panel](value_streams_dashboard.md#devsecops-metrics-comparison) and [DORA Performers score panel](value_streams_dashboard.md#dora-performers-score).
|
||||
- [CI/CD analytics charts](ci_cd_analytics.md) show the history of DORA metrics over time.
|
||||
- [Insights reports](../project/insights/_index.md) provide the option to create custom charts with [DORA query parameters](../project/insights/_index.md#dora-query-parameters).
|
||||
- [GraphQL API](../../api/graphql/reference/_index.md) (with the interactive [GraphQL explorer](../../api/graphql/_index.md#interactive-graphql-explorer)) and [REST API](../../api/dora/metrics.md) support the retrieval of metrics data.
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ For more information, see the [Value Stream Management category direction page](
|
|||
|
||||
The Value Streams Dashboard is a customizable dashboard you can use to identify trends, patterns, and opportunities for digital transformation improvements.
|
||||
The centralized UI in the Value Streams Dashboard acts as the single source of truth (SSOT), where all stakeholders can access and view the same set of metrics that are relevant to the organization.
|
||||
The Value Streams Dashboard includes [panels](#value-streams-dashboard-panels) that visualize the following metrics:
|
||||
The Value Streams Dashboard includes panels that visualize the following metrics:
|
||||
|
||||
- [DORA metrics](dora_metrics.md)
|
||||
- [Value Stream Analytics (VSA) - flow metrics](../group/value_stream_analytics/_index.md)
|
||||
|
|
@ -55,11 +55,11 @@ If you upgrade to the Ultimate tier, you get access to historical data, and can
|
|||
|
||||
{{< /alert >}}
|
||||
|
||||
## Value Streams Dashboard panels
|
||||
## Panels
|
||||
|
||||
The Value Streams Dashboard panels have a default configuration, but you can also [customize the dashboard panels](#customize-the-dashboard-panels).
|
||||
The Value Streams Dashboard panels have a default configuration, but you can also [customize the dashboard panels](#customize-dashboard-panels).
|
||||
|
||||
### Overview panel
|
||||
### Overview
|
||||
|
||||
{{< history >}}
|
||||
|
||||
|
|
@ -90,7 +90,7 @@ To view metrics on the Overview panel, the [background aggregation](#enable-or-d
|
|||
|
||||
{{< /alert >}}
|
||||
|
||||
### DevSecOps metrics comparison panels
|
||||
### DevSecOps metrics comparison
|
||||
|
||||
{{< history >}}
|
||||
|
||||
|
|
@ -120,7 +120,7 @@ The sparkline for the past six months represents value trends over this time per
|
|||
The sparkline color ranges from blue to green, where green indicates a positive trend, and blue indicates a negative trend.
|
||||
Sparklines help you identify patterns in metric trends (such as seasonal changes) over time.
|
||||
|
||||
#### Filter a DevSecOps metrics comparison panel by labels
|
||||
#### Filter panels by label
|
||||
|
||||
Label filters are appended as query parameters to the URL of the drill-down report of each eligible metric and automatically applied.
|
||||
If a comparison panel from the configuration file is enabled with `filters.labels`, the drill-down links inherit the labels from the panel filter.
|
||||
|
|
@ -143,7 +143,7 @@ Only labels that exactly match the specified filters are applied.
|
|||
|
||||
{{< /alert >}}
|
||||
|
||||
### DORA Performers score panel
|
||||
### DORA Performers score
|
||||
|
||||
{{< history >}}
|
||||
|
||||
|
|
@ -175,7 +175,7 @@ For example, if a project has a high score for deployment frequency (velocity),
|
|||
|
||||
To learn more, see the blog post [Inside DORA Performers score in GitLab Value Streams Dashboard](https://about.gitlab.com/blog/2024/01/18/inside-dora-performers-score-in-gitlab-value-streams-dashboard/).
|
||||
|
||||
#### Filter the DORA Performers score by project topics
|
||||
#### Filter the panel by project topic
|
||||
|
||||
When you customize dashboards with a YAML configuration,
|
||||
you can filter the displayed projects by assigned [topics](../project/project_topics.md).
|
||||
|
|
@ -240,13 +240,15 @@ To retrieve aggregated usage counts in the group, use the [GraphQL API](../../ap
|
|||
|
||||
## View the Value Streams Dashboard
|
||||
|
||||
### For groups
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- You must have at least the Reporter role for the group.
|
||||
- Overview background aggregation for Value Streams Dashboards must be enabled.
|
||||
- To view the contributor count metric in the comparison panel, you must [set up ClickHouse](../../integration/clickhouse.md).
|
||||
|
||||
To view the Value Streams Dashboard:
|
||||
To view the Value Streams Dashboard for a group:
|
||||
|
||||
- From Analytics Dashboards:
|
||||
|
||||
|
|
@ -260,7 +262,7 @@ To view the Value Streams Dashboard:
|
|||
1. Below the **Filter results** text box, in the **Lifecycle metrics** row, select **Value Streams Dashboard / DORA**.
|
||||
1. Optional. To open the new page, append this path `/analytics/dashboards/value_streams_dashboard` to the group URL (for example, `https://gitlab.com/groups/gitlab-org/-/analytics/dashboards/value_streams_dashboard`).
|
||||
|
||||
### View the Value Streams Dashboard for a project
|
||||
### For projects
|
||||
|
||||
{{< history >}}
|
||||
|
||||
|
|
@ -280,7 +282,7 @@ To view the Value Streams Dashboard as an analytics dashboard for a project:
|
|||
1. Select **Analyze > Analytics dashboards**.
|
||||
1. From the list of available dashboards, select **Value Streams Dashboard**.
|
||||
|
||||
### Schedule Value Streams Dashboard reports
|
||||
## Schedule reports
|
||||
|
||||
You can schedule reports using the CI/CD component
|
||||
[Value Streams Dashboard Scheduled Reports tool](https://gitlab.com/components/vsd-reports-generator).
|
||||
|
|
@ -294,7 +296,7 @@ The issue includes a comparison metrics table in Markdown format.
|
|||
|
||||
See an [example scheduled report](https://gitlab.com/components/vsd-reports-generator#example-for-monthly-executive-value-streams-report). To learn more, see the blog post [New Scheduled Reports Generation tool simplifies value stream management](https://about.gitlab.com/blog/2024/06/20/new-scheduled-reports-generation-tool-simplifies-value-stream-management/).
|
||||
|
||||
## Customize the dashboard panels
|
||||
## Customize dashboard panels
|
||||
|
||||
You can customize the Value Streams Dashboard and configure what subgroups and projects to include in the page.
|
||||
|
||||
|
|
@ -460,7 +462,7 @@ Filters for the `usage_overview` visualization.
|
|||
| Critical vulnerabilities over time | Critical vulnerabilities over time in project or group | [Vulnerability report](https://gitlab.com/gitlab-org/gitlab/-/security/vulnerability_report) | [Vulnerability report](../application_security/vulnerability_report/_index.md) | `vulnerability_critical` |
|
||||
| High vulnerabilities over time | High vulnerabilities over time in project or group | [Vulnerability report](https://gitlab.com/gitlab-org/gitlab/-/security/vulnerability_report) | [Vulnerability report](../application_security/vulnerability_report/_index.md) | `vulnerability_high` |
|
||||
|
||||
## Value Streams Dashboard metrics with Jira
|
||||
## Metrics with Jira
|
||||
|
||||
The following metrics do not depend on using Jira:
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ Use Pipeline execution policies to enforce CI/CD jobs for all applicable project
|
|||
{{< history >}}
|
||||
|
||||
- [Enabled](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/159858) the `suffix` field in GitLab 17.4.
|
||||
- [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/165096) pipeline execution so later stages wait for the `.pipeline-policy-pre` stage to complete in GitLab 17.7. [with a flag](../../../administration/feature_flags.md) named `ensure_pipeline_policy_pre_stage_complete`. Disabled by default.
|
||||
- [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/165096) pipeline execution so later stages wait for the `.pipeline-policy-pre` stage to complete in GitLab 17.7. [with a flag](../../../administration/feature_flags.md) named `ensure_pipeline_policy_pre_stage_complete`. Enabled by default.
|
||||
|
||||
{{< /history >}}
|
||||
|
||||
|
|
@ -401,7 +401,8 @@ the only jobs that run are the pipeline execution policy jobs.
|
|||
|
||||
{{< history >}}
|
||||
|
||||
- Updated handling of workflow rules [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/175088) in GitLab 17.8 [with a flag](../../../administration/feature_flags.md) named `policies_always_override_project_ci`. Enabled by default.
|
||||
- Updated handling of workflow rules [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/175088) in GitLab 17.8 [with a flag](../../../administration/feature_flags.md) named `policies_always_override_project_ci`. Enabled by default.
|
||||
- Updated handling of workflow rules [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/512877) in GitLab 17.10. Feature flag `policies_always_override_project_ci` removed.
|
||||
|
||||
{{< /history >}}
|
||||
|
||||
|
|
@ -504,14 +505,9 @@ ProjectVariablesYAML -- "Basis of the resulting pipeline" --> ResultingProjectVa
|
|||
|
||||
{{< alert type="note" >}}
|
||||
|
||||
When a pipeline execution policy uses workflow rules that prevent policy jobs from running, the
|
||||
project's original CI/CD configuration remains in effect instead of being overridden. You can
|
||||
conditionally apply pipeline execution policies to control when the policy impacts the project's
|
||||
CI/CD configuration. For example, if you set a workflow rule `if: $CI_PIPELINE_SOURCE ==
|
||||
"merge_request_event"`, the project's CI/CD configuration is only overridden when the pipeline source
|
||||
is a merge request event. However, if the feature flag `policies_always_override_project_ci` is enabled,
|
||||
the workflow rules in the pipeline execution policy also override the project's original CI/CD configuration.
|
||||
As a result, if workflow rules cause the pipeline execution policy to be filtered out, no pipeline is created.
|
||||
The workflow rules in the pipeline execution policy override the project's original CI/CD configuration.
|
||||
By defining workflow rules in the policy, you can set rules that are enforced across all linked projects,
|
||||
like preventing the use of branch pipelines.
|
||||
|
||||
{{< /alert >}}
|
||||
|
||||
|
|
|
|||
|
|
@ -228,8 +228,7 @@ Placeholder users are created per [import source](#supported-import-sources) and
|
|||
- If you import the same project twice, but to a different top-level group on the destination instance, the second import
|
||||
creates new placeholder users under that top-level group.
|
||||
|
||||
If importing to GitLab.com, placeholder users are limited per top-level group on the destination instance. The limits
|
||||
differ depending on your plan and seat count. Placeholder users do not count towards license limits.
|
||||
If importing to GitLab.com, placeholder users are limited per top-level group on the destination instance. The limits differ depending on your plan and seat count. Placeholder users do not count towards license limits.
|
||||
|
||||
| GitLab.com plan | Number of seats | Placeholder user limit on top-level group |
|
||||
|:-------------------------|:----------------|:------------------------------------------|
|
||||
|
|
@ -245,10 +244,29 @@ differ depending on your plan and seat count. Placeholder users do not count tow
|
|||
|
||||
Customers on legacy Bronze, Silver, or Gold plans have the corresponding Free, Premium, or Ultimate limits.
|
||||
For Premium customers trying out Ultimate (Ultimate trial paid customer plan), Premium limits apply.
|
||||
|
||||
If these limits are not sufficient for your import, [contact GitLab Support](https://about.gitlab.com/support/).
|
||||
|
||||
The above limits are for GitLab.com. GitLab Self-Managed has no placeholder limits by default. A self-managed instance administrator can [set a placeholder limit](../../../administration/instance_limits.md#import-placeholder-user-limits) for their installation.
|
||||
For GitLab Self-Managed and GitLab Dedicated, no placeholder limits apply by default.
|
||||
A GitLab administrator can [set a placeholder limit](../../../administration/instance_limits.md#import-placeholder-user-limits) on their instance.
|
||||
|
||||
For imports to GitLab.com, some contributions might not be created
|
||||
because these contributions are mapped to the same user.
|
||||
For example, if multiple merge request approvers are mapped to the same user,
|
||||
only the first approval is added and the others are ignored.
|
||||
These contributions include:
|
||||
|
||||
- Memberships
|
||||
- Merge request approvals, assignees, and reviewers
|
||||
- Issue assignees
|
||||
- Emoji
|
||||
- Push, merge request, and deploy access levels
|
||||
- Approval rules
|
||||
|
||||
You cannot determine the number of placeholder users you need in advance.
|
||||
When the placeholder user limit is reached, the import does not fail.
|
||||
Instead, all contributions are assigned to a bot user called `Import User`.
|
||||
|
||||
Every change creates a system note, which is not affected by the placeholder user limit.
|
||||
|
||||
### Reassign contributions and memberships
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,8 @@ module API
|
|||
send_snowplow_event = !!params[:send_to_snowplow]
|
||||
|
||||
if Gitlab::Tracking::AiTracking::EVENTS_MIGRATED_TO_INSTRUMENTATION_LAYER.exclude?(event_name)
|
||||
Gitlab::Tracking::AiTracking.track_event(event_name, **additional_properties.merge(user: current_user))
|
||||
Gitlab::Tracking::AiTracking.track_event(event_name,
|
||||
**additional_properties.merge(user: current_user, project_id: project_id, namespace_id: namespace_id))
|
||||
end
|
||||
|
||||
track_event(
|
||||
|
|
|
|||
|
|
@ -6993,9 +6993,14 @@ msgstr ""
|
|||
msgid "Analytics|Data table"
|
||||
msgstr ""
|
||||
|
||||
msgid "Analytics|Dates and times are displayed in the UTC timezone"
|
||||
msgid "Analytics|Dates and times are displayed in the UTC timezone."
|
||||
msgstr ""
|
||||
|
||||
msgid "Analytics|Dates and times are displayed in the UTC timezone. Date range is limited to %d day."
|
||||
msgid_plural "Analytics|Dates and times are displayed in the UTC timezone. Date range is limited to %d days."
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
msgid "Analytics|Default date range '%{defaultOption}' is not included in the list of dateRange options"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -19099,11 +19104,6 @@ msgstr ""
|
|||
msgid "Date range filter validation"
|
||||
msgstr ""
|
||||
|
||||
msgid "Date range limited to %d day"
|
||||
msgid_plural "Date range limited to %d days"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
msgid "Date range limited to %{number} days"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -36674,9 +36674,6 @@ msgstr ""
|
|||
msgid "MlModelRegistry|All artifact uploads failed or were canceled."
|
||||
msgstr ""
|
||||
|
||||
msgid "MlModelRegistry|An error has occurred when saving the model."
|
||||
msgstr ""
|
||||
|
||||
msgid "MlModelRegistry|Are you sure you want to delete this model version?"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -36737,9 +36734,6 @@ msgstr ""
|
|||
msgid "MlModelRegistry|Creating a model version"
|
||||
msgstr ""
|
||||
|
||||
msgid "MlModelRegistry|Creating models is also possible through the MLflow client. %{linkStart}Follow the documentation to learn more.%{linkEnd}"
|
||||
msgstr ""
|
||||
|
||||
msgid "MlModelRegistry|Creating models, model versions and runs is also possible using the MLflow client:"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -36815,6 +36809,9 @@ msgstr ""
|
|||
msgid "MlModelRegistry|Failed to load model runs with error: %{message}"
|
||||
msgstr ""
|
||||
|
||||
msgid "MlModelRegistry|Failed to load model version with error: %{message}"
|
||||
msgstr ""
|
||||
|
||||
msgid "MlModelRegistry|Failed to load model versions with error: %{message}"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -36830,18 +36827,12 @@ msgstr ""
|
|||
msgid "MlModelRegistry|For example 1.0.0"
|
||||
msgstr ""
|
||||
|
||||
msgid "MlModelRegistry|ID"
|
||||
msgstr ""
|
||||
|
||||
msgid "MlModelRegistry|Import model using MLflow"
|
||||
msgstr ""
|
||||
|
||||
msgid "MlModelRegistry|Import your machine learning models"
|
||||
msgstr ""
|
||||
|
||||
msgid "MlModelRegistry|Info"
|
||||
msgstr ""
|
||||
|
||||
msgid "MlModelRegistry|Latest version"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -36899,9 +36890,6 @@ msgstr ""
|
|||
msgid "MlModelRegistry|Must be unique. May not contain spaces."
|
||||
msgstr ""
|
||||
|
||||
msgid "MlModelRegistry|New model"
|
||||
msgstr ""
|
||||
|
||||
msgid "MlModelRegistry|New version"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -36911,9 +36899,6 @@ msgstr ""
|
|||
msgid "MlModelRegistry|No description available. To add a description, click \"Edit model\" above."
|
||||
msgstr ""
|
||||
|
||||
msgid "MlModelRegistry|No description provided"
|
||||
msgstr ""
|
||||
|
||||
msgid "MlModelRegistry|No logged artifacts."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -36977,9 +36962,6 @@ msgstr ""
|
|||
msgid "MlModelRegistry|Something went wrong while trying to delete the model version. Please try again later."
|
||||
msgstr ""
|
||||
|
||||
msgid "MlModelRegistry|Status"
|
||||
msgstr ""
|
||||
|
||||
msgid "MlModelRegistry|Step %{step}"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -46117,6 +46099,9 @@ msgstr ""
|
|||
msgid "ProjectsNew|Available only for projects within groups"
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectsNew|Bitbucket Server URL"
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectsNew|Choose a group"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -46186,6 +46171,9 @@ msgstr ""
|
|||
msgid "ProjectsNew|Import projects from Gitea"
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectsNew|Import repositories from Bitbucket Server"
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectsNew|Include a Getting Started README"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -46216,12 +46204,18 @@ msgstr ""
|
|||
msgid "ProjectsNew|No import options available"
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectsNew|Password/Personal access token"
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectsNew|Pick a group or namespace"
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectsNew|Pick a group or namespace where you want to create this project."
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectsNew|Please enter a valid Bitbucket Server URL."
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectsNew|Please enter a valid Gitea host URL."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -46234,6 +46228,12 @@ msgstr ""
|
|||
msgid "ProjectsNew|Please enter a valid project slug."
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectsNew|Please enter a valid token."
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectsNew|Please enter a valid username."
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectsNew|Please upload a valid GitLab project export file."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -53124,6 +53124,9 @@ msgstr ""
|
|||
msgid "SecurityReports|Attach to new issue"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityReports|Auto-resolve vulnerabilities that are no longer detected"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityReports|CVSS v%{version}:"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -53253,6 +53256,9 @@ msgstr ""
|
|||
msgid "SecurityReports|GitLab Duo (AI)"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityReports|Go to policies"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityReports|Group your vulnerabilities by one of the provided categories. Leave feedback or suggestions in %{feedbackIssueStart}this issue%{feedbackIssueEnd}."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -53477,6 +53483,9 @@ msgstr ""
|
|||
msgid "SecurityReports|This selection is required."
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityReports|To automatically resolve vulnerabilities when they are no longer detected by automated scanning, use the new auto-resolve option in your vulnerability management policies. From the %{boldStart}Policies%{boldEnd} page, configure a policy by applying the %{boldStart}Auto-resolve%{boldEnd} option and make sure the policy is linked to the appropriate projects. You can also configure the policy to auto-resolve only the vulnerabilities of a specific severity or from specific security scanners. See the %{linkStart}release post%{linkEnd} for details."
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityReports|To widen your search, change or remove filters above"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ RSpec.describe Import::BitbucketServerController, feature_category: :importers d
|
|||
end
|
||||
|
||||
before do
|
||||
stub_feature_flags(new_project_creation_form: false)
|
||||
sign_in(user)
|
||||
stub_application_setting(import_sources: ['bitbucket_server'])
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,117 @@
|
|||
import { nextTick } from 'vue';
|
||||
import { GlFormInput } from '@gitlab/ui';
|
||||
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import importFromBitbucketServerApp from '~/import/bitbucket_server/import_from_bitbucket_server_app.vue';
|
||||
import MultiStepFormTemplate from '~/vue_shared/components/multi_step_form_template.vue';
|
||||
|
||||
jest.mock('~/lib/utils/csrf', () => ({ token: 'mock-csrf-token' }));
|
||||
|
||||
describe('Import from Bitbucket Server app', () => {
|
||||
let wrapper;
|
||||
|
||||
const createComponent = () => {
|
||||
wrapper = shallowMountExtended(importFromBitbucketServerApp, {
|
||||
propsData: {
|
||||
backButtonPath: '/projects/new#import_project',
|
||||
formPath: '/import/bitbucket_server/configure',
|
||||
},
|
||||
stubs: {
|
||||
GlFormInput,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
createComponent();
|
||||
});
|
||||
|
||||
const findMultiStepForm = () => wrapper.findComponent(MultiStepFormTemplate);
|
||||
const findForm = () => wrapper.find('form');
|
||||
const findUrlInput = () => wrapper.findByTestId('url-input');
|
||||
const findUsernameInput = () => wrapper.findByTestId('username-input');
|
||||
const findTokenInput = () => wrapper.findByTestId('token-input');
|
||||
const findBackButton = () => wrapper.findByTestId('back-button');
|
||||
const findNextButton = () => wrapper.findByTestId('next-button');
|
||||
|
||||
describe('form', () => {
|
||||
it('renders the multi step form correctly', () => {
|
||||
expect(findMultiStepForm().props()).toMatchObject({
|
||||
currentStep: 3,
|
||||
stepsTotal: 4,
|
||||
});
|
||||
});
|
||||
|
||||
it('renders the form element correctly', () => {
|
||||
const form = findForm();
|
||||
|
||||
expect(form.attributes('action')).toBe('/import/bitbucket_server/configure');
|
||||
expect(form.find('input[type=hidden][name=authenticity_token]').attributes('value')).toBe(
|
||||
'mock-csrf-token',
|
||||
);
|
||||
});
|
||||
|
||||
it('does not submit the form without required fields', () => {
|
||||
const submitSpy = jest.spyOn(findForm().element, 'submit');
|
||||
|
||||
findForm().trigger('submit');
|
||||
expect(submitSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('submits the form with valid form data', async () => {
|
||||
const submitSpy = jest.spyOn(findForm().element, 'submit');
|
||||
|
||||
await findUrlInput().setValue('https://your-bitbucket-server');
|
||||
await findUsernameInput().setValue('username');
|
||||
await findTokenInput().setValue('863638293ddkdl29');
|
||||
await nextTick();
|
||||
|
||||
findForm().trigger('submit');
|
||||
expect(submitSpy).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('validation', () => {
|
||||
it('shows an error message when url is cleared', async () => {
|
||||
findUrlInput().setValue('');
|
||||
findUrlInput().trigger('blur');
|
||||
await nextTick();
|
||||
|
||||
const formGroup = wrapper.findByTestId('url-group');
|
||||
expect(formGroup.attributes('invalid-feedback')).toBe(
|
||||
'Please enter a valid Bitbucket Server URL.',
|
||||
);
|
||||
});
|
||||
|
||||
it('shows an error message when username is cleared', async () => {
|
||||
findUsernameInput().setValue('');
|
||||
findUsernameInput().trigger('blur');
|
||||
await nextTick();
|
||||
|
||||
const formGroup = wrapper.findByTestId('username-group');
|
||||
expect(formGroup.attributes('invalid-feedback')).toBe('Please enter a valid username.');
|
||||
});
|
||||
|
||||
it('shows an error message when token is cleared', async () => {
|
||||
findTokenInput().setValue('');
|
||||
findTokenInput().trigger('blur');
|
||||
await nextTick();
|
||||
|
||||
const formGroup = wrapper.findByTestId('token-group');
|
||||
expect(formGroup.attributes('invalid-feedback')).toBe('Please enter a valid token.');
|
||||
});
|
||||
});
|
||||
|
||||
describe('back button', () => {
|
||||
it('renders a back button', () => {
|
||||
expect(findBackButton().exists()).toBe(true);
|
||||
expect(findBackButton().attributes('href')).toBe('/projects/new#import_project');
|
||||
});
|
||||
});
|
||||
|
||||
describe('next button', () => {
|
||||
it('renders a button', () => {
|
||||
expect(findNextButton().exists()).toBe(true);
|
||||
expect(findNextButton().attributes('type')).toBe('submit');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -292,7 +292,7 @@ describe('ml/model_registry/apps/show_model_version.vue', () => {
|
|||
await waitForPromises();
|
||||
|
||||
expect(findLoadOrErrorOrShow().props('errorMessage')).toBe(
|
||||
'Failed to load model versions with error: Failure!',
|
||||
'Failed to load model version with error: Failure!',
|
||||
);
|
||||
expect(Sentry.captureException).toHaveBeenCalled();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,12 +2,6 @@ import { GlAvatarLabeled, GlLink, GlTableLite } from '@gitlab/ui';
|
|||
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import CandidateDetail from '~/ml/model_registry/components/candidate_detail.vue';
|
||||
import DetailRow from '~/ml/model_registry/components/candidate_detail_row.vue';
|
||||
import {
|
||||
NO_PARAMETERS_MESSAGE,
|
||||
NO_METRICS_MESSAGE,
|
||||
NO_METADATA_MESSAGE,
|
||||
NO_CI_MESSAGE,
|
||||
} from '~/ml/model_registry/translations';
|
||||
import { stubComponent } from 'helpers/stub_component';
|
||||
import { newCandidate } from '../mock_data';
|
||||
|
||||
|
|
@ -139,19 +133,19 @@ describe('ml/model_registry/components/candidate_detail.vue', () => {
|
|||
);
|
||||
|
||||
it('does not render params', () => {
|
||||
expect(findNoDataMessage(NO_PARAMETERS_MESSAGE).exists()).toBe(true);
|
||||
expect(findNoDataMessage('No logged parameters').exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('does not render metadata', () => {
|
||||
expect(findNoDataMessage(NO_METADATA_MESSAGE).exists()).toBe(true);
|
||||
expect(findNoDataMessage('No logged metadata').exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('does not render metrics', () => {
|
||||
expect(findNoDataMessage(NO_METRICS_MESSAGE).exists()).toBe(true);
|
||||
expect(findNoDataMessage('No logged metrics').exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('does not render CI info', () => {
|
||||
expect(findNoDataMessage(NO_CI_MESSAGE).exists()).toBe(true);
|
||||
expect(findNoDataMessage('Run not linked to a CI build').exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -280,6 +280,7 @@ describe('validation directive', () => {
|
|||
const feedbackMap = {
|
||||
valueMissing: {
|
||||
isInvalid: (el) => el.validity?.valueMissing,
|
||||
feedback: 'Please fill out the name field.',
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,13 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::BackgroundMigration::BackfillArchivedAndTraversalIdsToVulnerabilityStatistics, migration: :gitlab_sec, feature_category: :vulnerability_management do
|
||||
before(:all) do
|
||||
# Some spec in this file currently fails when a sec database is configured. We plan to ensure it all functions
|
||||
# and passes prior to the sec db rollout.
|
||||
# Consult https://gitlab.com/gitlab-org/gitlab/-/merge_requests/180764 for more info.
|
||||
skip_if_multiple_databases_are_setup(:sec)
|
||||
end
|
||||
|
||||
let(:organizations) { table(:organizations) }
|
||||
let(:namespaces) { table(:namespaces) }
|
||||
let(:projects) { table(:projects) }
|
||||
|
|
|
|||
|
|
@ -122,6 +122,13 @@ RSpec.describe Gitlab::BackgroundMigration::BackfillDetectedAtFromCreatedAtColum
|
|||
)
|
||||
end
|
||||
|
||||
before(:all) do
|
||||
# This test shares the db connection to establish it's fixtures, resulting in
|
||||
# incorrect connection usage, so we're skipping it.
|
||||
# Consult https://gitlab.com/gitlab-org/gitlab/-/merge_requests/180764 for more info.
|
||||
skip_if_multiple_databases_are_setup(:sec)
|
||||
end
|
||||
|
||||
before do
|
||||
# detected_at default value is NOW(), so update it to NULL
|
||||
vulnerability_without_detected_at.update_column :detected_at, nil
|
||||
|
|
|
|||
|
|
@ -46,6 +46,13 @@ RSpec.describe Gitlab::BackgroundMigration::BackfillMissingNamespaceIdOnNotes, f
|
|||
|
||||
let!(:user_1) { users_table.create!(name: 'bob', email: 'bob@example.com', projects_limit: 1) }
|
||||
|
||||
before do
|
||||
# This test shares the db connection to establish it's fixtures, resulting in
|
||||
# incorrect connection usage, so we're skipping it.
|
||||
# Consult https://gitlab.com/gitlab-org/gitlab/-/merge_requests/180764 for more info.
|
||||
skip_if_multiple_databases_are_setup(:sec)
|
||||
end
|
||||
|
||||
context "when namespace_id is derived from note.project_id" do
|
||||
let(:alert_management_alert_note) do
|
||||
notes_table.create!(project_id: project_1.id, noteable_type: "AlertManagement::Alert")
|
||||
|
|
|
|||
|
|
@ -27,6 +27,13 @@ RSpec.describe Gitlab::BackgroundMigration::BackfillProjectIdToDependencyListExp
|
|||
|
||||
subject(:perform_migration) { described_class.new(**args).perform }
|
||||
|
||||
before do
|
||||
# This test shares the db connection to establish it's fixtures, resulting in
|
||||
# incorrect connection usage, so we're skipping it.
|
||||
# Consult https://gitlab.com/gitlab-org/gitlab/-/merge_requests/180764 for more info.
|
||||
skip_if_multiple_databases_are_setup(:sec)
|
||||
end
|
||||
|
||||
context 'when export is missing project_id' do
|
||||
let!(:export) { dependency_list_exports.create!(pipeline_id: pipeline.id) }
|
||||
let!(:other_pipeline) { create_ci_pipeline('pipeline-2') }
|
||||
|
|
|
|||
|
|
@ -27,6 +27,13 @@ RSpec.describe Gitlab::BackgroundMigration::BackfillProjectIdToSecurityScans, fe
|
|||
|
||||
subject(:perform_migration) { described_class.new(**args).perform }
|
||||
|
||||
before do
|
||||
# This test shares the db connection to establish it's fixtures, resulting in
|
||||
# incorrect connection usage, so we're skipping it.
|
||||
# Consult https://gitlab.com/gitlab-org/gitlab/-/merge_requests/180764 for more info.
|
||||
skip_if_multiple_databases_are_setup(:sec)
|
||||
end
|
||||
|
||||
context 'when security_scan.build_id does not exist' do
|
||||
let!(:scan) do
|
||||
security_scans.create!(
|
||||
|
|
|
|||
|
|
@ -5,6 +5,13 @@ require 'spec_helper'
|
|||
RSpec.describe Gitlab::BackgroundMigration::BackfillVulnerabilityExternalIssueLinksProjectId,
|
||||
feature_category: :vulnerability_management,
|
||||
schema: 20240624135059 do
|
||||
before do
|
||||
# This test shares the db connection to establish it's fixtures, resulting in
|
||||
# incorrect connection usage, so we're skipping it.
|
||||
# Consult https://gitlab.com/gitlab-org/gitlab/-/merge_requests/180764 for more info.
|
||||
skip_if_multiple_databases_are_setup(:sec)
|
||||
end
|
||||
|
||||
include_examples 'desired sharding key backfill job' do
|
||||
let(:batch_table) { :vulnerability_external_issue_links }
|
||||
let(:backfill_column) { :project_id }
|
||||
|
|
|
|||
|
|
@ -5,6 +5,13 @@ require 'spec_helper'
|
|||
RSpec.describe Gitlab::BackgroundMigration::BackfillVulnerabilityOccurrenceIdentifiersProjectId,
|
||||
feature_category: :vulnerability_management,
|
||||
schema: 20240730171958 do
|
||||
before do
|
||||
# This test shares the db connection to establish it's fixtures, resulting in
|
||||
# incorrect connection usage, so we're skipping it.
|
||||
# Consult https://gitlab.com/gitlab-org/gitlab/-/merge_requests/180764 for more info.
|
||||
skip_if_multiple_databases_are_setup(:sec)
|
||||
end
|
||||
|
||||
include_examples 'desired sharding key backfill job' do
|
||||
let(:batch_table) { :vulnerability_occurrence_identifiers }
|
||||
let(:backfill_column) { :project_id }
|
||||
|
|
|
|||
|
|
@ -33,6 +33,11 @@ RSpec.describe Gitlab::BackgroundMigration::RemoveNamespaceFromOsTypeSbomCompone
|
|||
end
|
||||
|
||||
before do
|
||||
# This test shares the db connection to establish it's fixtures, resulting in
|
||||
# incorrect connection usage, so we're skipping it.
|
||||
# Consult https://gitlab.com/gitlab-org/gitlab/-/merge_requests/180764 for more info.
|
||||
skip_if_multiple_databases_are_setup(:sec)
|
||||
|
||||
os_prefix_to_purl_type_mapping.each.with_index do |(namespace, purl_type), index|
|
||||
components.create!(name: "#{namespace}/package-#{index}", purl_type: purl_type, component_type: 0)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -68,6 +68,13 @@ RSpec.describe Gitlab::BackgroundMigration::ResyncHasVulnerabilities, feature_ca
|
|||
|
||||
subject(:perform_migration) { described_class.new(**args).perform }
|
||||
|
||||
before do
|
||||
# This test shares the db connection to establish it's fixtures, resulting in
|
||||
# incorrect connection usage, so we're skipping it.
|
||||
# Consult https://gitlab.com/gitlab-org/gitlab/-/merge_requests/180764 for more info.
|
||||
skip_if_multiple_databases_are_setup(:sec)
|
||||
end
|
||||
|
||||
def create_project_setting(
|
||||
name,
|
||||
has_vulnerabilities_setting:,
|
||||
|
|
|
|||
|
|
@ -309,6 +309,11 @@ RSpec.describe Gitlab::Database::TablesLocker, :suppress_gitlab_schemas_validate
|
|||
subject { described_class.new.lock_writes }
|
||||
|
||||
before do
|
||||
# Some spec in this file currently fails when a sec database is configured. We plan to ensure it all functions
|
||||
# and passes prior to the sec db rollout.
|
||||
# Consult https://gitlab.com/gitlab-org/gitlab/-/issues/520270 for more info.
|
||||
skip_if_multiple_databases_are_setup(:sec)
|
||||
|
||||
allow(::Gitlab::Database).to receive(:db_config_share_with).and_return(nil)
|
||||
ci_db_config = Ci::ApplicationRecord.connection_db_config
|
||||
allow(::Gitlab::Database).to receive(:db_config_share_with).with(ci_db_config).and_return('main')
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe PagesDeployment, feature_category: :pages do
|
||||
using RSpec::Parameterized::TableSyntax
|
||||
let_it_be(:project) { create(:project) }
|
||||
|
||||
describe 'associations' do
|
||||
|
|
@ -232,5 +233,63 @@ RSpec.describe PagesDeployment, feature_category: :pages do
|
|||
expect { deployment.restore }
|
||||
.to change { deployment.deleted_at }.from(Time.zone.now).to(nil)
|
||||
end
|
||||
|
||||
context 'when restoring a deleted page deployment with path_prefix not nil', :freeze_time do
|
||||
let(:deleted_deployment) do
|
||||
create(:pages_deployment, project: project, deleted_at: Time.zone.now, path_prefix: 'test')
|
||||
end
|
||||
|
||||
let(:past_deactivation_date) { '2020-02-16' }
|
||||
|
||||
where(:path_prefix, :deleted_at) do
|
||||
'test2' | nil # active deployment with different path_prefix stays active
|
||||
'test' | ref(:past_deactivation_date) # stopped deployment with same path_prefix stays stopped
|
||||
'test2' | ref(:past_deactivation_date) # stopped deployment with different path_prefix stays stopped
|
||||
'' | nil # active deployment with no path_prefix stays active
|
||||
'' | ref(:past_deactivation_date) # stopped deployment with no path_prefix stays stopped
|
||||
end
|
||||
|
||||
with_them do
|
||||
it 'deactivate active deployment with diff paths and others stays the same' do
|
||||
deployment = create(:pages_deployment, project: project, path_prefix: path_prefix, deleted_at: deleted_at)
|
||||
expect { deleted_deployment.restore }
|
||||
.not_to change { deployment.reload.deleted_at }
|
||||
end
|
||||
end
|
||||
|
||||
it 'deactivate active deployment with same path_prefix' do
|
||||
active_deployment = create(:pages_deployment, project: project, path_prefix: 'test')
|
||||
expect { deleted_deployment.restore }
|
||||
.to change { active_deployment.reload.deleted_at }.from(nil).to(Time.zone.now)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when restoring a deleted page deployment with path_prefix nil', :freeze_time do
|
||||
let(:deleted_deployment) do
|
||||
create(:pages_deployment, project: project, deleted_at: Time.zone.now, path_prefix: '')
|
||||
end
|
||||
|
||||
let(:past_deactivation_date) { '2020-02-16' }
|
||||
|
||||
where(:path_prefix, :deleted_at) do
|
||||
'test2' | nil # active deployment with a path_prefix stays active
|
||||
'test2' | ref(:past_deactivation_date) # stopped deployment with a path_prefix stays stopped
|
||||
'' | ref(:past_deactivation_date) # stopped deployment with no path_prefix stays stopped
|
||||
end
|
||||
|
||||
with_them do
|
||||
it 'deactivate active deployment with diff paths and others stays the same' do
|
||||
deployment = create(:pages_deployment, project: project, path_prefix: path_prefix, deleted_at: deleted_at)
|
||||
expect { deleted_deployment.restore }
|
||||
.not_to change { deployment.reload.deleted_at }
|
||||
end
|
||||
end
|
||||
|
||||
it 'deactivate active deployment with same path_prefix' do
|
||||
active_deployment = create(:pages_deployment, project: project, path_prefix: '')
|
||||
expect { deleted_deployment.restore }
|
||||
.to change { active_deployment.reload.deleted_at }.from(nil).to(Time.zone.now)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -16,4 +16,28 @@ RSpec.describe JwksController, feature_category: :system_access do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '/oauth/discovery/keys' do
|
||||
include_context 'when doing OIDC key discovery'
|
||||
|
||||
it 'removes missing keys' do
|
||||
expect(Rails.application.credentials).to receive(:openid_connect_signing_key).and_return(rsa_key_1.to_pem)
|
||||
expect(Gitlab::CurrentSettings).to receive(:ci_jwt_signing_key).and_return(nil)
|
||||
|
||||
expect(jwks.size).to eq(1)
|
||||
expect(jwks).to match_array([
|
||||
satisfy { |jwk| key_match?(jwk, rsa_key_1) }
|
||||
])
|
||||
end
|
||||
|
||||
it 'removes duplicate keys' do
|
||||
expect(Rails.application.credentials).to receive(:openid_connect_signing_key).and_return(rsa_key_1.to_pem)
|
||||
expect(Gitlab::CurrentSettings).to receive(:ci_jwt_signing_key).and_return(rsa_key_1.to_pem)
|
||||
|
||||
expect(jwks.size).to eq(1)
|
||||
expect(jwks).to match_array([
|
||||
satisfy { |jwk| key_match?(jwk, rsa_key_1) }
|
||||
])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -75,57 +75,14 @@ RSpec.describe Projects::PipelinesController, feature_category: :continuous_inte
|
|||
expect(response).to have_gitlab_http_status(:ok)
|
||||
end
|
||||
|
||||
context 'when pipeline_stage_set_last_modified is disabled' do
|
||||
before do
|
||||
stub_feature_flags(pipeline_stage_set_last_modified: false)
|
||||
end
|
||||
it 'does not set Last-Modified' do
|
||||
create(:ci_build, :retried, :failed, pipeline: pipeline, stage: 'build')
|
||||
|
||||
it 'does not set Last-Modified' do
|
||||
create(:ci_build, :retried, :failed, pipeline: pipeline, stage: 'build')
|
||||
request_build_stage
|
||||
|
||||
request_build_stage
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(response.headers['Last-Modified']).to be_nil
|
||||
expect(response.headers['Cache-Control']).to eq('max-age=0, private, must-revalidate')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when pipeline_stage_set_last_modified is enabled' do
|
||||
before do
|
||||
stub_feature_flags(pipeline_stage_set_last_modified: true)
|
||||
stage.statuses.update_all(updated_at: status_timestamp)
|
||||
end
|
||||
|
||||
let(:last_modified) { DateTime.parse(response.headers['Last-Modified']).utc }
|
||||
let(:cache_control) { response.headers['Cache-Control'] }
|
||||
let(:expected_cache_control) { 'max-age=0, private, must-revalidate' }
|
||||
|
||||
context 'when status.updated_at is before stage.updated' do
|
||||
let(:stage) { pipeline.stage('build') }
|
||||
let(:status_timestamp) { stage.updated_at - 10.minutes }
|
||||
|
||||
it 'sets correct Last-Modified of stage.updated_at' do
|
||||
request_build_stage
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(last_modified).to be_within(1.second).of stage.updated_at
|
||||
expect(cache_control).to eq(expected_cache_control)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when status.updated_at is after stage.updated' do
|
||||
let(:stage) { pipeline.stage('build') }
|
||||
let(:status_timestamp) { stage.updated_at + 10.minutes }
|
||||
|
||||
it 'sets correct Last-Modified of max(status.updated_at)' do
|
||||
request_build_stage
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(last_modified).to be_within(1.second).of status_timestamp
|
||||
expect(cache_control).to eq(expected_cache_control)
|
||||
end
|
||||
end
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(response.headers['Last-Modified']).to be_nil
|
||||
expect(response.headers['Cache-Control']).to eq('max-age=0, private, must-revalidate')
|
||||
end
|
||||
|
||||
context 'with retried builds' do
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.shared_context 'when doing OIDC key discovery' do
|
||||
let_it_be(:rsa_key_1) { OpenSSL::PKey::RSA.new(2048) }
|
||||
let_it_be(:rsa_key_2) { OpenSSL::PKey::RSA.new(2048) }
|
||||
|
||||
subject(:jwks) do
|
||||
get '/oauth/discovery/keys'
|
||||
|
||||
jwks = Gitlab::Json.parse(response.body)
|
||||
jwks['keys'].map { |json| ::JWT::JWK.new(json) }
|
||||
end
|
||||
|
||||
def key_match?(jwk, private_key)
|
||||
jwk.public_key.to_pem == private_key.public_key.to_pem
|
||||
end
|
||||
end
|
||||
|
|
@ -122,6 +122,11 @@ RSpec.describe LooseForeignKeys::CleanupWorker, feature_category: :cell do
|
|||
end
|
||||
|
||||
it 'cleans up all rows' do
|
||||
# Some spec in this file currently fails when a sec database is configured. We plan to ensure it all functions
|
||||
# and passes prior to the sec db rollout.
|
||||
# Consult https://gitlab.com/gitlab-org/gitlab/-/issues/520270 for more info.
|
||||
skip_if_multiple_databases_are_setup(:sec)
|
||||
|
||||
perform_for(db: :main)
|
||||
|
||||
expect(loose_fk_child_table_1_1.count).to eq(0)
|
||||
|
|
@ -175,6 +180,13 @@ RSpec.describe LooseForeignKeys::CleanupWorker, feature_category: :cell do
|
|||
end
|
||||
|
||||
describe 'turbo mode' do
|
||||
before do
|
||||
# Some spec in this file currently fails when a sec database is configured. We plan to ensure it all functions
|
||||
# and passes prior to the sec db rollout.
|
||||
# Consult https://gitlab.com/gitlab-org/gitlab/-/issues/520270 for more info.
|
||||
skip_if_multiple_databases_are_setup(:sec)
|
||||
end
|
||||
|
||||
context 'when turbo mode is off' do
|
||||
where(:database_name, :feature_flag) do
|
||||
:main | :loose_foreign_keys_turbo_mode_main
|
||||
|
|
|
|||
Loading…
Reference in New Issue