Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2024-02-27 21:09:43 +00:00
parent 484f0959a2
commit d57f7e7a39
120 changed files with 1792 additions and 1181 deletions

View File

@ -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

View File

@ -0,0 +1,6 @@
---
Gitlab/AvoidCurrentOrganization:
Details: grace period
Exclude:
- 'app/models/organizations/organization_setting.rb'
- 'app/services/groups/create_service.rb'

View File

@ -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'

View File

@ -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'),
},
};

View File

@ -54,6 +54,9 @@ query getPipelineHeaderData($fullPath: ID!, $iid: ID!) {
configSource
failureReason
source
yamlErrors
yamlErrorMessages
trigger
...PipelineHeaderData
}
}

View File

@ -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"
>

View File

@ -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);
},
});
};

View File

@ -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>

View File

@ -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}Wheres 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>

View File

@ -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|Wheres 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>

View File

@ -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>

View File

@ -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>

View File

@ -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"

View File

@ -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>

View File

@ -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"

View File

@ -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>

View File

@ -58,6 +58,9 @@
"GoogleCloudArtifactRegistryArtifact": [
"GoogleCloudArtifactRegistryDockerImage"
],
"GoogleCloudArtifactRegistryArtifactDetails": [
"GoogleCloudArtifactRegistryDockerImageDetails"
],
"GoogleCloudLoggingConfigurationInterface": [
"GoogleCloudLoggingConfigurationType",
"InstanceGoogleCloudLoggingConfigurationType"

View File

@ -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')

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1 @@
ad12c9cea9e63231e6926e331624e106617572afeddc95032da058f1c9bf56a7

View File

@ -0,0 +1 @@
a044a9d56648bc0944b61e12dc9715074b03ec9b5de9b9447b6798c263e8db0b

View File

@ -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);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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

View File

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

View File

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

View File

@ -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).

View File

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

View File

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

View File

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

View File

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

View File

@ -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).

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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/).

View File

@ -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'
```

View File

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

View File

@ -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/).

View File

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

View File

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

View File

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

View File

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

View File

@ -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`

View File

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

View File

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

View File

@ -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

View File

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

View File

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

View File

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

View File

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

View File

@ -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

View File

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

View File

@ -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 |

View File

@ -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

View File

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

View File

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

View File

@ -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

View File

@ -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).

View File

@ -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

View File

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

View File

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

View File

@ -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).

View File

@ -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

View File

@ -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' },

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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}Wheres 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|Wheres 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 ""

View File

@ -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'

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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}")

View File

@ -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"
}
}
}

View 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