Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
484f0959a2
commit
d57f7e7a39
18
.rubocop.yml
18
.rubocop.yml
|
|
@ -497,6 +497,24 @@ BackgroundMigration/DictionaryFile:
|
|||
Include:
|
||||
- 'db/post_migrate/*.rb'
|
||||
|
||||
# See https://gitlab.com/gitlab-org/gitlab/-/issues/442751
|
||||
Gitlab/AvoidCurrentOrganization:
|
||||
Enabled: true
|
||||
Exclude:
|
||||
- 'app/controllers/**/*'
|
||||
- 'ee/app/controllers/**/*'
|
||||
- 'app/helpers/**/*'
|
||||
- 'ee/app/helpers/**/*'
|
||||
- 'app/views/**/*'
|
||||
- 'ee/app/views/**/*'
|
||||
- 'lib/api/**/*'
|
||||
- 'ee/lib/api/**/*'
|
||||
- 'app/graphql/**/*'
|
||||
- 'ee/app/graphql/**/*'
|
||||
- 'lib/gitlab/middleware/organizations/current.rb'
|
||||
- 'spec/**/*'
|
||||
- 'ee/spec/**/*'
|
||||
|
||||
# See https://gitlab.com/groups/gitlab-org/-/epics/7374
|
||||
Gitlab/AvoidGitlabInstanceChecks:
|
||||
Enabled: true
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
Gitlab/AvoidCurrentOrganization:
|
||||
Details: grace period
|
||||
Exclude:
|
||||
- 'app/models/organizations/organization_setting.rb'
|
||||
- 'app/services/groups/create_service.rb'
|
||||
|
|
@ -941,22 +941,6 @@ Layout/ArgumentAlignment:
|
|||
- 'ee/spec/requests/api/projects_spec.rb'
|
||||
- 'ee/spec/requests/api/protected_environments_spec.rb'
|
||||
- 'ee/spec/requests/api/provider_identity_spec.rb'
|
||||
- 'ee/spec/requests/api/releases_spec.rb'
|
||||
- 'ee/spec/requests/api/search_spec.rb'
|
||||
- 'ee/spec/requests/api/settings_spec.rb'
|
||||
- 'ee/spec/requests/api/status_checks_spec.rb'
|
||||
- 'ee/spec/requests/api/visual_review_discussions_spec.rb'
|
||||
- 'ee/spec/requests/api/vulnerability_findings_spec.rb'
|
||||
- 'ee/spec/requests/ee/confirmations_controller_spec.rb'
|
||||
- 'ee/spec/requests/ee/projects/environments_controller_spec.rb'
|
||||
- 'ee/spec/requests/ee/projects/service_desk_controller_spec.rb'
|
||||
- 'ee/spec/requests/groups/epics/epic_links_controller_spec.rb'
|
||||
- 'ee/spec/requests/groups/epics/related_epic_links_controller_spec.rb'
|
||||
- 'ee/spec/requests/groups/protected_environments_controller_spec.rb'
|
||||
- 'ee/spec/requests/groups/settings/domain_verification_controller_spec.rb'
|
||||
- 'ee/spec/requests/groups/two_factor_auths_controller_spec.rb'
|
||||
- 'ee/spec/requests/smartcard_controller_spec.rb'
|
||||
- 'ee/spec/requests/users/identity_verification_controller_spec.rb'
|
||||
- 'ee/spec/services/gitlab_subscriptions/reconciliations/check_seat_usage_alerts_eligibility_service_spec.rb'
|
||||
- 'ee/spec/services/groups/compliance_report_csv_service_spec.rb'
|
||||
- 'ee/spec/services/groups/mark_for_deletion_service_spec.rb'
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script>
|
||||
import { GlIcon, GlLink } from '@gitlab/ui';
|
||||
import { n__, s__, sprintf } from '~/locale';
|
||||
import { formatDate } from '~/lib/utils/datetime_utility';
|
||||
import { getTimeago } from '~/lib/utils/datetime_utility';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
|
@ -39,14 +39,10 @@ export default {
|
|||
},
|
||||
},
|
||||
computed: {
|
||||
hasVersion() {
|
||||
return this.latestVersion;
|
||||
},
|
||||
lastReleaseText() {
|
||||
if (this.hasVersion) {
|
||||
return sprintf(this.$options.i18n.lastRelease, {
|
||||
date: this.createdAt,
|
||||
});
|
||||
if (this.latestVersion?.createdAt) {
|
||||
const timeAgo = getTimeago().format(this.latestVersion.createdAt);
|
||||
return sprintf(this.$options.i18n.lastRelease, { timeAgo });
|
||||
}
|
||||
|
||||
return this.$options.i18n.lastReleaseMissing;
|
||||
|
|
@ -57,9 +53,6 @@ export default {
|
|||
openMergeRequestText() {
|
||||
return n__('%d merge request', '%d merge requests', this.openMergeRequestsCount);
|
||||
},
|
||||
createdAt() {
|
||||
return this.hasVersion && formatDate(this.latestVersion.createdAt, 'yyyy-mm-dd');
|
||||
},
|
||||
projectInfoItems() {
|
||||
return [
|
||||
{
|
||||
|
|
@ -90,7 +83,7 @@ export default {
|
|||
},
|
||||
i18n: {
|
||||
projectLink: s__('CiCatalog|Go to the project'),
|
||||
lastRelease: s__('CiCatalog|Last release at %{date}'),
|
||||
lastRelease: s__('CiCatalog|Released %{timeAgo}'),
|
||||
lastReleaseMissing: s__('CiCatalog|No release available'),
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -54,6 +54,9 @@ query getPipelineHeaderData($fullPath: ID!, $iid: ID!) {
|
|||
configSource
|
||||
failureReason
|
||||
source
|
||||
yamlErrors
|
||||
yamlErrorMessages
|
||||
trigger
|
||||
...PipelineHeaderData
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import {
|
|||
import { BUTTON_TOOLTIP_RETRY, BUTTON_TOOLTIP_CANCEL } from '~/ci/constants';
|
||||
import { timeIntervalInWords } from '~/lib/utils/datetime_utility';
|
||||
import { setUrlFragment, redirectTo } from '~/lib/utils/url_utility'; // eslint-disable-line import/no-deprecated
|
||||
import { __, s__, sprintf, formatNumber } from '~/locale';
|
||||
import { __, n__, s__, sprintf, formatNumber } from '~/locale';
|
||||
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
|
||||
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
|
||||
import CiIcon from '~/vue_shared/components/ci_icon/ci_icon.vue';
|
||||
|
|
@ -134,17 +134,6 @@ export default {
|
|||
default: '',
|
||||
},
|
||||
},
|
||||
props: {
|
||||
yamlErrors: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
trigger: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
apollo: {
|
||||
pipeline: {
|
||||
context() {
|
||||
|
|
@ -249,8 +238,10 @@ export default {
|
|||
return this.pipeline?.commit?.title || '';
|
||||
},
|
||||
totalJobsText() {
|
||||
return sprintf(__('%{jobs} Jobs'), {
|
||||
jobs: this.pipeline?.totalJobs || 0,
|
||||
const totalJobs = this.pipeline?.totalJobs || 0;
|
||||
|
||||
return sprintf(n__('%{jobs} job', '%{jobs} jobs', totalJobs), {
|
||||
jobs: totalJobs,
|
||||
});
|
||||
},
|
||||
triggeredText() {
|
||||
|
|
@ -327,17 +318,14 @@ export default {
|
|||
isScheduledPipeline() {
|
||||
return this.pipeline.source === SCHEDULE_SOURCE;
|
||||
},
|
||||
isInvalidPipeline() {
|
||||
return Boolean(this.yamlErrors);
|
||||
},
|
||||
failureReason() {
|
||||
return this.pipeline.failureReason;
|
||||
},
|
||||
badges() {
|
||||
return {
|
||||
schedule: this.isScheduledPipeline,
|
||||
trigger: this.trigger,
|
||||
invalid: this.isInvalidPipeline,
|
||||
trigger: this.pipeline.trigger,
|
||||
invalid: this.pipeline.yamlErrors,
|
||||
child: this.pipeline.child,
|
||||
latest: this.pipeline.latest,
|
||||
mergeTrainPipeline: this.isMergeTrainPipeline,
|
||||
|
|
@ -348,6 +336,9 @@ export default {
|
|||
stuck: this.pipeline.stuck,
|
||||
};
|
||||
},
|
||||
yamlErrorMessages() {
|
||||
return this.pipeline?.yamlErrorMessages || '';
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
reportFailure(errorType, errorMessages = []) {
|
||||
|
|
@ -543,7 +534,7 @@ export default {
|
|||
<gl-badge
|
||||
v-if="badges.invalid"
|
||||
v-gl-tooltip
|
||||
:title="yamlErrors"
|
||||
:title="yamlErrorMessages"
|
||||
variant="danger"
|
||||
size="sm"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import Vue from 'vue';
|
||||
import VueApollo from 'vue-apollo';
|
||||
import { parseBoolean } from '~/lib/utils/common_utils';
|
||||
import PipelineDetailsHeader from './header/pipeline_details_header.vue';
|
||||
|
||||
Vue.use(VueApollo);
|
||||
|
|
@ -12,7 +11,7 @@ export const createPipelineDetailsHeaderApp = (elSelector, apolloProvider, graph
|
|||
return;
|
||||
}
|
||||
|
||||
const { fullPath, pipelineIid, pipelinesPath, yamlErrors, trigger } = el.dataset;
|
||||
const { fullPath, pipelineIid, pipelinesPath } = el.dataset;
|
||||
|
||||
// eslint-disable-next-line no-new
|
||||
new Vue({
|
||||
|
|
@ -28,12 +27,7 @@ export const createPipelineDetailsHeaderApp = (elSelector, apolloProvider, graph
|
|||
pipelineIid,
|
||||
},
|
||||
render(createElement) {
|
||||
return createElement(PipelineDetailsHeader, {
|
||||
props: {
|
||||
yamlErrors,
|
||||
trigger: parseBoolean(trigger),
|
||||
},
|
||||
});
|
||||
return createElement(PipelineDetailsHeader);
|
||||
},
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -62,8 +62,6 @@ export default {
|
|||
@close="onToggleDrawer(false)"
|
||||
/>
|
||||
|
||||
<gl-button :href="runnersPath" variant="confirm">{{
|
||||
s__('Runners|Go to runners page')
|
||||
}}</gl-button>
|
||||
<gl-button :href="runnersPath" variant="confirm">{{ s__('Runners|View runners') }}</gl-button>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,289 @@
|
|||
<script>
|
||||
import {
|
||||
GlButton,
|
||||
GlFormInput,
|
||||
GlFormGroup,
|
||||
GlLink,
|
||||
GlIcon,
|
||||
GlPopover,
|
||||
GlSprintf,
|
||||
} from '@gitlab/ui';
|
||||
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
|
||||
import { createAlert } from '~/alert';
|
||||
import { s__ } from '~/locale';
|
||||
import { convertToGraphQLId } from '~/graphql_shared/utils';
|
||||
import { TYPENAME_CI_RUNNER } from '~/graphql_shared/constants';
|
||||
import runnerForRegistrationQuery from '../../graphql/register/runner_for_registration.query.graphql';
|
||||
import {
|
||||
I18N_FETCH_ERROR,
|
||||
STATUS_ONLINE,
|
||||
RUNNER_REGISTRATION_POLLING_INTERVAL_MS,
|
||||
} from '../../constants';
|
||||
import { captureException } from '../../sentry_utils';
|
||||
|
||||
export default {
|
||||
name: 'GoogleCloudRegistrationInstructions',
|
||||
i18n: {
|
||||
heading: s__('Runners|Register runner'),
|
||||
headingDescription: s__(
|
||||
'Runners|After you complete the steps below, an autoscaling fleet of runners is available to execute your CI/CD jobs in Google Cloud. Based on demand, a runner manager automatically creates temporary runners.',
|
||||
),
|
||||
stepOneHeading: s__('Runners|Step 1: Specify environment'),
|
||||
stepOneDescription: s__(
|
||||
'Runners|Environment in Google Cloud where runners execute CI/CD jobs. Runners are created in temporary virtual machines based on demand.',
|
||||
),
|
||||
stepTwoHeading: s__('Runners|Step 2: Set up GitLab Runner'),
|
||||
stepTwoDescription: s__(
|
||||
'Runners|To view the setup instructions, complete the previous form. The instructions help you set up an autoscaling fleet of runners to execute your CI/CD jobs in Google Cloud.',
|
||||
),
|
||||
projectIdLabel: s__('Runners|Google Cloud project ID'),
|
||||
projectIdDescription: s__(
|
||||
'Runners|To improve security, use a dedicated project for CI/CD, separate from resources and identity management projects. %{linkStart}Where’s my project ID in Google Cloud?%{linkEnd}',
|
||||
),
|
||||
regionLabel: s__('Runners|Region'),
|
||||
regionHelpText: s__('Runners|Specific geographical location where you can run your resources.'),
|
||||
learnMore: s__('Runners|Learn more in the %{linkStart}Google Cloud documentation%{linkEnd}.'),
|
||||
zoneLabel: s__('Runners|Zone'),
|
||||
zoneHelpText: s__(
|
||||
'Runners|Isolated location within a region. The zone determines what computing resources are available and where your data is stored and used.',
|
||||
),
|
||||
zonesLinkText: s__('Runners|View available zones'),
|
||||
machineTypeLabel: s__('Runners|Machine type'),
|
||||
machineTypeHelpText: s__(
|
||||
'Runners|Machine type with preset amounts of virtual machines processors (vCPUs) and memory',
|
||||
),
|
||||
machineTypeDescription: s__(
|
||||
'Runners|For most CI/CD jobs, use a %{linkStart}N2D standard machine type.%{linkEnd}',
|
||||
),
|
||||
runnerSetupBtnText: s__('Runners|Setup instructions'),
|
||||
},
|
||||
links: {
|
||||
projectIdLink:
|
||||
'https://cloud.google.com/resource-manager/docs/creating-managing-projects#identifying_projects',
|
||||
regionAndZonesLink: 'https://cloud.google.com/compute/docs/regions-zones',
|
||||
zonesLink: 'https://console.cloud.google.com/compute/zones?pli=1',
|
||||
machineTypesLink:
|
||||
'https://cloud.google.com/compute/docs/general-purpose-machines#n2d_machine_types',
|
||||
},
|
||||
components: {
|
||||
ClipboardButton,
|
||||
GlButton,
|
||||
GlFormInput,
|
||||
GlFormGroup,
|
||||
GlIcon,
|
||||
GlLink,
|
||||
GlPopover,
|
||||
GlSprintf,
|
||||
},
|
||||
props: {
|
||||
runnerId: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
projectId: '',
|
||||
region: '',
|
||||
zone: '',
|
||||
machineType: 'n2d-standard-2',
|
||||
token: '',
|
||||
runner: null,
|
||||
};
|
||||
},
|
||||
apollo: {
|
||||
runner: {
|
||||
query: runnerForRegistrationQuery,
|
||||
variables() {
|
||||
return {
|
||||
id: convertToGraphQLId(TYPENAME_CI_RUNNER, this.runnerId),
|
||||
};
|
||||
},
|
||||
manual: true,
|
||||
result({ data }) {
|
||||
if (data?.runner) {
|
||||
const { ephemeralAuthenticationToken, ...runner } = data.runner;
|
||||
this.runner = runner;
|
||||
|
||||
// The token is available in the API for a limited amount of time
|
||||
// preserve its original value if it is missing after polling.
|
||||
this.token = ephemeralAuthenticationToken || this.token;
|
||||
}
|
||||
},
|
||||
error(error) {
|
||||
createAlert({ message: I18N_FETCH_ERROR });
|
||||
captureException({ error, component: this.$options.name });
|
||||
},
|
||||
pollInterval() {
|
||||
if (this.isRunnerOnline) {
|
||||
// stop polling
|
||||
return 0;
|
||||
}
|
||||
return RUNNER_REGISTRATION_POLLING_INTERVAL_MS;
|
||||
},
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
isRunnerOnline() {
|
||||
return this.runner?.status === STATUS_ONLINE;
|
||||
},
|
||||
tokenMessage() {
|
||||
if (this.token) {
|
||||
return s__(
|
||||
'Runners|The %{boldStart}runner authentication token%{boldEnd} %{token} displays here %{boldStart}for a short time only%{boldEnd}. After you register the runner, this token is stored in the %{codeStart}config.toml%{codeEnd} and cannot be accessed again from the UI.',
|
||||
);
|
||||
}
|
||||
return s__(
|
||||
'Runners|The %{boldStart}runner authentication token%{boldEnd} is no longer visible, it is stored in the %{codeStart}config.toml%{codeEnd} if you have registered the runner.',
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="gl-mb-2">
|
||||
<h1 class="gl-font-size-h1">{{ $options.i18n.heading }}</h1>
|
||||
<p>
|
||||
<gl-icon name="information-o" class="gl-text-blue-600!" />
|
||||
<gl-sprintf :message="tokenMessage">
|
||||
<template #token>
|
||||
<code data-testid="runner-token">{{ token }}</code>
|
||||
<clipboard-button
|
||||
:text="token"
|
||||
:title="__('Copy')"
|
||||
size="small"
|
||||
category="tertiary"
|
||||
class="gl-border-none!"
|
||||
/>
|
||||
</template>
|
||||
<template #bold="{ content }">
|
||||
<span class="gl-font-weight-bold">{{ content }}</span>
|
||||
</template>
|
||||
<template #code="{ content }">
|
||||
<code>{{ content }}</code>
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
</p>
|
||||
<p>{{ $options.i18n.headingDescription }}</p>
|
||||
</div>
|
||||
<hr />
|
||||
|
||||
<!-- start: step one -->
|
||||
<div class="gl-pb-4">
|
||||
<h2 class="gl-font-lg">{{ $options.i18n.stepOneHeading }}</h2>
|
||||
<p>{{ $options.i18n.stepOneDescription }}</p>
|
||||
</div>
|
||||
|
||||
<gl-form-group :label="$options.i18n.projectIdLabel" label-for="project-id">
|
||||
<template #description>
|
||||
<gl-sprintf :message="$options.i18n.projectIdDescription">
|
||||
<template #link="{ content }">
|
||||
<gl-link
|
||||
:href="$options.links.projectIdLink"
|
||||
target="_blank"
|
||||
data-testid="project-id-link"
|
||||
>
|
||||
{{ content }} <gl-icon name="external-link" />
|
||||
</gl-link>
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
</template>
|
||||
<gl-form-input
|
||||
id="project-id"
|
||||
v-model="projectId"
|
||||
type="text"
|
||||
data-testid="project-id-input"
|
||||
/>
|
||||
</gl-form-group>
|
||||
<gl-form-group label-for="region-id">
|
||||
<template #label>
|
||||
<div>
|
||||
{{ $options.i18n.regionLabel }}
|
||||
<gl-icon id="region-popover" class="gl-ml-2" name="question-o" />
|
||||
<gl-popover triggers="hover" placement="top" target="region-popover">
|
||||
<template #default>
|
||||
<p>{{ $options.i18n.regionHelpText }}</p>
|
||||
<gl-sprintf :message="$options.i18n.learnMore">
|
||||
<template #link="{ content }">
|
||||
<gl-link :href="$options.links.regionAndZonesLink" target="_blank">
|
||||
{{ content }} <gl-icon name="external-link" />
|
||||
</gl-link>
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
</template>
|
||||
</gl-popover>
|
||||
</div>
|
||||
</template>
|
||||
<gl-form-input id="region-id" v-model="region" data-testid="region-input" />
|
||||
</gl-form-group>
|
||||
<gl-form-group label-for="zone-id">
|
||||
<template #label>
|
||||
<div>
|
||||
{{ $options.i18n.zoneLabel }}
|
||||
<gl-icon id="zone-popover" class="gl-ml-2" name="question-o" />
|
||||
<gl-popover triggers="hover" placement="top" target="zone-popover">
|
||||
<template #default>
|
||||
<p>{{ $options.i18n.zoneHelpText }}</p>
|
||||
<gl-sprintf :message="$options.i18n.machineTypeDescription">
|
||||
<template #link="{ content }">
|
||||
<gl-link :href="$options.links.regionAndZonesLink" target="_blank">
|
||||
{{ content }} <gl-icon name="external-link" />
|
||||
</gl-link>
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
</template>
|
||||
</gl-popover>
|
||||
</div>
|
||||
</template>
|
||||
<template #description>
|
||||
<gl-link :href="$options.links.zonesLink" target="_blank" data-testid="zone-link">
|
||||
{{ $options.i18n.zonesLinkText }}
|
||||
<gl-icon name="external-link" />
|
||||
</gl-link>
|
||||
</template>
|
||||
<gl-form-input id="zone-id" v-model="zone" data-testid="zone-input" />
|
||||
</gl-form-group>
|
||||
<gl-form-group label-for="machine-type-id">
|
||||
<template #label>
|
||||
<div>
|
||||
{{ $options.i18n.machineTypeLabel }}
|
||||
<gl-icon id="machine-type-popover" class="gl-ml-2" name="question-o" />
|
||||
<gl-popover triggers="hover" placement="top" target="machine-type-popover">
|
||||
<template #default>
|
||||
{{ $options.i18n.machineTypeHelpText }}
|
||||
</template>
|
||||
</gl-popover>
|
||||
</div>
|
||||
</template>
|
||||
<template #description>
|
||||
<gl-sprintf :message="$options.i18n.machineTypeDescription">
|
||||
<template #link="{ content }">
|
||||
<gl-link
|
||||
:href="$options.links.machineTypesLink"
|
||||
target="_blank"
|
||||
data-testid="machine-types-link"
|
||||
>
|
||||
{{ content }} <gl-icon name="external-link" />
|
||||
</gl-link>
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
</template>
|
||||
<gl-form-input id="machine-type-id" v-model="machineType" data-testid="machine-type-input" />
|
||||
</gl-form-group>
|
||||
|
||||
<hr />
|
||||
<!-- end: step one -->
|
||||
|
||||
<!-- start: step two -->
|
||||
<div class="gl-pb-4">
|
||||
<h2 class="gl-font-lg">{{ $options.i18n.stepTwoHeading }}</h2>
|
||||
<p>{{ $options.i18n.stepTwoDescription }}</p>
|
||||
</div>
|
||||
<gl-button>{{ $options.i18n.runnerSetupBtnText }}</gl-button>
|
||||
|
||||
<hr />
|
||||
<!-- end: step two -->
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -1,105 +0,0 @@
|
|||
<script>
|
||||
import {
|
||||
GlAccordion,
|
||||
GlAccordionItem,
|
||||
GlButton,
|
||||
GlForm,
|
||||
GlFormGroup,
|
||||
GlFormInput,
|
||||
GlIcon,
|
||||
GlLink,
|
||||
} from '@gitlab/ui';
|
||||
import { s__ } from '~/locale';
|
||||
import CodeBlock from '~/vue_shared/components/code_block.vue';
|
||||
|
||||
export default {
|
||||
name: 'RunnerCloudForm',
|
||||
i18n: {
|
||||
title: s__('Runners|Google Cloud'),
|
||||
description: s__(
|
||||
'Runners|To improve security, use a dedicated project for CI/CD, separate from resources and identity management projects.',
|
||||
),
|
||||
docsLinkText: s__('Runners|Where’s my project ID in Google Cloud?'),
|
||||
projectIdLabel: s__('Runners|Google Cloud project ID'),
|
||||
helpText: s__('Runners|Project for the new runner.'),
|
||||
configurationLabel: s__('Runners|Configuration'),
|
||||
configurationHelpText: s__(
|
||||
"Runners|If you haven't already, configure your Google Cloud project to connect to this GitLab project and use the runner.",
|
||||
),
|
||||
accordionTitle: s__('Runners|Configuration instructions'),
|
||||
continueBtnText: s__('Runners|Continue to runner details'),
|
||||
},
|
||||
components: {
|
||||
CodeBlock,
|
||||
GlAccordion,
|
||||
GlAccordionItem,
|
||||
GlButton,
|
||||
GlForm,
|
||||
GlFormGroup,
|
||||
GlFormInput,
|
||||
GlIcon,
|
||||
GlLink,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
projectId: '',
|
||||
/* eslint-disable @gitlab/require-i18n-strings */
|
||||
configurationScript: `hello world.`,
|
||||
/* eslint-enable @gitlab/require-i18n-strings */
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<h2 class="gl-font-size-h2 gl-mb-5">{{ $options.i18n.title }}</h2>
|
||||
|
||||
<gl-form>
|
||||
<gl-form-group label-for="project-id">
|
||||
<template #label>
|
||||
<div class="gl-mb-3">{{ $options.i18n.projectIdLabel }}</div>
|
||||
<span class="gl-font-weight-normal">{{ $options.i18n.helpText }}</span>
|
||||
</template>
|
||||
<template #description>
|
||||
<span class="gl-display-block gl-mb-2">{{ $options.i18n.description }}</span>
|
||||
|
||||
<gl-link
|
||||
href="https://cloud.google.com/resource-manager/docs/creating-managing-projects#identifying_projects"
|
||||
target="_blank"
|
||||
>
|
||||
{{ $options.i18n.docsLinkText }}
|
||||
<gl-icon name="external-link" />
|
||||
</gl-link>
|
||||
</template>
|
||||
<gl-form-input
|
||||
id="project-id"
|
||||
v-model="projectId"
|
||||
type="text"
|
||||
data-testid="project-id-input"
|
||||
/>
|
||||
</gl-form-group>
|
||||
</gl-form>
|
||||
|
||||
<label>{{ $options.i18n.configurationLabel }}</label>
|
||||
<p>{{ $options.i18n.configurationHelpText }}</p>
|
||||
|
||||
<gl-accordion :header-level="3">
|
||||
<gl-accordion-item :title="$options.i18n.accordionTitle" :header-level="3" visible>
|
||||
<!-- TODO add configuration setup details https://gitlab.com/gitlab-org/gitlab/-/issues/439486 -->
|
||||
<code-block
|
||||
:code="configurationScript"
|
||||
class="gl-border-1 gl-border-solid gl-border-gray-200 gl-p-3!"
|
||||
/>
|
||||
</gl-accordion-item>
|
||||
</gl-accordion>
|
||||
|
||||
<gl-button
|
||||
class="gl-mt-5"
|
||||
variant="confirm"
|
||||
data-testid="continue-btn"
|
||||
@click="$emit('continue', projectId)"
|
||||
>
|
||||
{{ $options.i18n.continueBtnText }}
|
||||
</gl-button>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -1,200 +0,0 @@
|
|||
<script>
|
||||
import {
|
||||
GlCollapsibleListbox,
|
||||
GlFormGroup,
|
||||
GlLink,
|
||||
GlIcon,
|
||||
GlPopover,
|
||||
GlSprintf,
|
||||
} from '@gitlab/ui';
|
||||
import { s__ } from '~/locale';
|
||||
import RunnerCreateFormNew from '~/ci/runner/components/runner_create_form_new.vue';
|
||||
|
||||
import { PROJECT_TYPE, RUNNER_TYPES } from '../constants';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GlCollapsibleListbox,
|
||||
GlFormGroup,
|
||||
GlIcon,
|
||||
GlLink,
|
||||
GlPopover,
|
||||
GlSprintf,
|
||||
RunnerCreateFormNew,
|
||||
},
|
||||
props: {
|
||||
projectId: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
groupId: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
runnerType: {
|
||||
type: String,
|
||||
required: true,
|
||||
validator: (t) => RUNNER_TYPES.includes(t),
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
regions: [
|
||||
{
|
||||
text: 'us-central-1',
|
||||
value: 'us-central-1',
|
||||
},
|
||||
],
|
||||
selectedRegion: 'us-central-1',
|
||||
zones: [
|
||||
{
|
||||
text: 'us-central-1a',
|
||||
value: 'us-central-1a',
|
||||
},
|
||||
],
|
||||
selectedZone: 'us-central-1a',
|
||||
machineTypes: [
|
||||
{
|
||||
text: 'n2d-standard-2 (2 vCPU, 1 core, 8 GB memory)',
|
||||
value: 'n2d-standard-2 (2 vCPU, 1 core, 8 GB memory)',
|
||||
},
|
||||
],
|
||||
selectedMachineType: 'n2d-standard-2 (2 vCPU, 1 core, 8 GB memory)',
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
onSubmit(runnerDetails) {
|
||||
this.$emit('submit', {
|
||||
selectedRegion: this.selectedRegion,
|
||||
selectedZone: this.selectedZone,
|
||||
selectedMachineType: this.selectedMachineType,
|
||||
...runnerDetails,
|
||||
});
|
||||
},
|
||||
onPrevious(runnerDetails) {
|
||||
this.$emit('previous', {
|
||||
selectedRegion: this.selectedRegion,
|
||||
selectedZone: this.selectedZone,
|
||||
selectedMachineType: this.selectedMachineType,
|
||||
...runnerDetails,
|
||||
});
|
||||
},
|
||||
},
|
||||
i18n: {
|
||||
executionEnvironment: s__('Runners|Execution environment'),
|
||||
executionEnvironmentDescription: s__(
|
||||
'Runners|Runners are created based on demand, in temporary virtual machine (VM) instances. The VMs use the Google Container-Optimized OS and Docker Engine with support for auto-scaling',
|
||||
),
|
||||
regionLabel: s__('Runners|Region'),
|
||||
regionHelpText: s__('Runners|Specific geographical location where you can run your resources.'),
|
||||
zoneLabel: s__('Runners|Zone'),
|
||||
zoneHelpText: s__(
|
||||
'Runners|Isolated location within a region. The zone determines what computing resources are available and where your data is stored and used.',
|
||||
),
|
||||
machineTypeLabel: s__('Runners|Machine type'),
|
||||
machineTypeHelpText: s__(
|
||||
'Runners|Machine type with preset amounts of virtual machines processors (vCPUs) and memory',
|
||||
),
|
||||
learnMore: s__('Runners|Learn more in the %{linkStart}Google Cloud documentation%{linkEnd}.'),
|
||||
},
|
||||
links: {
|
||||
regionAndZonesLink: 'https://cloud.google.com/compute/docs/regions-zones',
|
||||
},
|
||||
PROJECT_TYPE,
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<div class="row gl-mx-0">
|
||||
<div class="col-8 gl-px-0">
|
||||
<h3>{{ $options.i18n.executionEnvironment }}</h3>
|
||||
<p>{{ $options.i18n.executionEnvironmentDescription }}</p>
|
||||
<gl-form-group label-for="region-id">
|
||||
<template #label>
|
||||
<div class="gl-mb-3">
|
||||
{{ $options.i18n.regionLabel
|
||||
}}<gl-icon id="region-popover" class="gl-ml-2" name="question-o" />
|
||||
<gl-popover triggers="hover" placement="top" target="region-popover">
|
||||
<template #default>
|
||||
<p>{{ $options.i18n.regionHelpText }}</p>
|
||||
<gl-sprintf :message="$options.i18n.learnMore">
|
||||
<template #link="{ content }">
|
||||
<gl-link :href="$options.links.regionAndZonesLink" target="_blank">
|
||||
{{ content }}<gl-icon name="external-link" />
|
||||
</gl-link>
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
</template>
|
||||
</gl-popover>
|
||||
</div>
|
||||
</template>
|
||||
<gl-collapsible-listbox
|
||||
id="region-id"
|
||||
:selected="selectedRegion"
|
||||
:items="regions"
|
||||
:toggle-text="selectedRegion"
|
||||
block
|
||||
data-testid="region-dropdown"
|
||||
/>
|
||||
</gl-form-group>
|
||||
<gl-form-group label-for="zone-id">
|
||||
<template #label>
|
||||
<div class="gl-mb-3">
|
||||
{{ $options.i18n.zoneLabel
|
||||
}}<gl-icon id="zone-popover" class="gl-ml-2" name="question-o" />
|
||||
<gl-popover triggers="hover" placement="top" target="zone-popover">
|
||||
<template #default>
|
||||
<p>{{ $options.i18n.zoneHelpText }}</p>
|
||||
<gl-sprintf :message="$options.i18n.learnMore">
|
||||
<template #link="{ content }">
|
||||
<gl-link :href="$options.links.regionAndZonesLink" target="_blank">
|
||||
{{ content }}<gl-icon name="external-link" />
|
||||
</gl-link>
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
</template>
|
||||
</gl-popover>
|
||||
</div>
|
||||
</template>
|
||||
<gl-collapsible-listbox
|
||||
:selected="selectedZone"
|
||||
:items="zones"
|
||||
:toggle-text="selectedZone"
|
||||
block
|
||||
data-testid="zone-dropdown"
|
||||
/>
|
||||
</gl-form-group>
|
||||
<gl-form-group label-for="machine-type-id">
|
||||
<template #label>
|
||||
<div class="gl-mb-3">
|
||||
{{ $options.i18n.machineTypeLabel
|
||||
}}<gl-icon id="machine-type-popover" class="gl-ml-2" name="question-o" />
|
||||
<gl-popover triggers="hover" placement="top" target="machine-type-popover">
|
||||
<template #default>
|
||||
{{ $options.i18n.machineTypeHelpText }}
|
||||
</template>
|
||||
</gl-popover>
|
||||
</div>
|
||||
</template>
|
||||
<gl-collapsible-listbox
|
||||
:selected="selectedMachineType"
|
||||
:items="machineTypes"
|
||||
:toggle-text="selectedMachineType"
|
||||
block
|
||||
data-testid="machine-type-dropdown"
|
||||
/>
|
||||
</gl-form-group>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row gl-mx-0">
|
||||
<runner-create-form-new
|
||||
:runner-type="runnerType"
|
||||
:group-id="groupId"
|
||||
@createRunner="onSubmit"
|
||||
@previous="onPrevious"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -1,93 +0,0 @@
|
|||
<script>
|
||||
import { GlForm, GlButton } from '@gitlab/ui';
|
||||
import RunnerFormFields from '~/ci/runner/components/runner_form_fields.vue';
|
||||
import { modelToUpdateMutationVariables } from 'ee_else_ce/ci/runner/runner_update_form_utils';
|
||||
import { RUNNER_TYPES, DEFAULT_ACCESS_LEVEL, PROJECT_TYPE, GROUP_TYPE } from '../constants';
|
||||
|
||||
export default {
|
||||
name: 'RunnerCreateForm',
|
||||
components: {
|
||||
GlForm,
|
||||
GlButton,
|
||||
RunnerFormFields,
|
||||
},
|
||||
props: {
|
||||
runnerType: {
|
||||
type: String,
|
||||
required: true,
|
||||
validator: (t) => RUNNER_TYPES.includes(t),
|
||||
},
|
||||
groupId: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
projectId: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
showPrevious: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
runner: {
|
||||
runnerType: this.runnerType,
|
||||
description: '',
|
||||
maintenanceNote: '',
|
||||
paused: false,
|
||||
accessLevel: DEFAULT_ACCESS_LEVEL,
|
||||
runUntagged: false,
|
||||
locked: false,
|
||||
tagList: '',
|
||||
maximumTimeout: '',
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
mutationInput() {
|
||||
const { input } = modelToUpdateMutationVariables(this.runner);
|
||||
|
||||
if (this.runnerType === GROUP_TYPE) {
|
||||
return {
|
||||
...input,
|
||||
groupId: this.groupId,
|
||||
};
|
||||
}
|
||||
if (this.runnerType === PROJECT_TYPE) {
|
||||
return {
|
||||
...input,
|
||||
projectId: this.projectId,
|
||||
};
|
||||
}
|
||||
return input;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onSubmit() {
|
||||
this.$emit('createRunner', this.mutationInput);
|
||||
},
|
||||
onPrevious() {
|
||||
this.$emit('previous', this.mutationInput);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<gl-form @submit.prevent="onSubmit">
|
||||
<runner-form-fields v-model="runner" :runner-type="runnerType" />
|
||||
|
||||
<div class="gl-display-flex gl-mt-6">
|
||||
<gl-button v-if="showPrevious" class="gl-mr-4" data-testid="back-button" @click="onPrevious">
|
||||
{{ __('Back') }}
|
||||
</gl-button>
|
||||
<gl-button type="submit" variant="confirm" class="js-no-auto-disable">
|
||||
{{ s__('Runners|Create runner') }}
|
||||
</gl-button>
|
||||
</div>
|
||||
</gl-form>
|
||||
</template>
|
||||
|
|
@ -7,18 +7,8 @@ import runnerCreateMutation from '~/ci/runner/graphql/new/runner_create.mutation
|
|||
import RegistrationCompatibilityAlert from '~/ci/runner/components/registration/registration_compatibility_alert.vue';
|
||||
import RunnerGoogleCloudOption from '~/ci/runner/components/runner_google_cloud_option.vue';
|
||||
import RunnerPlatformsRadioGroup from '~/ci/runner/components/runner_platforms_radio_group.vue';
|
||||
import RunnerCloudConnectionForm from '~/ci/runner/components/runner_cloud_connection_form.vue';
|
||||
import RunnerCloudExecutionEnvironment from '~/ci/runner/components/runner_cloud_execution_environment.vue';
|
||||
import RunnerCreateForm from '~/ci/runner/components/runner_create_form.vue';
|
||||
import {
|
||||
DEFAULT_PLATFORM,
|
||||
GOOGLE_CLOUD_PLATFORM,
|
||||
GOOGLE_CLOUD_SETUP_START,
|
||||
GOOGLE_CLOUD_SETUP_END,
|
||||
GROUP_TYPE,
|
||||
PARAM_KEY_PLATFORM,
|
||||
I18N_CREATE_ERROR,
|
||||
} from '../constants';
|
||||
import { DEFAULT_PLATFORM, GROUP_TYPE, PARAM_KEY_PLATFORM, I18N_CREATE_ERROR } from '../constants';
|
||||
import { saveAlertToLocalStorage } from '../local_storage_alert/save_alert_to_local_storage';
|
||||
|
||||
export default {
|
||||
|
|
@ -27,9 +17,7 @@ export default {
|
|||
RegistrationCompatibilityAlert,
|
||||
RunnerGoogleCloudOption,
|
||||
RunnerPlatformsRadioGroup,
|
||||
RunnerCloudConnectionForm,
|
||||
RunnerCreateForm,
|
||||
RunnerCloudExecutionEnvironment,
|
||||
},
|
||||
mixins: [glFeatureFlagsMixin()],
|
||||
props: {
|
||||
|
|
@ -41,28 +29,12 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
platform: DEFAULT_PLATFORM,
|
||||
googleCloudStage: GOOGLE_CLOUD_SETUP_START,
|
||||
cloudConnectionDetails: {},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
googleCloudProvisioningEnabled() {
|
||||
return this.glFeatures.googleCloudRunnerProvisioning;
|
||||
},
|
||||
showCloudForm() {
|
||||
return (
|
||||
this.platform === GOOGLE_CLOUD_PLATFORM &&
|
||||
this.googleCloudStage === GOOGLE_CLOUD_SETUP_START &&
|
||||
this.googleCloudProvisioningEnabled
|
||||
);
|
||||
},
|
||||
showCloudFormEnd() {
|
||||
return (
|
||||
this.platform === GOOGLE_CLOUD_PLATFORM &&
|
||||
this.googleCloudStage === GOOGLE_CLOUD_SETUP_END &&
|
||||
this.googleCloudProvisioningEnabled
|
||||
);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async createRunner(runnerInfo) {
|
||||
|
|
@ -108,14 +80,6 @@ export default {
|
|||
onError(error) {
|
||||
createAlert({ message: error.message });
|
||||
},
|
||||
onContinueGoogleCloud(cloudConnection) {
|
||||
// Store the variables from the start of the form
|
||||
this.cloudConnectionDetails = cloudConnection;
|
||||
this.googleCloudStage = GOOGLE_CLOUD_SETUP_END;
|
||||
},
|
||||
onPrevious() {
|
||||
this.googleCloudStage = GOOGLE_CLOUD_SETUP_START;
|
||||
},
|
||||
},
|
||||
GROUP_TYPE,
|
||||
};
|
||||
|
|
@ -149,18 +113,7 @@ export default {
|
|||
|
||||
<hr aria-hidden="true" />
|
||||
|
||||
<runner-cloud-connection-form v-if="showCloudForm" @continue="onContinueGoogleCloud" />
|
||||
|
||||
<runner-cloud-execution-environment
|
||||
v-else-if="showCloudFormEnd"
|
||||
:runner-type="$options.GROUP_TYPE"
|
||||
:group-id="groupId"
|
||||
@submit="createRunner"
|
||||
@previous="onPrevious"
|
||||
/>
|
||||
|
||||
<runner-create-form
|
||||
v-else
|
||||
:runner-type="$options.GROUP_TYPE"
|
||||
:group-id="groupId"
|
||||
@saved="onSaved"
|
||||
|
|
|
|||
|
|
@ -1,17 +1,21 @@
|
|||
<script>
|
||||
import { GlButton } from '@gitlab/ui';
|
||||
import { getParameterByName, updateHistory, mergeUrlParams } from '~/lib/utils/url_utility';
|
||||
import { PARAM_KEY_PLATFORM, DEFAULT_PLATFORM } from '../constants';
|
||||
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||
import { PARAM_KEY_PLATFORM, DEFAULT_PLATFORM, GOOGLE_CLOUD_PLATFORM } from '../constants';
|
||||
import RegistrationInstructions from '../components/registration/registration_instructions.vue';
|
||||
import GoogleCloudRegistrationInstructions from '../components/registration/google_cloud_registration_instructions.vue';
|
||||
import PlatformsDrawer from '../components/registration/platforms_drawer.vue';
|
||||
|
||||
export default {
|
||||
name: 'GroupRegisterRunnerApp',
|
||||
components: {
|
||||
GoogleCloudRegistrationInstructions,
|
||||
GlButton,
|
||||
RegistrationInstructions,
|
||||
PlatformsDrawer,
|
||||
},
|
||||
mixins: [glFeatureFlagsMixin()],
|
||||
props: {
|
||||
runnerId: {
|
||||
type: String,
|
||||
|
|
@ -28,6 +32,13 @@ export default {
|
|||
isDrawerOpen: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
showGoogleCloudRegistration() {
|
||||
return (
|
||||
this.glFeatures.googleCloudRunnerProvisioning && this.platform === GOOGLE_CLOUD_PLATFORM
|
||||
);
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
platform(platform) {
|
||||
updateHistory({
|
||||
|
|
@ -47,23 +58,26 @@ export default {
|
|||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<registration-instructions
|
||||
:runner-id="runnerId"
|
||||
:platform="platform"
|
||||
@toggleDrawer="onToggleDrawer"
|
||||
>
|
||||
<template #runner-list-name>{{ s__('Runners|Group area › Runners') }}</template>
|
||||
</registration-instructions>
|
||||
<template v-if="showGoogleCloudRegistration">
|
||||
<google-cloud-registration-instructions :runner-id="runnerId" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<registration-instructions
|
||||
:runner-id="runnerId"
|
||||
:platform="platform"
|
||||
@toggleDrawer="onToggleDrawer"
|
||||
>
|
||||
<template #runner-list-name>{{ s__('Runners|Group area › Runners') }}</template>
|
||||
</registration-instructions>
|
||||
|
||||
<platforms-drawer
|
||||
:platform="platform"
|
||||
:open="isDrawerOpen"
|
||||
@selectPlatform="onSelectPlatform"
|
||||
@close="onToggleDrawer(false)"
|
||||
/>
|
||||
<platforms-drawer
|
||||
:platform="platform"
|
||||
:open="isDrawerOpen"
|
||||
@selectPlatform="onSelectPlatform"
|
||||
@close="onToggleDrawer(false)"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<gl-button :href="runnersPath" variant="confirm">{{
|
||||
s__('Runners|Go to runners page')
|
||||
}}</gl-button>
|
||||
<gl-button :href="runnersPath" variant="confirm">{{ s__('Runners|View runners') }}</gl-button>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -7,15 +7,11 @@ import runnerCreateMutation from '~/ci/runner/graphql/new/runner_create.mutation
|
|||
import RegistrationCompatibilityAlert from '~/ci/runner/components/registration/registration_compatibility_alert.vue';
|
||||
import RunnerGoogleCloudOption from '~/ci/runner/components/runner_google_cloud_option.vue';
|
||||
import RunnerPlatformsRadioGroup from '~/ci/runner/components/runner_platforms_radio_group.vue';
|
||||
import RunnerCloudConnectionForm from '~/ci/runner/components/runner_cloud_connection_form.vue';
|
||||
import RunnerCloudExecutionEnvironment from '~/ci/runner/components/runner_cloud_execution_environment.vue';
|
||||
import RunnerCreateForm from '~/ci/runner/components/runner_create_form.vue';
|
||||
import {
|
||||
DEFAULT_PLATFORM,
|
||||
PARAM_KEY_PLATFORM,
|
||||
GOOGLE_CLOUD_PLATFORM,
|
||||
GOOGLE_CLOUD_SETUP_START,
|
||||
GOOGLE_CLOUD_SETUP_END,
|
||||
PROJECT_TYPE,
|
||||
I18N_CREATE_ERROR,
|
||||
} from '../constants';
|
||||
|
|
@ -28,8 +24,6 @@ export default {
|
|||
RegistrationCompatibilityAlert,
|
||||
RunnerGoogleCloudOption,
|
||||
RunnerPlatformsRadioGroup,
|
||||
RunnerCloudConnectionForm,
|
||||
RunnerCloudExecutionEnvironment,
|
||||
RunnerCreateForm,
|
||||
},
|
||||
mixins: [glFeatureFlagsMixin()],
|
||||
|
|
@ -42,28 +36,12 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
platform: DEFAULT_PLATFORM,
|
||||
googleCloudStage: GOOGLE_CLOUD_SETUP_START,
|
||||
cloudConnectionDetails: {},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
googleCloudProvisioningEnabled() {
|
||||
return this.glFeatures.googleCloudRunnerProvisioning;
|
||||
},
|
||||
showCloudForm() {
|
||||
return (
|
||||
this.platform === GOOGLE_CLOUD_PLATFORM &&
|
||||
this.googleCloudStage === GOOGLE_CLOUD_SETUP_START &&
|
||||
this.googleCloudProvisioningEnabled
|
||||
);
|
||||
},
|
||||
showCloudFormEnd() {
|
||||
return (
|
||||
this.platform === GOOGLE_CLOUD_PLATFORM &&
|
||||
this.googleCloudStage === GOOGLE_CLOUD_SETUP_END &&
|
||||
this.googleCloudProvisioningEnabled
|
||||
);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async createRunner(runnerInfo) {
|
||||
|
|
@ -112,14 +90,6 @@ export default {
|
|||
}
|
||||
createAlert({ message: error.message });
|
||||
},
|
||||
onContinueGoogleCloud(cloudConnection) {
|
||||
// Store the variables from the start of the form
|
||||
this.cloudConnectionDetails = cloudConnection;
|
||||
this.googleCloudStage = GOOGLE_CLOUD_SETUP_END;
|
||||
},
|
||||
onPrevious() {
|
||||
this.googleCloudStage = GOOGLE_CLOUD_SETUP_START;
|
||||
},
|
||||
},
|
||||
PROJECT_TYPE,
|
||||
GOOGLE_CLOUD_PLATFORM,
|
||||
|
|
@ -154,18 +124,7 @@ export default {
|
|||
|
||||
<hr aria-hidden="true" />
|
||||
|
||||
<runner-cloud-connection-form v-if="showCloudForm" @continue="onContinueGoogleCloud" />
|
||||
|
||||
<runner-cloud-execution-environment
|
||||
v-else-if="showCloudFormEnd"
|
||||
:runner-type="$options.PROJECT_TYPE"
|
||||
:project-id="projectId"
|
||||
@submit="createRunner"
|
||||
@previous="onPrevious"
|
||||
/>
|
||||
|
||||
<runner-create-form
|
||||
v-else
|
||||
:runner-type="$options.PROJECT_TYPE"
|
||||
:project-id="projectId"
|
||||
@saved="onSaved"
|
||||
|
|
|
|||
|
|
@ -1,17 +1,21 @@
|
|||
<script>
|
||||
import { GlButton } from '@gitlab/ui';
|
||||
import { getParameterByName, updateHistory, mergeUrlParams } from '~/lib/utils/url_utility';
|
||||
import { PARAM_KEY_PLATFORM, DEFAULT_PLATFORM } from '../constants';
|
||||
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||
import { PARAM_KEY_PLATFORM, DEFAULT_PLATFORM, GOOGLE_CLOUD_PLATFORM } from '../constants';
|
||||
import RegistrationInstructions from '../components/registration/registration_instructions.vue';
|
||||
import GoogleCloudRegistrationInstructions from '../components/registration/google_cloud_registration_instructions.vue';
|
||||
import PlatformsDrawer from '../components/registration/platforms_drawer.vue';
|
||||
|
||||
export default {
|
||||
name: 'ProjectRegisterRunnerApp',
|
||||
components: {
|
||||
GoogleCloudRegistrationInstructions,
|
||||
GlButton,
|
||||
RegistrationInstructions,
|
||||
PlatformsDrawer,
|
||||
},
|
||||
mixins: [glFeatureFlagsMixin()],
|
||||
props: {
|
||||
runnerId: {
|
||||
type: String,
|
||||
|
|
@ -28,6 +32,13 @@ export default {
|
|||
isDrawerOpen: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
showGoogleCloudRegistration() {
|
||||
return (
|
||||
this.glFeatures.googleCloudRunnerProvisioning && this.platform === GOOGLE_CLOUD_PLATFORM
|
||||
);
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
platform(platform) {
|
||||
updateHistory({
|
||||
|
|
@ -47,23 +58,28 @@ export default {
|
|||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<registration-instructions
|
||||
:runner-id="runnerId"
|
||||
:platform="platform"
|
||||
@toggleDrawer="onToggleDrawer"
|
||||
>
|
||||
<template #runner-list-name>{{ s__('Runners|Project › CI/CD Settings › Runners') }}</template>
|
||||
</registration-instructions>
|
||||
<template v-if="showGoogleCloudRegistration">
|
||||
<google-cloud-registration-instructions :runner-id="runnerId" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<registration-instructions
|
||||
:runner-id="runnerId"
|
||||
:platform="platform"
|
||||
@toggleDrawer="onToggleDrawer"
|
||||
>
|
||||
<template #runner-list-name>{{
|
||||
s__('Runners|Project › CI/CD Settings › Runners')
|
||||
}}</template>
|
||||
</registration-instructions>
|
||||
|
||||
<platforms-drawer
|
||||
:platform="platform"
|
||||
:open="isDrawerOpen"
|
||||
@selectPlatform="onSelectPlatform"
|
||||
@close="onToggleDrawer(false)"
|
||||
/>
|
||||
<platforms-drawer
|
||||
:platform="platform"
|
||||
:open="isDrawerOpen"
|
||||
@selectPlatform="onSelectPlatform"
|
||||
@close="onToggleDrawer(false)"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<gl-button :href="runnersPath" variant="confirm">{{
|
||||
s__('Runners|Go to runners page')
|
||||
}}</gl-button>
|
||||
<gl-button :href="runnersPath" variant="confirm">{{ s__('Runners|View runners') }}</gl-button>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -58,6 +58,9 @@
|
|||
"GoogleCloudArtifactRegistryArtifact": [
|
||||
"GoogleCloudArtifactRegistryDockerImage"
|
||||
],
|
||||
"GoogleCloudArtifactRegistryArtifactDetails": [
|
||||
"GoogleCloudArtifactRegistryDockerImageDetails"
|
||||
],
|
||||
"GoogleCloudLoggingConfigurationInterface": [
|
||||
"GoogleCloudLoggingConfigurationType",
|
||||
"InstanceGoogleCloudLoggingConfigurationType"
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
|||
after_action :verify_known_sign_in
|
||||
|
||||
protect_from_forgery except: [:failure] + AuthHelper.saml_providers, with: :exception, prepend: true
|
||||
before_action :log_saml_response, only: [:saml]
|
||||
|
||||
feature_category :system_access
|
||||
|
||||
|
|
@ -39,6 +40,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
|||
# the number of failed sign in attempts
|
||||
def failure
|
||||
update_login_counter_metric(failed_strategy.name, 'failed')
|
||||
log_saml_response if params['SAMLResponse']
|
||||
|
||||
if params[:username].present? && AuthHelper.form_based_provider?(failed_strategy.name)
|
||||
user = User.find_by_login(params[:username])
|
||||
|
|
@ -357,6 +359,10 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
|||
session.delete(:provider_2FA)
|
||||
end
|
||||
end
|
||||
|
||||
def log_saml_response
|
||||
Gitlab::AuthLogger.info(payload_type: 'saml_response', saml_response: ParameterFilters::SamlResponse.filter(params['SAMLResponse'].dup))
|
||||
end
|
||||
end
|
||||
|
||||
OmniauthCallbacksController.prepend_mod_with('OmniauthCallbacksController')
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ module Types
|
|||
value 'LATEST_RELEASED_AT_DESC', 'Latest release date by descending order.', value: :latest_released_at_desc
|
||||
value 'CREATED_ASC', 'Created date by ascending order.', value: :created_at_asc
|
||||
value 'CREATED_DESC', 'Created date by descending order.', value: :created_at_desc
|
||||
value 'STAR_COUNT_ASC', 'Star count by ascending order.', value: :star_count_asc
|
||||
value 'STAR_COUNT_DESC', 'Star count by descending order.', value: :star_count_desc
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -30,9 +30,7 @@ module Projects
|
|||
full_path: project.full_path,
|
||||
graphql_resource_etag: graphql_etag_pipeline_path(pipeline),
|
||||
pipeline_iid: pipeline.iid,
|
||||
pipelines_path: project_pipelines_path(project),
|
||||
yaml_errors: pipeline.yaml_errors,
|
||||
trigger: pipeline.trigger?.to_s
|
||||
pipelines_path: project_pipelines_path(project)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ module Ci
|
|||
when 'latest_released_at_asc' then relation.order_by_latest_released_at_asc
|
||||
when 'created_at_asc' then relation.order_by_created_at_asc
|
||||
when 'created_at_desc' then relation.order_by_created_at_desc
|
||||
when 'star_count_asc' then relation.order_by_star_count(:asc)
|
||||
else
|
||||
relation.order_by_star_count(:desc)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ class Event < ApplicationRecord
|
|||
|
||||
RESET_PROJECT_ACTIVITY_INTERVAL = 1.hour
|
||||
REPOSITORY_UPDATED_AT_INTERVAL = 5.minutes
|
||||
CONTRIBUTABLE_TARGET_TYPES = %w[MergeRequest Issue WorkItem].freeze
|
||||
|
||||
sha_attribute :fingerprint
|
||||
|
||||
|
|
@ -93,16 +94,14 @@ class Event < ApplicationRecord
|
|||
scope :created_between, ->(start_time, end_time) { where(created_at: start_time..end_time) }
|
||||
scope :count_by_dates, ->(date_interval) { group("DATE(created_at + #{date_interval})").count }
|
||||
|
||||
scope :contributions, -> do
|
||||
scope :contributions, ->(target_types: nil) do
|
||||
contribution_actions = [actions[:pushed], actions[:commented]]
|
||||
|
||||
contributable_target_types = %w[MergeRequest Issue WorkItem]
|
||||
target_contribution_actions = [actions[:created], actions[:closed], actions[:merged], actions[:approved]]
|
||||
|
||||
where(
|
||||
'action IN (?) OR (target_type IN (?) AND action IN (?))',
|
||||
contribution_actions,
|
||||
contributable_target_types, target_contribution_actions
|
||||
target_types || contributable_target_types, target_contribution_actions
|
||||
)
|
||||
end
|
||||
|
||||
|
|
@ -145,6 +144,10 @@ class Event < ApplicationRecord
|
|||
end
|
||||
end
|
||||
|
||||
def contributable_target_types
|
||||
CONTRIBUTABLE_TARGET_TYPES
|
||||
end
|
||||
|
||||
def limit_recent(limit = 20, offset = nil)
|
||||
recent.limit(limit).offset(offset)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ module WithPagination
|
|||
#
|
||||
# we shouldn't try to paginate single resources
|
||||
def represent(resource, opts = {})
|
||||
if paginated? && resource.respond_to?(:page)
|
||||
if paginated? && (resource.respond_to?(:page) || resource.respond_to?(:cursor_for_next_page))
|
||||
super(paginator.paginate(resource), opts)
|
||||
else
|
||||
super(resource, opts)
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@
|
|||
%strong
|
||||
- if event.project
|
||||
= link_to_project(event.project)
|
||||
- elsif event.group
|
||||
= link_to_group(event.group)
|
||||
- else
|
||||
= event.resource_parent_name
|
||||
- else
|
||||
|
|
|
|||
|
|
@ -230,6 +230,7 @@ module Gitlab
|
|||
sharedSecret
|
||||
redirect
|
||||
question
|
||||
SAMLResponse
|
||||
]
|
||||
|
||||
# This config option can be removed after Rails 7.1 by https://gitlab.com/gitlab-org/gitlab/-/issues/416270
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
name: epic_events_on_contributions_calendar
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/138688
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/434527
|
||||
milestone: '16.10'
|
||||
type: development
|
||||
group: group::tenant scale
|
||||
default_enabled: false
|
||||
|
|
@ -197,14 +197,12 @@
|
|||
- 1
|
||||
- - compliance_management_standards_adherence_export_mailer
|
||||
- 1
|
||||
- - compliance_management_standards_base
|
||||
- 1
|
||||
- - compliance_management_standards_gitlab_at_least_two_approvals
|
||||
- 1
|
||||
- - compliance_management_standards_gitlab_at_least_two_approvals_group
|
||||
- 1
|
||||
- - compliance_management_standards_gitlab_base
|
||||
- 1
|
||||
- - compliance_management_standards_gitlab_group_base
|
||||
- 1
|
||||
- - compliance_management_standards_gitlab_prevent_approval_by_author
|
||||
- 1
|
||||
- - compliance_management_standards_gitlab_prevent_approval_by_author_group
|
||||
|
|
@ -213,8 +211,14 @@
|
|||
- 1
|
||||
- - compliance_management_standards_gitlab_prevent_approval_by_committer_group
|
||||
- 1
|
||||
- - compliance_management_standards_group_base
|
||||
- 1
|
||||
- - compliance_management_standards_refresh
|
||||
- 1
|
||||
- - compliance_management_standards_soc2_at_least_one_non_author_approval
|
||||
- 1
|
||||
- - compliance_management_standards_soc2_at_least_one_non_author_approval_group
|
||||
- 1
|
||||
- - compliance_management_update_default_framework
|
||||
- 1
|
||||
- - compliance_management_violation_export_mailer
|
||||
|
|
@ -777,6 +781,8 @@
|
|||
- 1
|
||||
- - vulnerability_exports_export_deletion
|
||||
- 1
|
||||
- - vulnerability_external_issue_links_update_vulnerability_read
|
||||
- 1
|
||||
- - web_hook
|
||||
- 1
|
||||
- - web_hooks_log_destroy
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddOccupiesSeatToMemberRole < Gitlab::Database::Migration[2.2]
|
||||
milestone '16.10'
|
||||
|
||||
def change
|
||||
add_column :member_roles, :occupies_seat, :boolean, default: false, null: false
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddIndexToOccupiesSeatOnMemberRole < Gitlab::Database::Migration[2.2]
|
||||
milestone '16.10'
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
INDEX_NAME = 'index_member_roles_on_occupies_seat'
|
||||
|
||||
def up
|
||||
add_concurrent_index :member_roles, :occupies_seat, name: INDEX_NAME
|
||||
end
|
||||
|
||||
def down
|
||||
remove_concurrent_index_by_name :member_roles, name: INDEX_NAME
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
ad12c9cea9e63231e6926e331624e106617572afeddc95032da058f1c9bf56a7
|
||||
|
|
@ -0,0 +1 @@
|
|||
a044a9d56648bc0944b61e12dc9715074b03ec9b5de9b9447b6798c263e8db0b
|
||||
|
|
@ -10670,6 +10670,7 @@ CREATE TABLE member_roles (
|
|||
remove_project boolean DEFAULT false NOT NULL,
|
||||
admin_terraform_state boolean DEFAULT false NOT NULL,
|
||||
admin_cicd_variables boolean DEFAULT false NOT NULL,
|
||||
occupies_seat boolean DEFAULT false NOT NULL,
|
||||
CONSTRAINT check_4364846f58 CHECK ((char_length(description) <= 255)),
|
||||
CONSTRAINT check_9907916995 CHECK ((char_length(name) <= 255))
|
||||
);
|
||||
|
|
@ -25491,6 +25492,8 @@ CREATE INDEX index_member_approval_on_reviewed_by_id ON member_approvals USING b
|
|||
|
||||
CREATE INDEX index_member_roles_on_namespace_id ON member_roles USING btree (namespace_id);
|
||||
|
||||
CREATE INDEX index_member_roles_on_occupies_seat ON member_roles USING btree (occupies_seat);
|
||||
|
||||
CREATE INDEX index_members_on_access_level ON members USING btree (access_level);
|
||||
|
||||
CREATE INDEX index_members_on_expires_at ON members USING btree (expires_at);
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/46391) in GitLab 11.9.
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
GitLab integrates with [LDAP - Lightweight Directory Access Protocol](https://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol)
|
||||
to support user authentication.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
If you are an administrator, use the following information to troubleshoot LDAP.
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
If you have [configured LDAP to work with GitLab](index.md), GitLab can automatically synchronize
|
||||
users and groups.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
GitLab supports authentication using smart cards.
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ description: "GitLab administrator: enable and disable GitLab features deployed
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
GitLab adopted [feature flags strategies](../development/feature_flags/index.md)
|
||||
to deploy features in an early stage of development so that they can be
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
GitLab supports and automates housekeeping tasks in Git repositories to ensure
|
||||
that they can be served as efficiently as possible. Housekeeping tasks include:
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
GitLab has several features based on receiving incoming email messages:
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
GitLab provides Rake tasks to check the integrity of various components.
|
||||
See also the [check GitLab configuration Rake task](maintenance.md#check-gitlab-configuration).
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/390690) in GitLab 15.9, Rake task no longer automatically creates namespaces or groups that don't exist.
|
||||
> - Requirement for Maintainer role instead of Developer role introduced in GitLab 16.0 and backported to GitLab 15.11.1 and GitLab 15.10.5.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
The following are LDAP-related Rake tasks.
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
GitLab provides Rake tasks for general maintenance.
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28369) in GitLab 12.10.
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
GitLab provides Rake tasks for [project import and export](../../user/project/settings/import_export.md).
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/108279) in GitLab 15.9.
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67802) in GitLab 14.2.
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
There is a Rake task for migrating uploads between different storage types.
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
In GitLab 11.9 and later, EXIF data is automatically stripped from JPG or TIFF image uploads.
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
GitLab can be set up to allow users to comment on issues and merge requests by
|
||||
replying to notification emails.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/196051) in GitLab 12.8 replacing Custom Hooks.
|
||||
> - [Renamed](https://gitlab.com/gitlab-org/gitlab/-/issues/372991) from server hooks to Git server hooks in GitLab 15.6.
|
||||
|
|
|
|||
|
|
@ -386,6 +386,26 @@ Whether Gitpod is enabled in application settings.
|
|||
|
||||
Returns [`Boolean`](#boolean).
|
||||
|
||||
### `Query.googleCloudArtifactRegistryRepositoryArtifact`
|
||||
|
||||
Details about an artifact in the Google Cloud Artifact Registry.
|
||||
|
||||
DETAILS:
|
||||
**Introduced** in GitLab 16.10.
|
||||
**Status**: Experiment.
|
||||
|
||||
Returns [`GoogleCloudArtifactRegistryArtifactDetails`](#googlecloudartifactregistryartifactdetails).
|
||||
|
||||
#### Arguments
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="querygooglecloudartifactregistryrepositoryartifactgooglecloudprojectid"></a>`googleCloudProjectId` | [`String!`](#string) | ID of the Google Cloud project. |
|
||||
| <a id="querygooglecloudartifactregistryrepositoryartifactimage"></a>`image` | [`String!`](#string) | Name of the image in the Google Cloud Artifact Registry. |
|
||||
| <a id="querygooglecloudartifactregistryrepositoryartifactlocation"></a>`location` | [`String!`](#string) | Location of the Artifact Registry repository. |
|
||||
| <a id="querygooglecloudartifactregistryrepositoryartifactprojectpath"></a>`projectPath` | [`ID!`](#id) | Full project path. |
|
||||
| <a id="querygooglecloudartifactregistryrepositoryartifactrepository"></a>`repository` | [`String!`](#string) | Repository on the Google Cloud Artifact Registry. |
|
||||
|
||||
### `Query.group`
|
||||
|
||||
Find a group.
|
||||
|
|
@ -19932,20 +19952,35 @@ Represents a docker artifact of Google Cloud Artifact Registry.
|
|||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="googlecloudartifactregistrydockerimageartifactregistryimageurl"></a>`artifactRegistryImageUrl` | [`String!`](#string) | Google Cloud URL to access the image. |
|
||||
| <a id="googlecloudartifactregistrydockerimagebuildtime"></a>`buildTime` | [`Time`](#time) | Time when the image was built. |
|
||||
| <a id="googlecloudartifactregistrydockerimagedigest"></a>`digest` | [`String!`](#string) | Image's digest. |
|
||||
| <a id="googlecloudartifactregistrydockerimageimage"></a>`image` | [`String!`](#string) | Image's name. |
|
||||
| <a id="googlecloudartifactregistrydockerimageimagesizebytes"></a>`imageSizeBytes` | [`String`](#string) | Calculated size of the image. |
|
||||
| <a id="googlecloudartifactregistrydockerimagelocation"></a>`location` | [`String!`](#string) | Location of the Artifact Registry repository. |
|
||||
| <a id="googlecloudartifactregistrydockerimagemediatype"></a>`mediaType` | [`String`](#string) | Media type of the image. |
|
||||
| <a id="googlecloudartifactregistrydockerimagename"></a>`name` | [`String!`](#string) | Unique image name. |
|
||||
| <a id="googlecloudartifactregistrydockerimageprojectid"></a>`projectId` | [`String!`](#string) | ID of the Google Cloud project. |
|
||||
| <a id="googlecloudartifactregistrydockerimagerepository"></a>`repository` | [`String!`](#string) | Repository on the Google Cloud Artifact Registry. |
|
||||
| <a id="googlecloudartifactregistrydockerimagetags"></a>`tags` | [`[String!]`](#string) | Tags attached to the image. |
|
||||
| <a id="googlecloudartifactregistrydockerimageupdatetime"></a>`updateTime` | [`Time`](#time) | Time when the image was last updated. |
|
||||
| <a id="googlecloudartifactregistrydockerimageuploadtime"></a>`uploadTime` | [`Time`](#time) | Time when the image was uploaded. |
|
||||
| <a id="googlecloudartifactregistrydockerimageuri"></a>`uri` | [`String!`](#string) | Google Cloud URI to access the image. |
|
||||
|
||||
### `GoogleCloudArtifactRegistryDockerImageDetails`
|
||||
|
||||
Represents details about docker artifact of Google Cloud Artifact Registry.
|
||||
|
||||
#### Fields
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="googlecloudartifactregistrydockerimagedetailsartifactregistryimageurl"></a>`artifactRegistryImageUrl` | [`String!`](#string) | Google Cloud URL to access the image. |
|
||||
| <a id="googlecloudartifactregistrydockerimagedetailsbuildtime"></a>`buildTime` | [`Time`](#time) | Time when the image was built. |
|
||||
| <a id="googlecloudartifactregistrydockerimagedetailsdigest"></a>`digest` | [`String!`](#string) | Image's digest. |
|
||||
| <a id="googlecloudartifactregistrydockerimagedetailsimage"></a>`image` | [`String!`](#string) | Image's name. |
|
||||
| <a id="googlecloudartifactregistrydockerimagedetailsimagesizebytes"></a>`imageSizeBytes` | [`String`](#string) | Calculated size of the image. |
|
||||
| <a id="googlecloudartifactregistrydockerimagedetailslocation"></a>`location` | [`String!`](#string) | Location of the Artifact Registry repository. |
|
||||
| <a id="googlecloudartifactregistrydockerimagedetailsmediatype"></a>`mediaType` | [`String`](#string) | Media type of the image. |
|
||||
| <a id="googlecloudartifactregistrydockerimagedetailsname"></a>`name` | [`String!`](#string) | Unique image name. |
|
||||
| <a id="googlecloudartifactregistrydockerimagedetailsprojectid"></a>`projectId` | [`String!`](#string) | ID of the Google Cloud project. |
|
||||
| <a id="googlecloudartifactregistrydockerimagedetailsrepository"></a>`repository` | [`String!`](#string) | Repository on the Google Cloud Artifact Registry. |
|
||||
| <a id="googlecloudartifactregistrydockerimagedetailstags"></a>`tags` | [`[String!]`](#string) | Tags attached to the image. |
|
||||
| <a id="googlecloudartifactregistrydockerimagedetailsupdatetime"></a>`updateTime` | [`Time`](#time) | Time when the image was last updated. |
|
||||
| <a id="googlecloudartifactregistrydockerimagedetailsuploadtime"></a>`uploadTime` | [`Time`](#time) | Time when the image was uploaded. |
|
||||
| <a id="googlecloudartifactregistrydockerimagedetailsuri"></a>`uri` | [`String!`](#string) | Google Cloud URI to access the image. |
|
||||
|
||||
### `GoogleCloudArtifactRegistryRepository`
|
||||
|
||||
|
|
@ -30710,6 +30745,8 @@ Values for sorting catalog resources.
|
|||
| <a id="cicatalogresourcesortlatest_released_at_desc"></a>`LATEST_RELEASED_AT_DESC` | Latest release date by descending order. |
|
||||
| <a id="cicatalogresourcesortname_asc"></a>`NAME_ASC` | Name by ascending order. |
|
||||
| <a id="cicatalogresourcesortname_desc"></a>`NAME_DESC` | Name by descending order. |
|
||||
| <a id="cicatalogresourcesortstar_count_asc"></a>`STAR_COUNT_ASC` | Star count by ascending order. |
|
||||
| <a id="cicatalogresourcesortstar_count_desc"></a>`STAR_COUNT_DESC` | Star count by descending order. |
|
||||
|
||||
### `CiCatalogResourceVersionSort`
|
||||
|
||||
|
|
@ -31008,6 +31045,7 @@ Name of the check for the compliance standard.
|
|||
|
||||
| Value | Description |
|
||||
| ----- | ----------- |
|
||||
| <a id="compliancestandardsadherencechecknameat_least_one_non_author_approval"></a>`AT_LEAST_ONE_NON_AUTHOR_APPROVAL` | At least one non author approval. |
|
||||
| <a id="compliancestandardsadherencechecknameat_least_two_approvals"></a>`AT_LEAST_TWO_APPROVALS` | At least two approvals. |
|
||||
| <a id="compliancestandardsadherencechecknameprevent_approval_by_merge_request_author"></a>`PREVENT_APPROVAL_BY_MERGE_REQUEST_AUTHOR` | Prevent approval by merge request author. |
|
||||
| <a id="compliancestandardsadherencechecknameprevent_approval_by_merge_request_committers"></a>`PREVENT_APPROVAL_BY_MERGE_REQUEST_COMMITTERS` | Prevent approval by merge request committers. |
|
||||
|
|
@ -31019,6 +31057,7 @@ Name of the compliance standard.
|
|||
| Value | Description |
|
||||
| ----- | ----------- |
|
||||
| <a id="compliancestandardsadherencestandardgitlab"></a>`GITLAB` | Gitlab. |
|
||||
| <a id="compliancestandardsadherencestandardsoc2"></a>`SOC2` | Soc2. |
|
||||
|
||||
### `ComplianceStandardsAdherenceStatus`
|
||||
|
||||
|
|
@ -34282,6 +34321,14 @@ One of:
|
|||
|
||||
- [`GoogleCloudArtifactRegistryDockerImage`](#googlecloudartifactregistrydockerimage)
|
||||
|
||||
#### `GoogleCloudArtifactRegistryArtifactDetails`
|
||||
|
||||
Details type of Google Cloud Artifact Registry artifacts.
|
||||
|
||||
One of:
|
||||
|
||||
- [`GoogleCloudArtifactRegistryDockerImageDetails`](#googlecloudartifactregistrydockerimagedetails)
|
||||
|
||||
#### `Issuable`
|
||||
|
||||
Represents an issuable.
|
||||
|
|
|
|||
|
|
@ -1660,7 +1660,7 @@ Group audit events can be accessed via the [Group Audit Events API](audit_events
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
Syncs the group with its linked LDAP group. Only available to group owners and administrators.
|
||||
|
||||
|
|
@ -1684,7 +1684,7 @@ List, add, and delete LDAP group links.
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
Lists LDAP group links.
|
||||
|
||||
|
|
@ -1700,7 +1700,7 @@ GET /groups/:id/ldap_group_links
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
Adds an LDAP group link using a CN or filter. Adding a group link by filter is only supported in the Premium tier and above.
|
||||
|
||||
|
|
@ -1723,7 +1723,7 @@ To define the LDAP group link, provide either a `cn` or a `filter`, but not both
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
Deletes an LDAP group link. Deprecated. Scheduled for removal in a future release.
|
||||
|
||||
|
|
@ -1752,7 +1752,7 @@ DELETE /groups/:id/ldap_group_links/:provider/:cn
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
Deletes an LDAP group link using a CN or filter. Deleting by filter is only supported in the Premium tier and above.
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
**Offering:** GitLab.com, Self-managed
|
||||
|
||||
Endpoints for connecting custom domains and TLS certificates in [GitLab Pages](https://about.gitlab.com/stages-devops-lifecycle/pages/).
|
||||
|
||||
|
|
|
|||
|
|
@ -214,3 +214,109 @@ curl --request DELETE \
|
|||
--header 'PRIVATE-TOKEN: <your_access_token>' \
|
||||
--header 'Content-Type: application/json'
|
||||
```
|
||||
|
||||
## Get a project's CI/CD job token allowlist of groups
|
||||
|
||||
Fetch the CI/CD job token allowlist of groups (job token scope) of a project.
|
||||
|
||||
```plaintext
|
||||
GET /projects/:id/job_token_scope/groups_allowlist
|
||||
```
|
||||
|
||||
Supported attributes:
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
|-----------|----------------|----------|-------------|
|
||||
| `id` | integer/string | Yes | ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
|
||||
|
||||
This endpoint supports [offset-based pagination](rest/index.md#offset-based-pagination).
|
||||
|
||||
If successful, returns [`200`](rest/index.md#status-codes) and a list of groups with limited fields for each project.
|
||||
|
||||
Example request:
|
||||
|
||||
```shell
|
||||
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/job_token_scope/groups_allowlist"
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": 4,
|
||||
"web_url": "https://gitlab.example.com/groups/diaspora/diaspora-group",
|
||||
"name": "namegroup"
|
||||
},
|
||||
{
|
||||
...
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## Add a group to a CI/CD job token allowlist
|
||||
|
||||
Add a group to the CI/CD job token allowlist of a project.
|
||||
|
||||
```plaintext
|
||||
POST /projects/:id/job_token_scope/groups_allowlist
|
||||
```
|
||||
|
||||
Supported attributes:
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
|-------------------|----------------|----------|-------------|
|
||||
| `id` | integer/string | Yes | ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
|
||||
| `target_group_id` | integer | Yes | The ID of the group added to the CI/CD job token groups allowlist. |
|
||||
|
||||
If successful, returns [`201`](rest/index.md#status-codes) and the following response attributes:
|
||||
|
||||
| Attribute | Type | Description |
|
||||
|---------------------|---------|-------------|
|
||||
| `source_project_id` | integer | ID of the project containing the CI/CD job token inbound allowlist to update. |
|
||||
| `target_group_id` | integer | ID of the group that is added to the source project's groups allowlist. |
|
||||
|
||||
Example request:
|
||||
|
||||
```shell
|
||||
curl --request POST \
|
||||
--url "https://gitlab.example.com/api/v4/projects/1/job_token_scope/groups_allowlist" \
|
||||
--header 'PRIVATE-TOKEN: <your_access_token>' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{ "target_group_id": 2 }'
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
{
|
||||
"source_project_id": 1,
|
||||
"target_group_id": 2
|
||||
}
|
||||
```
|
||||
|
||||
## Remove a group from a CI/CD job token allowlist
|
||||
|
||||
Remove a group from the CI/CD job token allowlist of a project.
|
||||
|
||||
```plaintext
|
||||
DELETE /projects/:id/job_token_scope/groups_allowlist/:target_group_id
|
||||
```
|
||||
|
||||
Supported attributes:
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
|-------------------|----------------|----------|-------------|
|
||||
| `id` | integer/string | Yes | ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
|
||||
| `target_group_id` | integer | Yes | The ID of the group that is removed from the CI/CD job token groups allowlist. |
|
||||
|
||||
If successful, returns [`204`](rest/index.md#status-codes) and no response body.
|
||||
|
||||
Example request:
|
||||
|
||||
```shell
|
||||
curl --request DELETE \
|
||||
--url "https://gitlab.example.com/api/v4/projects/1/job_token_scope/groups_allowlist/2" \
|
||||
--header 'PRIVATE-TOKEN: <your_access_token>' \
|
||||
--header 'Content-Type: application/json'
|
||||
```
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ description: Read through the GitLab installation methods.
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
This page offers a walkthrough of a common configuration for GitLab on AWS using the official Linux package. You should customize it to accommodate your needs.
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ description: 'Learn how to spin up a pre-configured GitLab VM on Microsoft Azure
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
For users of the Microsoft Azure business cloud, GitLab has a pre-configured offering in
|
||||
the [Azure Marketplace](https://azuremarketplace.microsoft.com/en-us/marketplace/).
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
You can install GitLab on several cloud providers.
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
The GitLab Docker images are monolithic images of GitLab running all the
|
||||
necessary services in a single container.
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ description: 'Learn how to install a GitLab instance on Google Cloud Platform.'
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
You can install GitLab on a [Google Cloud Platform (GCP)](https://cloud.google.com/) using the official Linux package. You should customize it to accommodate your needs.
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
You can install GitLab on several [cloud providers](cloud_providers.md),
|
||||
or use one of the following methods.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
This is the official installation guide to set up a production GitLab server
|
||||
using the source files. It was created for and tested on **Debian/Ubuntu** operating systems.
|
||||
|
|
@ -700,7 +700,7 @@ sudo -u git -H bundle exec rake "gitlab:workhorse:install[/home/git/gitlab-workh
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
GitLab-Elasticsearch-Indexer uses [GNU Make](https://www.gnu.org/software/make/). The
|
||||
following command-line installs GitLab-Elasticsearch-Indexer in `/home/git/gitlab-elasticsearch-indexer`
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
Here are a few resources you might want to check out after completing the
|
||||
installation.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
This guide documents how to manage PostgreSQL extensions for installations with an external
|
||||
PostgreSQL database.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
While you should install GitLab on its own (sub)domain, sometimes
|
||||
this is not possible due to a variety of reasons. In that case, GitLab can also
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
This page includes information about the minimum requirements you need to install and use GitLab.
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: "To determine the technical writer assigned to the Stage/Group associated
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
GitLab can integrate with [Kerberos](https://web.mit.edu/kerberos/) as an authentication mechanism.
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
GitLab provides Rake tasks for cleaning up GitLab instances.
|
||||
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ DETAILS:
|
|||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/142189) in GitLab 16.9.
|
||||
|
||||
The Rake task for bulk user assignment is available in GitLab 16.9 and later. For GitLab 16.8, use the script [`bulk_user_assignment.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/duo_pro/bulk_user_assignment.rb) instead.
|
||||
The Rake task for bulk user assignment is available in GitLab 16.9 and later. For GitLab 16.8, use the script [`bulk_user_assignment.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/app/services/gitlab_subscriptions/duo_pro/bulk_user_assignment.rb) instead.
|
||||
|
||||
To perform bulk user assignment for GitLab Duo Pro, you can use the following Rake task:
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
Rotating secrets of third-party integrations is an important security practice
|
||||
that helps mitigate the risks associated with leaked secrets, such as
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: For assistance with this tutorial, see https://handbook.gitlab.com/handboo
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Ultimate
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
**Offering:** GitLab.com, Self-managed
|
||||
**Status:** Experiment
|
||||
|
||||
Understanding how your users engage with your website or application is important for making data-driven decisions.
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ Some features are still in development. View details about [support for each sta
|
|||
| Goal | Feature | Tier/Offering/Status |
|
||||
|---|---|---|
|
||||
| Helps you write code more efficiently by showing code suggestions as you type. <br><br><i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [Watch overview](https://www.youtube.com/watch?v=hCAyCTacdAQ) | [Code Suggestions](project/repository/code_suggestions/index.md) | **Tier:** Premium or Ultimate with [GitLab Duo Pro](../subscriptions/subscription-add-ons.md) <br>**Offering:** GitLab.com, Self-managed, GitLab Dedicated |
|
||||
| Processes and generates text and code in a conversational manner. Helps you quickly identify useful information in large volumes of text in issues, epics, code, and GitLab documentation. | [Chat](gitlab_duo_chat.md) | **Beta Access** subject to the [Testing Agreement](https://handbook.gitlab.com/handbook/legal/testing-agreement/):<br>- SaaS, self-managed <br>- Premium and Ultimate tiers<br><br>**Status:** Beta |
|
||||
| Processes and generates text and code in a conversational manner. Helps you quickly identify useful information in large volumes of text in issues, epics, code, and GitLab documentation. | [Chat](gitlab_duo_chat.md) | **Beta Access** subject to the [Testing Agreement](https://handbook.gitlab.com/handbook/legal/testing-agreement/):<br>- GitLab.com, Self-managed, GitLab Dedicated <br>- Premium and Ultimate tiers<br><br>**Status:** Beta |
|
||||
| Helps you discover or recall Git commands when and where you need them. | [Git suggestions](../editor_extensions/gitlab_cli/index.md#gitlab-duo-commands) | **Tier:** Ultimate <br>**Offering:** GitLab.com <br>**Status:** Experiment |
|
||||
| Assists with quickly getting everyone up to speed on lengthy conversations to help ensure you are all on the same page. | [Discussion summary](#summarize-issue-discussions-with-discussion-summary) | **Tier:** Ultimate <br>**Offering:** GitLab.com <br>**Status:** Experiment |
|
||||
| Generates issue descriptions. | [Issue description generation](#summarize-an-issue-with-issue-description-generation) | **Tier:** Ultimate<br>**Offering:** GitLab.com <br>**Status:** Experiment |
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ DETAILS:
|
|||
|
||||
## Supported architectures
|
||||
|
||||
Operational Container Scanning runs only on `linux/amd64` architecture due to a limitation of the [Trivy wrapper](https://gitlab.com/gitlab-org/security-products/analyzers/trivy-k8s-wrapper) image used for the scanning. To track support for `linux/amd64` see [issue 442804](https://gitlab.com/gitlab-org/gitlab/-/issues/442804).
|
||||
Operational Container Scanning runs only on `linux/amd64` architecture due to a limitation of the [Trivy wrapper](https://gitlab.com/gitlab-org/security-products/analyzers/trivy-k8s-wrapper) image used for the scanning. To track support for `linux/arm64` see [issue 442804](https://gitlab.com/gitlab-org/gitlab/-/issues/442804).
|
||||
|
||||
## Enable operational container scanning
|
||||
|
||||
|
|
|
|||
|
|
@ -81,6 +81,29 @@ To update the adherence status for these projects, the group-level or the projec
|
|||
To comply with the GitLab standard, you must have at least two users approve a merge request to get it merged. For more
|
||||
information, see [Merge request approval rules](../../project/merge_requests/approvals/rules.md).
|
||||
|
||||
### SOC 2 standard
|
||||
|
||||
The SOC 2 standard consists of one rule:
|
||||
|
||||
- At least one non-author approval.
|
||||
|
||||
#### At least one non-author approval
|
||||
|
||||
To comply with the SOC 2 standard, you must:
|
||||
|
||||
- Prevent users from approving their own merge requests. For more information, see
|
||||
[Prevent approval by author](../../project/merge_requests/approvals/settings.md#prevent-approval-by-author).
|
||||
- Prevent users from approving merge requests where they've added commits, see
|
||||
[Prevent approvals by users who add commits](../../project/merge_requests/approvals/settings.md#prevent-approvals-by-users-who-add-commits).
|
||||
- At least one approval is required, see [Merge request approval rules](../../project/merge_requests/approvals/rules.md).
|
||||
|
||||
These settings are available for an entire self-managed GitLab instance. However, when these settings are updated at the instance level,
|
||||
the adherence status for all the projects on the instance is not updated automatically. To update the adherence status
|
||||
for these projects, you must update the group-level or project-level setting. For more information on the instance-level settings, see:
|
||||
|
||||
- [Prevent approval by author](../../../administration/merge_requests_approvals.md).
|
||||
- [Prevent approvals by users who add commits](../../../administration/merge_requests_approvals.md).
|
||||
|
||||
### Export compliance standards adherence report for projects in a group
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/413736) in GitLab 16.8 [with a flag](../../../administration/feature_flags.md) named `compliance_standards_adherence_csv_export`. Disabled by default.
|
||||
|
|
|
|||
|
|
@ -278,7 +278,7 @@ After you lock the membership for a group:
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
Group syncing allows LDAP groups to be mapped to GitLab groups. This provides more control over per-group user management. To configure group syncing, edit the `group_base` **DN** (`'OU=Global Groups,OU=GitLab INT,DC=GitLab,DC=org'`). This **OU** contains all groups that are associated with GitLab groups.
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
**Offering:** GitLab.com, Self-managed
|
||||
|
||||
Two-factor authentication (2FA) provides an additional level of security to your GitLab account. For others to access
|
||||
your account, they would need your username and password _and_ access to your second factor of authentication.
|
||||
|
|
@ -232,6 +232,9 @@ On your GitLab server:
|
|||
|
||||
### Enable one-time password using FortiToken Cloud
|
||||
|
||||
DETAILS:
|
||||
**Offering:** Self-managed
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/212313) in GitLab 13.7 [with a flag](../../../administration/feature_flags.md) named `forti_token_cloud`. Disabled by default.
|
||||
|
||||
FLAG:
|
||||
|
|
@ -488,7 +491,7 @@ a GitLab global administrator disable 2FA for your account:
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** Self-managed, GitLab Dedicated
|
||||
**Offering:** Self-managed
|
||||
|
||||
- Take care that 2FA keeps working after [restoring a GitLab backup](../../../administration/backup_restore/index.md).
|
||||
- To ensure 2FA authorizes correctly with a time-based one-time password (TOTP) server, synchronize your GitLab
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
**Offering:** GitLab.com, Self-managed
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/238461) in GitLab 15.4, you can use verified domains to [bypass user email confirmation for SAML- or SCIM-provisioned users](../../../group/saml_sso/index.md#bypass-user-email-confirmation-with-verified-domains).
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
**Offering:** GitLab.com, Self-managed
|
||||
|
||||
Every GitLab Pages project on GitLab.com is available under
|
||||
HTTPS for the default Pages domain (`*.gitlab.io`). Once you set
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
**Offering:** GitLab.com, Self-managed
|
||||
|
||||
By default, Service Desk is active in new projects.
|
||||
If it's not active, you can do it in the project's settings.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
**Offering:** GitLab.com, Self-managed
|
||||
|
||||
With Service Desk, your customers
|
||||
can email you bug reports, feature requests, or general feedback.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
DETAILS:
|
||||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
**Offering:** GitLab.com, Self-managed
|
||||
|
||||
You can use Service Desk to [create an issue](#as-an-end-user-issue-creator) or [respond to one](#as-a-responder-to-the-issue).
|
||||
In these issues, you can also see our friendly neighborhood [Support Bot](configure.md#support-bot-user).
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module API
|
||||
module Entities
|
||||
class GroupScopeLink < Grape::Entity
|
||||
expose :source_project_id, documentation: { type: 'integer' }
|
||||
expose :target_group_id, documentation: { type: 'integer' }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -74,6 +74,26 @@ module API
|
|||
present paginate(inbound_projects), with: Entities::BasicProjectDetails
|
||||
end
|
||||
|
||||
desc 'Fetch project groups allowlist for CI_JOB_TOKEN access settings.' do
|
||||
failure [
|
||||
{ code: 401, message: 'Unauthorized' },
|
||||
{ code: 403, message: 'Forbidden' },
|
||||
{ code: 404, message: 'Not found' }
|
||||
]
|
||||
success status: 200, model: Entities::BasicProjectDetails
|
||||
tags %w[projects_job_token_scope]
|
||||
end
|
||||
params do
|
||||
use :pagination
|
||||
end
|
||||
get ':id/job_token_scope/groups_allowlist' do
|
||||
authorize_admin_project
|
||||
|
||||
groups_allowlist = ::Ci::JobToken::Scope.new(user_project).groups
|
||||
|
||||
present paginate(groups_allowlist), with: Entities::BasicGroupDetails
|
||||
end
|
||||
|
||||
desc 'Add target project to allowlist.' do
|
||||
failure [
|
||||
{ code: 400, message: 'Bad Request' },
|
||||
|
|
@ -114,6 +134,87 @@ module API
|
|||
present result.payload[:project_link], with: Entities::ProjectScopeLink
|
||||
end
|
||||
|
||||
desc 'Add target group to allowlist.' do
|
||||
failure [
|
||||
{ code: 400, message: 'Bad Request' },
|
||||
{ code: 401, message: 'Unauthorized' },
|
||||
{ code: 403, message: 'Forbidden' },
|
||||
{ code: 404, message: 'Not found' },
|
||||
{ code: 422, message: 'Unprocessable entity' }
|
||||
]
|
||||
success status: 201, model: Entities::BasicGroupDetails
|
||||
tags %w[projects_job_token_scope]
|
||||
end
|
||||
params do
|
||||
requires :id,
|
||||
allow_blank: false,
|
||||
desc: 'ID of user project',
|
||||
documentation: { example: 1 },
|
||||
type: Integer
|
||||
|
||||
requires :target_group_id,
|
||||
allow_blank: false,
|
||||
desc: 'ID of target group',
|
||||
documentation: { example: 2 },
|
||||
type: Integer
|
||||
end
|
||||
post ':id/job_token_scope/groups_allowlist' do
|
||||
authorize_admin_project
|
||||
|
||||
target_group_id = declared_params(include_missing: false).fetch(:target_group_id)
|
||||
target_group = Group.find_by_id(target_group_id)
|
||||
break not_found!("target_group_id not found") if target_group.blank?
|
||||
|
||||
result = ::Ci::JobTokenScope::AddGroupService
|
||||
.new(user_project, current_user)
|
||||
.execute(target_group)
|
||||
|
||||
break bad_request!(result[:message]) if result.error?
|
||||
|
||||
present result.payload[:group_link], with: Entities::GroupScopeLink
|
||||
end
|
||||
|
||||
desc 'Delete target group from allowlist.' do
|
||||
failure [
|
||||
{ code: 400, message: 'Bad Request' },
|
||||
{ code: 401, message: 'Unauthorized' },
|
||||
{ code: 403, message: 'Forbidden' },
|
||||
{ code: 404, message: 'Not found' }
|
||||
]
|
||||
success code: 204
|
||||
tags %w[projects_job_token_scope]
|
||||
end
|
||||
params do
|
||||
requires :id,
|
||||
allow_blank: false,
|
||||
desc: 'ID of user project',
|
||||
documentation: { example: 1 },
|
||||
type: Integer
|
||||
|
||||
requires :target_group_id,
|
||||
allow_blank: false,
|
||||
desc: 'ID of the group to be removed from the allowlist',
|
||||
documentation: { example: 2 },
|
||||
type: Integer
|
||||
end
|
||||
delete ':id/job_token_scope/groups_allowlist/:target_group_id' do
|
||||
target_group_id = declared_params(include_missing: false).fetch(:target_group_id)
|
||||
target_group = Group.find_by_id(target_group_id)
|
||||
break not_found!("target_group_id not found") if target_group.blank?
|
||||
|
||||
result = ::Ci::JobTokenScope::RemoveGroupService
|
||||
.new(user_project, current_user)
|
||||
.execute(target_group)
|
||||
|
||||
if result.success?
|
||||
no_content!
|
||||
elsif result.reason == :insufficient_permissions
|
||||
forbidden!(result.message)
|
||||
else
|
||||
bad_request!(result.message)
|
||||
end
|
||||
end
|
||||
|
||||
desc 'Delete project from allowlist.' do
|
||||
failure [
|
||||
{ code: 400, message: 'Bad Request' },
|
||||
|
|
|
|||
|
|
@ -7,18 +7,20 @@ module Gitlab
|
|||
|
||||
attr_reader :contributor
|
||||
attr_reader :current_user
|
||||
attr_reader :groups
|
||||
attr_reader :projects
|
||||
|
||||
def initialize(contributor, current_user = nil)
|
||||
@contributor = contributor
|
||||
@contributor_time_instance = local_timezone_instance(contributor.timezone).now
|
||||
@current_user = current_user
|
||||
@groups = [] # Overriden in EE
|
||||
@projects = ContributedProjectsFinder.new(contributor)
|
||||
.execute(current_user, ignore_visibility: @contributor.include_private_contributions?)
|
||||
end
|
||||
|
||||
def activity_dates
|
||||
return {} if projects.empty?
|
||||
return {} if groups.blank? && projects.blank?
|
||||
|
||||
start_time = @contributor_time_instance.years_ago(1).beginning_of_day
|
||||
end_time = @contributor_time_instance.end_of_day
|
||||
|
|
@ -39,6 +41,13 @@ module Gitlab
|
|||
private
|
||||
|
||||
def contributions_between(start_time, end_time)
|
||||
Event.from_union(
|
||||
collect_events_between(start_time, end_time),
|
||||
remove_duplicates: false
|
||||
)
|
||||
end
|
||||
|
||||
def collect_events_between(start_time, end_time)
|
||||
# Can't use Event.contributions here because we need to check 3 different
|
||||
# project_features for the (currently) 4 different contribution types
|
||||
repo_events =
|
||||
|
|
@ -55,11 +64,11 @@ module Gitlab
|
|||
.for_merge_request
|
||||
.for_action(%i[merged created closed approved])
|
||||
|
||||
note_events =
|
||||
project_note_events =
|
||||
project_events_created_between(start_time, end_time, features: %i[issues merge_requests])
|
||||
.for_action(:commented)
|
||||
|
||||
Event.from_union([repo_events, issue_events, mr_events, note_events], remove_duplicates: false)
|
||||
[repo_events, issue_events, mr_events, project_note_events]
|
||||
end
|
||||
|
||||
def can_read_cross_project?
|
||||
|
|
@ -103,3 +112,5 @@ module Gitlab
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
Gitlab::ContributionsCalendar.prepend_mod
|
||||
|
|
|
|||
|
|
@ -5,6 +5,35 @@ module Gitlab
|
|||
class Pagination
|
||||
InvalidResourceError = Class.new(StandardError)
|
||||
|
||||
class CursorPagination < Gitlab::Pagination::Base
|
||||
attr_reader :request_context
|
||||
|
||||
delegate :params, :header, to: :request_context
|
||||
|
||||
def initialize(request_context)
|
||||
@request_context = request_context
|
||||
end
|
||||
|
||||
def paginate(resource)
|
||||
resource
|
||||
.tap { |paginator| apply_pagination_headers(paginator) }
|
||||
.records
|
||||
.tap { |records| header('X-Per-Page', records.count) }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def apply_pagination_headers(paginator)
|
||||
header('X-Next-Page', paginator.cursor_for_next_page)
|
||||
header('X-Page', params[:cursor])
|
||||
header('X-Page-Type', 'cursor')
|
||||
header('X-Prev-Page', paginator.cursor_for_previous_page)
|
||||
Gitlab::Pagination::Keyset::HeaderBuilder
|
||||
.new(request_context)
|
||||
.add_next_page_header(cursor: paginator.cursor_for_next_page)
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(request, response)
|
||||
@request = request
|
||||
@response = response
|
||||
|
|
@ -13,6 +42,8 @@ module Gitlab
|
|||
def paginate(resource)
|
||||
if resource.respond_to?(:page)
|
||||
::Gitlab::Pagination::OffsetPagination.new(self).paginate(resource)
|
||||
elsif resource.respond_to?(:cursor_for_next_page)
|
||||
CursorPagination.new(self).paginate(resource)
|
||||
else
|
||||
raise InvalidResourceError
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ParameterFilters
|
||||
class SamlResponse
|
||||
def self.filter(value)
|
||||
return value unless value.presence
|
||||
|
||||
raw_response = if Base64.decode64(value).scan(/[^[:ascii:]]/).count == 0
|
||||
Base64.decode64(value)
|
||||
else
|
||||
value
|
||||
end
|
||||
|
||||
response = Nokogiri::XML(raw_response) do |config|
|
||||
config.options = Nokogiri::XML::ParseOptions::NONET
|
||||
end
|
||||
|
||||
[
|
||||
'/samlp:Response/@IssueInstant',
|
||||
'/samlp:Response/saml:Assertion/@IssueInstant',
|
||||
'/samlp:Response/saml:Assertion/saml:Conditions/@NotBefore',
|
||||
'/samlp:Response/saml:Assertion/saml:Conditions/@NotOnOrAfter',
|
||||
'/samlp:Response/saml:Assertion/saml:AuthnStatement/@AuthnInstant',
|
||||
'/samlp:Response/saml:Assertion/saml:AuthnStatement/@SessionNotOnOrAfter'
|
||||
].each do |xpath|
|
||||
response.at_xpath(xpath).value = 'REDACTED'
|
||||
end
|
||||
|
||||
[
|
||||
['//ds:Signature/ds:SignatureValue', { ds: 'http://www.w3.org/2000/09/xmldsig#' }],
|
||||
['//ds:Signature/ds:SignedInfo/ds:Reference/ds:DigestValue', { ds: 'http://www.w3.org/2000/09/xmldsig#' }]
|
||||
].each do |xpath, namespace|
|
||||
response.at_xpath(xpath, namespace.presence).content = 'REDACTED'
|
||||
end
|
||||
|
||||
response.to_xml
|
||||
|
||||
rescue Nokogiri::XML::SyntaxError
|
||||
'REDACTED'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -812,8 +812,10 @@ msgstr ""
|
|||
msgid "%{jobName} job is being retried"
|
||||
msgstr ""
|
||||
|
||||
msgid "%{jobs} Jobs"
|
||||
msgstr ""
|
||||
msgid "%{jobs} job"
|
||||
msgid_plural "%{jobs} jobs"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
msgid "%{key} is not a valid URL."
|
||||
msgstr ""
|
||||
|
|
@ -10563,9 +10565,6 @@ msgstr ""
|
|||
msgid "CiCatalog|Go to the project"
|
||||
msgstr ""
|
||||
|
||||
msgid "CiCatalog|Last release at %{date}"
|
||||
msgstr ""
|
||||
|
||||
msgid "CiCatalog|No component available"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -10578,6 +10577,9 @@ msgstr ""
|
|||
msgid "CiCatalog|Readme"
|
||||
msgstr ""
|
||||
|
||||
msgid "CiCatalog|Released %{timeAgo}"
|
||||
msgstr ""
|
||||
|
||||
msgid "CiCatalog|Released %{timeAgo} by %{author}"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -12997,6 +12999,9 @@ msgstr ""
|
|||
msgid "ComplianceStandardsAdherence|A rule is configured to require two approvals."
|
||||
msgstr ""
|
||||
|
||||
msgid "ComplianceStandardsAdherence|At least one non-author approval"
|
||||
msgstr ""
|
||||
|
||||
msgid "ComplianceStandardsAdherence|At least two approvals"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -13018,6 +13023,9 @@ msgstr ""
|
|||
msgid "ComplianceStandardsAdherence|Have a valid rule that prevents author-approved merge requests from being merged"
|
||||
msgstr ""
|
||||
|
||||
msgid "ComplianceStandardsAdherence|Have a valid rule that prevents merge requests with less than one non-author approval from being merged"
|
||||
msgstr ""
|
||||
|
||||
msgid "ComplianceStandardsAdherence|Have a valid rule that prevents merge requests with less than two approvals from being merged"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -13042,6 +13050,9 @@ msgstr ""
|
|||
msgid "ComplianceStandardsAdherence|No rule is configured to prevent merge requests approved by committers."
|
||||
msgstr ""
|
||||
|
||||
msgid "ComplianceStandardsAdherence|No rule is configured to require at least one non-author approval."
|
||||
msgstr ""
|
||||
|
||||
msgid "ComplianceStandardsAdherence|No rule is configured to require two approvals."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -42569,6 +42580,9 @@ msgstr ""
|
|||
msgid "Runners|Administrator"
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|After you complete the steps below, an autoscaling fleet of runners is available to execute your CI/CD jobs in Google Cloud. Based on demand, a runner manager automatically creates temporary runners."
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|All"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -42656,15 +42670,9 @@ msgstr ""
|
|||
msgid "Runners|Configuration"
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|Configuration instructions"
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|Containers"
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|Continue to runner details"
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|Copy and paste the following command into your command line to register the runner."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -42757,7 +42765,7 @@ msgstr ""
|
|||
msgid "Runners|Environment"
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|Execution environment"
|
||||
msgid "Runners|Environment in Google Cloud where runners execute CI/CD jobs. Runners are created in temporary virtual machines based on demand."
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|Executor"
|
||||
|
|
@ -42784,6 +42792,9 @@ msgstr ""
|
|||
msgid "Runners|Fleet dashboard"
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|For most CI/CD jobs, use a %{linkStart}N2D standard machine type.%{linkEnd}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|Get started with runners"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -42793,12 +42804,6 @@ msgstr ""
|
|||
msgid "Runners|Go to %{groupLink} to enable them."
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|Go to runners page"
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|Google Cloud"
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|Google Cloud project ID"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -42823,9 +42828,6 @@ msgstr ""
|
|||
msgid "Runners|If both settings are disabled, new runners cannot be registered."
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|If you haven't already, configure your Google Cloud project to connect to this GitLab project and use the runner."
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|In GitLab Runner 15.6, the use of registration tokens and runner parameters in the 'register' command was deprecated. They have been replaced by authentication tokens. %{linkStart}How does this impact my current registration workflow?%{linkEnd}"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -43013,9 +43015,6 @@ msgstr ""
|
|||
msgid "Runners|Project"
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|Project for the new runner."
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|Project runners"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -43151,9 +43150,6 @@ msgstr ""
|
|||
msgid "Runners|Runners"
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|Runners are created based on demand, in temporary virtual machine (VM) instances. The VMs use the Google Container-Optimized OS and Docker Engine with support for auto-scaling"
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|Runners are either:"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -43199,6 +43195,9 @@ msgstr ""
|
|||
msgid "Runners|Separate multiple tags with a comma. For example, %{example}."
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|Setup instructions"
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|Show only inherited"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -43226,9 +43225,15 @@ msgstr ""
|
|||
msgid "Runners|Step 1"
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|Step 1: Specify environment"
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|Step 2"
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|Step 2: Set up GitLab Runner"
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|Step 3 (optional)"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -43323,7 +43328,7 @@ msgstr ""
|
|||
msgid "Runners|This runner is outdated, an upgrade is recommended"
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|To improve security, use a dedicated project for CI/CD, separate from resources and identity management projects."
|
||||
msgid "Runners|To improve security, use a dedicated project for CI/CD, separate from resources and identity management projects. %{linkStart}Where’s my project ID in Google Cloud?%{linkEnd}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|To install Runner in Kubernetes follow the instructions described in the GitLab documentation."
|
||||
|
|
@ -43341,6 +43346,9 @@ msgstr ""
|
|||
msgid "Runners|To view the runner, go to %{runnerListName}."
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|To view the setup instructions, complete the previous form. The instructions help you set up an autoscaling fleet of runners to execute your CI/CD jobs in Google Cloud."
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|Token expiry"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -43398,12 +43406,18 @@ msgstr ""
|
|||
msgid "Runners|Version starts with"
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|View available zones"
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|View installation instructions"
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|View metrics"
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|View runners"
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|View runners list"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -43413,9 +43427,6 @@ msgstr ""
|
|||
msgid "Runners|Wait time to pick a job"
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|Where’s my project ID in Google Cloud?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. %{percentage} spot."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -43539,6 +43550,12 @@ msgstr ""
|
|||
msgid "SHA256"
|
||||
msgstr ""
|
||||
|
||||
msgid "SOC 2"
|
||||
msgstr ""
|
||||
|
||||
msgid "SOC2"
|
||||
msgstr ""
|
||||
|
||||
msgid "SSH Key"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ gem 'gitlab_quality-test_tooling', '~> 1.11.0', require: false
|
|||
gem 'gitlab-utils', path: '../gems/gitlab-utils'
|
||||
gem 'activesupport', '~> 7.0.8.1' # This should stay in sync with the root's Gemfile
|
||||
gem 'allure-rspec', '~> 2.24.0'
|
||||
gem 'capybara', '~> 3.39.2'
|
||||
gem 'capybara', '~> 3.40.0'
|
||||
gem 'capybara-screenshot', '~> 1.0.26'
|
||||
gem 'rake', '~> 13', '>= 13.1.0'
|
||||
gem 'rspec', '~> 3.13'
|
||||
|
|
|
|||
|
|
@ -46,11 +46,11 @@ GEM
|
|||
debug_inspector (>= 0.0.1)
|
||||
builder (3.2.4)
|
||||
byebug (11.1.3)
|
||||
capybara (3.39.2)
|
||||
capybara (3.40.0)
|
||||
addressable
|
||||
matrix
|
||||
mini_mime (>= 0.1.3)
|
||||
nokogiri (~> 1.8)
|
||||
nokogiri (~> 1.11)
|
||||
rack (>= 1.6.0)
|
||||
rack-test (>= 0.6.3)
|
||||
regexp_parser (>= 1.5, < 3.0)
|
||||
|
|
@ -347,7 +347,7 @@ DEPENDENCIES
|
|||
activesupport (~> 7.0.8.1)
|
||||
airborne (~> 0.3.7)
|
||||
allure-rspec (~> 2.24.0)
|
||||
capybara (~> 3.39.2)
|
||||
capybara (~> 3.40.0)
|
||||
capybara-screenshot (~> 1.0.26)
|
||||
chemlab (~> 0.11, >= 0.11.1)
|
||||
chemlab-library-www-gitlab-com (~> 0.1, >= 0.1.1)
|
||||
|
|
|
|||
|
|
@ -30,8 +30,8 @@ module QA
|
|||
end
|
||||
|
||||
Page::Milestone::Show.perform do |milestone|
|
||||
expect(milestone).to have_element('milestone-title-content', text: title)
|
||||
expect(milestone).to have_element('milestone-description-content', text: description)
|
||||
expect(milestone).to have_element('data-testid': 'milestone-title-content', text: title)
|
||||
expect(milestone).to have_element('data-testid': 'milestone-description-content', text: description)
|
||||
expect(milestone).to have_start_date(start_date)
|
||||
expect(milestone).to have_due_date(due_date)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -30,8 +30,8 @@ module QA
|
|||
end
|
||||
|
||||
Page::Milestone::Show.perform do |milestone|
|
||||
expect(milestone).to have_element('milestone-title-content', text: title)
|
||||
expect(milestone).to have_element('milestone-description-content', text: description)
|
||||
expect(milestone).to have_element('data-testid': 'milestone-title-content', text: title)
|
||||
expect(milestone).to have_element('data-testid': 'milestone-description-content', text: description)
|
||||
expect(milestone).to have_start_date(start_date)
|
||||
expect(milestone).to have_due_date(due_date)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ module QA
|
|||
|
||||
Page::Project::Tag::New.perform do |new_tag|
|
||||
expect(new_tag).to have_content('You are not allowed to create this tag as it is protected.')
|
||||
expect(new_tag).to have_element('create-tag-button')
|
||||
expect(new_tag).to have_element('data-testid': 'create-tag-button')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ module QA
|
|||
Page::File::Show.perform(&:click_edit)
|
||||
|
||||
Page::File::Form.perform do |file_form|
|
||||
expect(file_form).to have_element('commit-button')
|
||||
expect(file_form).to have_element('data-testid': 'commit-button')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rubocop-rspec'
|
||||
|
||||
module RuboCop
|
||||
module Cop
|
||||
module Gitlab
|
||||
# This cop checks for use Current.organization at banned layers of the application
|
||||
#
|
||||
# @example
|
||||
#
|
||||
# # bad
|
||||
# class SomeService
|
||||
# def execute
|
||||
# do_something_with(Current.organization)
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# # good
|
||||
# class SomeController < ApplicationController
|
||||
# def create
|
||||
# response = SomeService.new(organization: Current.organization).execute
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# class SomeService
|
||||
# def initialize(organization:)
|
||||
# @organization = organization
|
||||
# end
|
||||
#
|
||||
# def execute
|
||||
# do_something_with(@organization)
|
||||
# end
|
||||
# end
|
||||
#
|
||||
#
|
||||
class AvoidCurrentOrganization < RuboCop::Cop::Base
|
||||
MSG = 'Avoid the use of `%{name}` outside of approved application layers. ' \
|
||||
'Instead, pass the value down to those layers. ' \
|
||||
'See https://gitlab.com/gitlab-org/gitlab/-/issues/442751.'
|
||||
RESTRICT_ON_SEND = %i[
|
||||
organization organization=
|
||||
].freeze
|
||||
|
||||
# @!method current_organization?(node)
|
||||
def_node_matcher :current_organization?, <<~PATTERN
|
||||
(send
|
||||
(const
|
||||
{nil? (cbase)} :Current) {:organization | :organization=} ...)
|
||||
PATTERN
|
||||
|
||||
def on_send(node)
|
||||
return unless current_organization?(node)
|
||||
|
||||
add_offense(node, message: format(MSG, name: node.method_name))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -11,9 +11,6 @@ class MigrationCollisionChecker
|
|||
|
||||
ERROR_CODE = 1
|
||||
|
||||
# To be removed in https://gitlab.com/gitlab-org/gitlab/-/merge_requests/129012
|
||||
SKIP_MIGRATIONS = %w[AddInternalToNotes BackfillInternalOnNotes].freeze
|
||||
|
||||
Result = Struct.new(:error_code, :error_message)
|
||||
|
||||
def initialize
|
||||
|
|
@ -36,9 +33,6 @@ class MigrationCollisionChecker
|
|||
MIGRATION_FOLDERS.each do |migration_folder|
|
||||
Dir.glob(base_path.join(migration_folder)).each do |migration_path|
|
||||
klass_name = CLASS_MATCHER.match(File.read(migration_path))[1]
|
||||
|
||||
next if SKIP_MIGRATIONS.include?(klass_name)
|
||||
|
||||
collisions[klass_name] << migration_path
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -668,6 +668,12 @@ RSpec.describe OmniauthCallbacksController, type: :controller, feature_category:
|
|||
|
||||
expect(flash[:alert]).to start_with 'Signing in using your saml account without a pre-existing GitLab account is not allowed.'
|
||||
end
|
||||
|
||||
it 'logs saml_response for debugging' do
|
||||
expect(Gitlab::AuthLogger).to receive(:info).with(payload_type: 'saml_response', saml_response: anything)
|
||||
|
||||
post :saml, params: { SAMLResponse: mock_saml_response }
|
||||
end
|
||||
end
|
||||
|
||||
context 'with GitLab initiated request' do
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ RSpec.describe 'Pipeline', :js, feature_category: :continuous_integration do
|
|||
|
||||
within_testid 'pipeline-details-header' do
|
||||
expect(page).to have_content("For #{pipeline.ref}")
|
||||
expect(page).to have_content("#{pipeline.statuses.count} Jobs")
|
||||
expect(page).to have_content("#{pipeline.statuses.count} jobs")
|
||||
expect(page).to have_link(pipeline.ref,
|
||||
href: project_commits_path(pipeline.project, pipeline.ref))
|
||||
end
|
||||
|
|
@ -666,7 +666,7 @@ RSpec.describe 'Pipeline', :js, feature_category: :continuous_integration do
|
|||
visit_pipeline
|
||||
|
||||
within_testid 'pipeline-details-header' do
|
||||
expect(page).to have_content("#{pipeline.statuses.count} Jobs")
|
||||
expect(page).to have_content("#{pipeline.statuses.count} jobs")
|
||||
expect(page).to have_content("Related merge request !#{merge_request.iid} " \
|
||||
"to merge #{merge_request.source_branch}")
|
||||
expect(page).to have_link("!#{merge_request.iid}",
|
||||
|
|
@ -700,7 +700,7 @@ RSpec.describe 'Pipeline', :js, feature_category: :continuous_integration do
|
|||
|
||||
it 'shows the pipeline information', :sidekiq_might_not_need_inline do
|
||||
within_testid 'pipeline-details-header' do
|
||||
expect(page).to have_content("#{pipeline.statuses.count} Jobs")
|
||||
expect(page).to have_content("#{pipeline.statuses.count} jobs")
|
||||
expect(page).to have_content("Related merge request !#{merge_request.iid} " \
|
||||
"to merge #{merge_request.source_branch}")
|
||||
expect(page).to have_link("!#{merge_request.iid}",
|
||||
|
|
@ -737,7 +737,7 @@ RSpec.describe 'Pipeline', :js, feature_category: :continuous_integration do
|
|||
visit_pipeline
|
||||
|
||||
within_testid 'pipeline-details-header' do
|
||||
expect(page).to have_content("#{pipeline.statuses.count} Jobs")
|
||||
expect(page).to have_content("#{pipeline.statuses.count} jobs")
|
||||
expect(page).to have_content("Related merge request !#{merge_request.iid} " \
|
||||
"to merge #{merge_request.source_branch} " \
|
||||
"into #{merge_request.target_branch}")
|
||||
|
|
@ -774,7 +774,7 @@ RSpec.describe 'Pipeline', :js, feature_category: :continuous_integration do
|
|||
|
||||
it 'shows the pipeline information', :sidekiq_might_not_need_inline do
|
||||
within_testid 'pipeline-details-header' do
|
||||
expect(page).to have_content("#{pipeline.statuses.count} Jobs")
|
||||
expect(page).to have_content("#{pipeline.statuses.count} jobs")
|
||||
expect(page).to have_content("Related merge request !#{merge_request.iid} " \
|
||||
"to merge #{merge_request.source_branch} " \
|
||||
"into #{merge_request.target_branch}")
|
||||
|
|
|
|||
|
|
@ -2,80 +2,39 @@
|
|||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"uri",
|
||||
"tags",
|
||||
"imageSizeBytes",
|
||||
"uploadTime",
|
||||
"mediaType",
|
||||
"buildTime",
|
||||
"updateTime",
|
||||
"projectId",
|
||||
"location",
|
||||
"repository",
|
||||
"image",
|
||||
"digest",
|
||||
"artifactRegistryImageUrl"
|
||||
"digest"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"uri": {
|
||||
"type": "string"
|
||||
},
|
||||
"tags": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"imageSizeBytes": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"uploadTime": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"mediaType": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"buildTime": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"updateTime": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"projectId": {
|
||||
"type": "string"
|
||||
},
|
||||
"location": {
|
||||
"type": "string"
|
||||
},
|
||||
"repository": {
|
||||
"type": "string"
|
||||
},
|
||||
"image": {
|
||||
"type": "string"
|
||||
},
|
||||
"digest": {
|
||||
"type": "string"
|
||||
},
|
||||
"artifactRegistryUrl": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
53
spec/fixtures/api/schemas/graphql/google_cloud/artifact_registry/docker_image_details.json
vendored
Normal file
53
spec/fixtures/api/schemas/graphql/google_cloud/artifact_registry/docker_image_details.json
vendored
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
{
|
||||
"type": "object",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "./docker_image.json"
|
||||
}
|
||||
],
|
||||
"required": [
|
||||
"uri",
|
||||
"imageSizeBytes",
|
||||
"buildTime",
|
||||
"mediaType",
|
||||
"projectId",
|
||||
"location",
|
||||
"repository",
|
||||
"artifactRegistryImageUrl"
|
||||
],
|
||||
"properties": {
|
||||
"uri": {
|
||||
"type": "string"
|
||||
},
|
||||
"imageSizeBytes": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"buildTime": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"mediaType": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"projectId": {
|
||||
"type": "string"
|
||||
},
|
||||
"location": {
|
||||
"type": "string"
|
||||
},
|
||||
"repository": {
|
||||
"type": "string"
|
||||
},
|
||||
"artifactRegistryUrl": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue