Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
6bbf79d852
commit
d024f170c7
|
|
@ -256,7 +256,6 @@ export default {
|
|||
'app/assets/javascripts/tags/components/delete_tag_modal.vue',
|
||||
'app/assets/javascripts/token_access/components/outbound_token_access.vue',
|
||||
'app/assets/javascripts/token_access/components/token_permissions.vue',
|
||||
'app/assets/javascripts/tooltips/components/tooltips.vue',
|
||||
'app/assets/javascripts/usage_quotas/components/search_and_sort_bar/search_and_sort_bar.vue',
|
||||
'app/assets/javascripts/user_lists/components/user_lists.vue',
|
||||
'app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals.vue',
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
d19af9f22edb454a615b9bb90fdcaa24f72eb488
|
||||
a2177df705fe856c93c8576bb96cd15e225ea32f
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
96892bcaa0e6b6ff3727d5b312cab22e8dcb9d59
|
||||
a817e7aaa39a4b29f1c99e38bf6b9f8a074d7098
|
||||
|
|
|
|||
4
Gemfile
4
Gemfile
|
|
@ -270,7 +270,7 @@ gem 'asciidoctor-kroki', '~> 0.10.0', require: false, feature_category: :markdow
|
|||
gem 'rouge', '~> 4.5.0', feature_category: :shared
|
||||
gem 'truncato', '~> 0.7.13', feature_category: :team_planning
|
||||
gem 'nokogiri', '~> 1.18', feature_category: :shared
|
||||
gem 'gitlab-glfm-markdown', '~> 0.0.27', feature_category: :markdown
|
||||
gem 'gitlab-glfm-markdown', '~> 0.0.29', feature_category: :markdown
|
||||
gem 'tanuki_emoji', '~> 0.13', feature_category: :markdown
|
||||
gem 'unicode-emoji', '~> 4.0', feature_category: :markdown
|
||||
|
||||
|
|
@ -729,7 +729,7 @@ gem 'cvss-suite', '~> 3.3.0', require: 'cvss_suite', feature_category: :software
|
|||
gem 'arr-pm', '~> 0.0.12', feature_category: :package_registry
|
||||
|
||||
# Remote Development
|
||||
gem 'devfile', '~> 0.3.0', feature_category: :workspaces
|
||||
gem 'devfile', '~> 0.4.0', feature_category: :workspaces
|
||||
|
||||
# Apple plist parsing
|
||||
gem 'CFPropertyList', '~> 3.0.0', feature_category: :mobile_devops
|
||||
|
|
|
|||
|
|
@ -113,10 +113,10 @@
|
|||
{"name":"deprecation_toolkit","version":"1.5.1","platform":"ruby","checksum":"a8a1ab1a19ae40ea12560b65010e099f3459ebde390b76621ef0c21c516a04ba"},
|
||||
{"name":"derailed_benchmarks","version":"2.2.1","platform":"ruby","checksum":"654280664fded41c9cd8fc27fc0fcfaf096023afab90eb4ac1185ba70c5d4439"},
|
||||
{"name":"descendants_tracker","version":"0.0.4","platform":"ruby","checksum":"e9c41dd4cfbb85829a9301ea7e7c48c2a03b26f09319db230e6479ccdc780897"},
|
||||
{"name":"devfile","version":"0.3.0","platform":"aarch64-linux","checksum":"a0fe52455c0c4b092727fb002a9c1ceed823c8c862522eab65090ae9325ecdb1"},
|
||||
{"name":"devfile","version":"0.3.0","platform":"arm64-darwin","checksum":"5c950972f6c064915f487678344e286bf1ca9225a104302a9092945e6942edf7"},
|
||||
{"name":"devfile","version":"0.3.0","platform":"ruby","checksum":"7de291449c57429867f3df33b9cf2f929bd39ed3cfba553b0959afdfdea8fa5a"},
|
||||
{"name":"devfile","version":"0.3.0","platform":"x86_64-linux","checksum":"3f90080602c660b36abf506559378ae904bca82023cce484c8a6f3f98b7155db"},
|
||||
{"name":"devfile","version":"0.4.0","platform":"aarch64-linux","checksum":"ca9a030210755023608e8f853794c0006ebd1acff2b0f54a47202a9bf98a8bce"},
|
||||
{"name":"devfile","version":"0.4.0","platform":"arm64-darwin","checksum":"99588818b3833373236af0cf0559932a4dac4ee6fa017fa7f8885e6acb83a7e3"},
|
||||
{"name":"devfile","version":"0.4.0","platform":"ruby","checksum":"885b7728dae945582321364346f5bb59c4f92457f6cea2231c30ad1e5a168af9"},
|
||||
{"name":"devfile","version":"0.4.0","platform":"x86_64-linux","checksum":"942fb20bce2a13a58ec58632ce1c7a1323cc7e95819e39b548529044b4ad89bc"},
|
||||
{"name":"device_detector","version":"1.0.0","platform":"ruby","checksum":"b800fb3150b00c23e87b6768011808ac1771fffaae74c3238ebaf2b782947a7d"},
|
||||
{"name":"devise","version":"4.9.4","platform":"ruby","checksum":"920042fe5e704c548aa4eb65ebdd65980b83ffae67feb32c697206bfd975a7f8"},
|
||||
{"name":"devise-two-factor","version":"4.1.1","platform":"ruby","checksum":"c95f5b07533e62217aaed3c386874d94e2d472fb5f2b6598afe8600fc17a8b95"},
|
||||
|
|
@ -224,13 +224,13 @@
|
|||
{"name":"gitlab-dangerfiles","version":"4.8.1","platform":"ruby","checksum":"bbad321c9638152a643d27a20b35ba1e2d8eddcc6bdfc4493d7b96e816ecf300"},
|
||||
{"name":"gitlab-experiment","version":"0.9.1","platform":"ruby","checksum":"f230ee742154805a755d5f2539dc44d93cdff08c5bbbb7656018d61f93d01f48"},
|
||||
{"name":"gitlab-fog-azure-rm","version":"2.2.0","platform":"ruby","checksum":"31aa7c2170f57874053144e7f716ec9e15f32e71ffbd2c56753dce46e2e78ba9"},
|
||||
{"name":"gitlab-glfm-markdown","version":"0.0.28","platform":"aarch64-linux-gnu","checksum":"67a2e7d2cd1208d22abb9c162e88aa725f0fa31ea7fa8a6f56481370a5d1ef2d"},
|
||||
{"name":"gitlab-glfm-markdown","version":"0.0.28","platform":"aarch64-linux-musl","checksum":"c4b8ce9061238f0cebdaeeceb64bf2e6f1d72f4bfe72b11ac191f45dce12e302"},
|
||||
{"name":"gitlab-glfm-markdown","version":"0.0.28","platform":"arm64-darwin","checksum":"fe71765e04305f5a34647b3338e5101f92547f627a76ddedab35631f98907420"},
|
||||
{"name":"gitlab-glfm-markdown","version":"0.0.28","platform":"ruby","checksum":"960e481c037bbe319ec73792a3fc0fa024a9c11ab16786f24591417a255514a1"},
|
||||
{"name":"gitlab-glfm-markdown","version":"0.0.28","platform":"x86_64-darwin","checksum":"1434de2be23464ac379e30a125213ce00e6c907f47362b50a2d50488bc1e73d2"},
|
||||
{"name":"gitlab-glfm-markdown","version":"0.0.28","platform":"x86_64-linux-gnu","checksum":"59c5a0c577cb9301253bce6c9c0e2b9585110a34c46197cedc16e1142fb2feaf"},
|
||||
{"name":"gitlab-glfm-markdown","version":"0.0.28","platform":"x86_64-linux-musl","checksum":"298757eb48905451285d8c2ef4ecbb1691ed2b30f522998bc65474be340def8a"},
|
||||
{"name":"gitlab-glfm-markdown","version":"0.0.29","platform":"aarch64-linux-gnu","checksum":"b4c12b3f87c27f4397344b58b37bb7db6d635747bb88bc9ffe57664b743b6d7b"},
|
||||
{"name":"gitlab-glfm-markdown","version":"0.0.29","platform":"aarch64-linux-musl","checksum":"815e476e31f7f0d89fc410ec95dc2bf502936073a5fa5ec6849fd38dfb27f1c1"},
|
||||
{"name":"gitlab-glfm-markdown","version":"0.0.29","platform":"arm64-darwin","checksum":"7a0b2e4f35e61a1227199117dd3632c45ee8e5b3ef06b4f92011a30de762f5f0"},
|
||||
{"name":"gitlab-glfm-markdown","version":"0.0.29","platform":"ruby","checksum":"a19a8a996d403d98b7d9acfb57d3be5259681011c647c5a8a0a1292f5f6eb226"},
|
||||
{"name":"gitlab-glfm-markdown","version":"0.0.29","platform":"x86_64-darwin","checksum":"1e322c51ec338a6958010a062005285f335318c2a4b2dee71c2848468498c08d"},
|
||||
{"name":"gitlab-glfm-markdown","version":"0.0.29","platform":"x86_64-linux-gnu","checksum":"e8086a21a4e3187d76fa89eecac88aa57a89627de2a3b789d70d4844efe881db"},
|
||||
{"name":"gitlab-glfm-markdown","version":"0.0.29","platform":"x86_64-linux-musl","checksum":"f934efe5efc53d36ea00a030cc0d530bad81901ef782b7774dd0bfaef73f1c37"},
|
||||
{"name":"gitlab-kas-grpc","version":"17.9.1","platform":"ruby","checksum":"fd480c1669c741ceab8d5f86b7e5e32b71f4f25af8b523725382dae425aaa958"},
|
||||
{"name":"gitlab-labkit","version":"0.37.0","platform":"ruby","checksum":"d2dd0a60db2149a9a8eebf2975dc23f54ac3ceb01bdba732eb1b26b86dfffa70"},
|
||||
{"name":"gitlab-license","version":"2.6.0","platform":"ruby","checksum":"2c1f8ae73835640ec77bf758c1d0c9730635043c01cf77902f7976e826d7d016"},
|
||||
|
|
|
|||
|
|
@ -529,7 +529,7 @@ GEM
|
|||
thor (>= 0.19, < 2)
|
||||
descendants_tracker (0.0.4)
|
||||
thread_safe (~> 0.3, >= 0.3.1)
|
||||
devfile (0.3.0)
|
||||
devfile (0.4.0)
|
||||
device_detector (1.0.0)
|
||||
devise (4.9.4)
|
||||
bcrypt (~> 3.0)
|
||||
|
|
@ -761,7 +761,7 @@ GEM
|
|||
mime-types
|
||||
net-http-persistent (~> 4.0)
|
||||
nokogiri (~> 1, >= 1.10.8)
|
||||
gitlab-glfm-markdown (0.0.28)
|
||||
gitlab-glfm-markdown (0.0.29)
|
||||
rb_sys (~> 0.9.109)
|
||||
gitlab-kas-grpc (17.9.1)
|
||||
grpc (~> 1.0)
|
||||
|
|
@ -2057,7 +2057,7 @@ DEPENDENCIES
|
|||
declarative_policy (~> 1.1.0)
|
||||
deprecation_toolkit (~> 1.5.1)
|
||||
derailed_benchmarks
|
||||
devfile (~> 0.3.0)
|
||||
devfile (~> 0.4.0)
|
||||
device_detector
|
||||
devise (~> 4.9.3)
|
||||
devise-pbkdf2-encryptable (~> 0.0.0)!
|
||||
|
|
@ -2108,7 +2108,7 @@ DEPENDENCIES
|
|||
gitlab-duo-workflow-service-client (~> 0.1)!
|
||||
gitlab-experiment (~> 0.9.1)
|
||||
gitlab-fog-azure-rm (~> 2.2.0)
|
||||
gitlab-glfm-markdown (~> 0.0.27)
|
||||
gitlab-glfm-markdown (~> 0.0.29)
|
||||
gitlab-housekeeper!
|
||||
gitlab-http!
|
||||
gitlab-kas-grpc (~> 17.9.0.pre.rc2)
|
||||
|
|
|
|||
|
|
@ -113,10 +113,10 @@
|
|||
{"name":"deprecation_toolkit","version":"1.5.1","platform":"ruby","checksum":"a8a1ab1a19ae40ea12560b65010e099f3459ebde390b76621ef0c21c516a04ba"},
|
||||
{"name":"derailed_benchmarks","version":"2.2.1","platform":"ruby","checksum":"654280664fded41c9cd8fc27fc0fcfaf096023afab90eb4ac1185ba70c5d4439"},
|
||||
{"name":"descendants_tracker","version":"0.0.4","platform":"ruby","checksum":"e9c41dd4cfbb85829a9301ea7e7c48c2a03b26f09319db230e6479ccdc780897"},
|
||||
{"name":"devfile","version":"0.3.0","platform":"aarch64-linux","checksum":"a0fe52455c0c4b092727fb002a9c1ceed823c8c862522eab65090ae9325ecdb1"},
|
||||
{"name":"devfile","version":"0.3.0","platform":"arm64-darwin","checksum":"5c950972f6c064915f487678344e286bf1ca9225a104302a9092945e6942edf7"},
|
||||
{"name":"devfile","version":"0.3.0","platform":"ruby","checksum":"7de291449c57429867f3df33b9cf2f929bd39ed3cfba553b0959afdfdea8fa5a"},
|
||||
{"name":"devfile","version":"0.3.0","platform":"x86_64-linux","checksum":"3f90080602c660b36abf506559378ae904bca82023cce484c8a6f3f98b7155db"},
|
||||
{"name":"devfile","version":"0.4.0","platform":"aarch64-linux","checksum":"ca9a030210755023608e8f853794c0006ebd1acff2b0f54a47202a9bf98a8bce"},
|
||||
{"name":"devfile","version":"0.4.0","platform":"arm64-darwin","checksum":"99588818b3833373236af0cf0559932a4dac4ee6fa017fa7f8885e6acb83a7e3"},
|
||||
{"name":"devfile","version":"0.4.0","platform":"ruby","checksum":"885b7728dae945582321364346f5bb59c4f92457f6cea2231c30ad1e5a168af9"},
|
||||
{"name":"devfile","version":"0.4.0","platform":"x86_64-linux","checksum":"942fb20bce2a13a58ec58632ce1c7a1323cc7e95819e39b548529044b4ad89bc"},
|
||||
{"name":"device_detector","version":"1.0.0","platform":"ruby","checksum":"b800fb3150b00c23e87b6768011808ac1771fffaae74c3238ebaf2b782947a7d"},
|
||||
{"name":"devise","version":"4.9.4","platform":"ruby","checksum":"920042fe5e704c548aa4eb65ebdd65980b83ffae67feb32c697206bfd975a7f8"},
|
||||
{"name":"devise-two-factor","version":"4.1.1","platform":"ruby","checksum":"c95f5b07533e62217aaed3c386874d94e2d472fb5f2b6598afe8600fc17a8b95"},
|
||||
|
|
@ -224,13 +224,13 @@
|
|||
{"name":"gitlab-dangerfiles","version":"4.8.1","platform":"ruby","checksum":"bbad321c9638152a643d27a20b35ba1e2d8eddcc6bdfc4493d7b96e816ecf300"},
|
||||
{"name":"gitlab-experiment","version":"0.9.1","platform":"ruby","checksum":"f230ee742154805a755d5f2539dc44d93cdff08c5bbbb7656018d61f93d01f48"},
|
||||
{"name":"gitlab-fog-azure-rm","version":"2.2.0","platform":"ruby","checksum":"31aa7c2170f57874053144e7f716ec9e15f32e71ffbd2c56753dce46e2e78ba9"},
|
||||
{"name":"gitlab-glfm-markdown","version":"0.0.28","platform":"aarch64-linux-gnu","checksum":"67a2e7d2cd1208d22abb9c162e88aa725f0fa31ea7fa8a6f56481370a5d1ef2d"},
|
||||
{"name":"gitlab-glfm-markdown","version":"0.0.28","platform":"aarch64-linux-musl","checksum":"c4b8ce9061238f0cebdaeeceb64bf2e6f1d72f4bfe72b11ac191f45dce12e302"},
|
||||
{"name":"gitlab-glfm-markdown","version":"0.0.28","platform":"arm64-darwin","checksum":"fe71765e04305f5a34647b3338e5101f92547f627a76ddedab35631f98907420"},
|
||||
{"name":"gitlab-glfm-markdown","version":"0.0.28","platform":"ruby","checksum":"960e481c037bbe319ec73792a3fc0fa024a9c11ab16786f24591417a255514a1"},
|
||||
{"name":"gitlab-glfm-markdown","version":"0.0.28","platform":"x86_64-darwin","checksum":"1434de2be23464ac379e30a125213ce00e6c907f47362b50a2d50488bc1e73d2"},
|
||||
{"name":"gitlab-glfm-markdown","version":"0.0.28","platform":"x86_64-linux-gnu","checksum":"59c5a0c577cb9301253bce6c9c0e2b9585110a34c46197cedc16e1142fb2feaf"},
|
||||
{"name":"gitlab-glfm-markdown","version":"0.0.28","platform":"x86_64-linux-musl","checksum":"298757eb48905451285d8c2ef4ecbb1691ed2b30f522998bc65474be340def8a"},
|
||||
{"name":"gitlab-glfm-markdown","version":"0.0.29","platform":"aarch64-linux-gnu","checksum":"b4c12b3f87c27f4397344b58b37bb7db6d635747bb88bc9ffe57664b743b6d7b"},
|
||||
{"name":"gitlab-glfm-markdown","version":"0.0.29","platform":"aarch64-linux-musl","checksum":"815e476e31f7f0d89fc410ec95dc2bf502936073a5fa5ec6849fd38dfb27f1c1"},
|
||||
{"name":"gitlab-glfm-markdown","version":"0.0.29","platform":"arm64-darwin","checksum":"7a0b2e4f35e61a1227199117dd3632c45ee8e5b3ef06b4f92011a30de762f5f0"},
|
||||
{"name":"gitlab-glfm-markdown","version":"0.0.29","platform":"ruby","checksum":"a19a8a996d403d98b7d9acfb57d3be5259681011c647c5a8a0a1292f5f6eb226"},
|
||||
{"name":"gitlab-glfm-markdown","version":"0.0.29","platform":"x86_64-darwin","checksum":"1e322c51ec338a6958010a062005285f335318c2a4b2dee71c2848468498c08d"},
|
||||
{"name":"gitlab-glfm-markdown","version":"0.0.29","platform":"x86_64-linux-gnu","checksum":"e8086a21a4e3187d76fa89eecac88aa57a89627de2a3b789d70d4844efe881db"},
|
||||
{"name":"gitlab-glfm-markdown","version":"0.0.29","platform":"x86_64-linux-musl","checksum":"f934efe5efc53d36ea00a030cc0d530bad81901ef782b7774dd0bfaef73f1c37"},
|
||||
{"name":"gitlab-kas-grpc","version":"17.9.1","platform":"ruby","checksum":"fd480c1669c741ceab8d5f86b7e5e32b71f4f25af8b523725382dae425aaa958"},
|
||||
{"name":"gitlab-labkit","version":"0.37.0","platform":"ruby","checksum":"d2dd0a60db2149a9a8eebf2975dc23f54ac3ceb01bdba732eb1b26b86dfffa70"},
|
||||
{"name":"gitlab-license","version":"2.6.0","platform":"ruby","checksum":"2c1f8ae73835640ec77bf758c1d0c9730635043c01cf77902f7976e826d7d016"},
|
||||
|
|
|
|||
|
|
@ -541,7 +541,7 @@ GEM
|
|||
thor (>= 0.19, < 2)
|
||||
descendants_tracker (0.0.4)
|
||||
thread_safe (~> 0.3, >= 0.3.1)
|
||||
devfile (0.3.0)
|
||||
devfile (0.4.0)
|
||||
device_detector (1.0.0)
|
||||
devise (4.9.4)
|
||||
bcrypt (~> 3.0)
|
||||
|
|
@ -773,7 +773,7 @@ GEM
|
|||
mime-types
|
||||
net-http-persistent (~> 4.0)
|
||||
nokogiri (~> 1, >= 1.10.8)
|
||||
gitlab-glfm-markdown (0.0.28)
|
||||
gitlab-glfm-markdown (0.0.29)
|
||||
rb_sys (~> 0.9.109)
|
||||
gitlab-kas-grpc (17.9.1)
|
||||
grpc (~> 1.0)
|
||||
|
|
@ -2091,7 +2091,7 @@ DEPENDENCIES
|
|||
declarative_policy (~> 1.1.0)
|
||||
deprecation_toolkit (~> 1.5.1)
|
||||
derailed_benchmarks
|
||||
devfile (~> 0.3.0)
|
||||
devfile (~> 0.4.0)
|
||||
device_detector
|
||||
devise (~> 4.9.3)
|
||||
devise-pbkdf2-encryptable (~> 0.0.0)!
|
||||
|
|
@ -2142,7 +2142,7 @@ DEPENDENCIES
|
|||
gitlab-duo-workflow-service-client (~> 0.1)!
|
||||
gitlab-experiment (~> 0.9.1)
|
||||
gitlab-fog-azure-rm (~> 2.2.0)
|
||||
gitlab-glfm-markdown (~> 0.0.27)
|
||||
gitlab-glfm-markdown (~> 0.0.29)
|
||||
gitlab-housekeeper!
|
||||
gitlab-http!
|
||||
gitlab-kas-grpc (~> 17.9.0.pre.rc2)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
<script>
|
||||
import { GlBadge, GlTab } from '@gitlab/ui';
|
||||
import { I18N_FETCH_ERROR } from '~/ci/runner/constants';
|
||||
import { createAlert } from '~/alert';
|
||||
import { fetchPolicies } from '~/lib/graphql';
|
||||
import allRunnersQuery from 'ee_else_ce/ci/runner/graphql/list/all_runners.query.graphql';
|
||||
import RunnerName from '~/ci/runner/components/runner_name.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GlBadge,
|
||||
GlTab,
|
||||
RunnerName,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
runners: {
|
||||
items: [],
|
||||
pageInfo: {},
|
||||
},
|
||||
};
|
||||
},
|
||||
apollo: {
|
||||
runners: {
|
||||
query: allRunnersQuery,
|
||||
fetchPolicy: fetchPolicies.NETWORK_ONLY,
|
||||
variables() {
|
||||
return {
|
||||
type: 'INSTANCE_TYPE',
|
||||
};
|
||||
},
|
||||
update(data) {
|
||||
const { runners } = data;
|
||||
return {
|
||||
items: runners?.nodes || [],
|
||||
pageInfo: runners?.pageInfo || {},
|
||||
};
|
||||
},
|
||||
error() {
|
||||
createAlert({ message: I18N_FETCH_ERROR });
|
||||
},
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
runnersItems() {
|
||||
return this.runners.items;
|
||||
},
|
||||
runnersItemCount() {
|
||||
return this.runnersItems.length;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<gl-tab>
|
||||
<template #title>
|
||||
<div class="gl-flex gl-gap-2">
|
||||
{{ __('Instance') }}
|
||||
<gl-badge>{{ runnersItemCount }}</gl-badge>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<ul>
|
||||
<li v-for="runner in runnersItems" :key="runner.key">
|
||||
<runner-name :key="runner.key" :runner="runner" />
|
||||
</li>
|
||||
</ul>
|
||||
</gl-tab>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
<script>
|
||||
import { GlBadge, GlTab } from '@gitlab/ui';
|
||||
import { __ } from '~/locale';
|
||||
import { I18N_FETCH_ERROR } from '~/ci/runner/constants';
|
||||
import { createAlert } from '~/alert';
|
||||
import { fetchPolicies } from '~/lib/graphql';
|
||||
import groupRunnersQuery from 'ee_else_ce/ci/runner/graphql/list/group_runners.query.graphql';
|
||||
|
||||
import RunnerName from '~/ci/runner/components/runner_name.vue';
|
||||
|
||||
export const QUERY_TYPES = {
|
||||
project: 'PROJECT_TYPE',
|
||||
group: 'GROUP_TYPE',
|
||||
};
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GlBadge,
|
||||
GlTab,
|
||||
RunnerName,
|
||||
},
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: __('Project'),
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'project',
|
||||
},
|
||||
groupFullPath: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
runners: {
|
||||
items: [],
|
||||
urlsById: {},
|
||||
pageInfo: {},
|
||||
},
|
||||
};
|
||||
},
|
||||
apollo: {
|
||||
runners: {
|
||||
query: groupRunnersQuery,
|
||||
fetchPolicy: fetchPolicies.NETWORK_ONLY,
|
||||
variables() {
|
||||
return {
|
||||
type: QUERY_TYPES[this.type],
|
||||
groupFullPath: this.groupFullPath,
|
||||
};
|
||||
},
|
||||
update(data) {
|
||||
const { edges = [], pageInfo = {} } = data?.group?.runners || {};
|
||||
const items = edges.map(({ node }) => node);
|
||||
return { items, pageInfo };
|
||||
},
|
||||
error() {
|
||||
createAlert({ message: I18N_FETCH_ERROR });
|
||||
},
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
runnersItems() {
|
||||
return this.runners.items;
|
||||
},
|
||||
runnersItemsCount() {
|
||||
return this.runnersItems.length;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<gl-tab>
|
||||
<template #title>
|
||||
<div class="gl-flex gl-gap-2">
|
||||
{{ title }}
|
||||
<gl-badge>{{ runnersItemsCount }}</gl-badge>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<ul>
|
||||
<li v-for="runner in runnersItems" :key="runner.key">
|
||||
<runner-name :key="runner.key" :runner="runner" />
|
||||
</li>
|
||||
</ul>
|
||||
</gl-tab>
|
||||
</template>
|
||||
|
|
@ -1,6 +1,11 @@
|
|||
import Vue from 'vue';
|
||||
import VueApollo from 'vue-apollo';
|
||||
import createDefaultClient from '~/lib/graphql';
|
||||
import { parseBoolean } from '~/lib/utils/common_utils';
|
||||
import ProjectRunnersSettingsApp from './project_runners_settings_app.vue';
|
||||
|
||||
Vue.use(VueApollo);
|
||||
|
||||
export const initProjectRunnersSettings = (selector = '#js-project-runners-settings') => {
|
||||
const el = document.querySelector(selector);
|
||||
|
||||
|
|
@ -8,10 +13,31 @@ export const initProjectRunnersSettings = (selector = '#js-project-runners-setti
|
|||
return null;
|
||||
}
|
||||
|
||||
const apolloProvider = new VueApollo({
|
||||
defaultClient: createDefaultClient(),
|
||||
});
|
||||
|
||||
const {
|
||||
canCreateRunner,
|
||||
allowRegistrationToken,
|
||||
registrationToken,
|
||||
newProjectRunnerPath,
|
||||
groupFullPath,
|
||||
} = el.dataset;
|
||||
|
||||
return new Vue({
|
||||
el,
|
||||
apolloProvider,
|
||||
render(h) {
|
||||
return h(ProjectRunnersSettingsApp, {});
|
||||
return h(ProjectRunnersSettingsApp, {
|
||||
props: {
|
||||
canCreateRunner: parseBoolean(canCreateRunner),
|
||||
allowRegistrationToken: parseBoolean(allowRegistrationToken),
|
||||
registrationToken,
|
||||
newProjectRunnerPath,
|
||||
groupFullPath,
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,11 +1,64 @@
|
|||
<script>
|
||||
import { GlButton, GlTabs } from '@gitlab/ui';
|
||||
import CrudComponent from '~/vue_shared/components/crud_component.vue';
|
||||
import RegistrationDropdown from '~/ci/runner/components/registration/registration_dropdown.vue';
|
||||
import RunnersTab from '~/ci/runner/project_runners_settings/components/runners_tab.vue';
|
||||
import InstanceRunnersTab from '~/ci/runner/project_runners_settings/components/instance_runners_tab.vue';
|
||||
|
||||
export default {
|
||||
name: 'ProjectRunnersSettingsApp',
|
||||
components: {
|
||||
GlButton,
|
||||
GlTabs,
|
||||
CrudComponent,
|
||||
RegistrationDropdown,
|
||||
RunnersTab,
|
||||
InstanceRunnersTab,
|
||||
},
|
||||
props: {
|
||||
canCreateRunner: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
allowRegistrationToken: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
registrationToken: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
newProjectRunnerPath: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
groupFullPath: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<!-- eslint-disable-next-line @gitlab/vue-require-i18n-strings -->
|
||||
<pre>:vue_project_runners_settings</pre>
|
||||
</div>
|
||||
<crud-component :title="s__('Runners|Runners')" body-class="!gl-m-0">
|
||||
<template #actions>
|
||||
<gl-button v-if="canCreateRunner" size="small" :href="newProjectRunnerPath">{{
|
||||
s__('Runners|New project runner')
|
||||
}}</gl-button>
|
||||
<registration-dropdown
|
||||
size="small"
|
||||
type="PROJECT_TYPE"
|
||||
:allow-registration-token="allowRegistrationToken"
|
||||
:registration-token="registrationToken"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<gl-tabs>
|
||||
<runners-tab :title="__('Project')" type="project" :group-full-path="groupFullPath" />
|
||||
<runners-tab :title="__('Group')" type="group" :group-full-path="groupFullPath" />
|
||||
<instance-runners-tab />
|
||||
</gl-tabs>
|
||||
</crud-component>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,14 +1,23 @@
|
|||
import { addShortcutsExtension } from '~/behaviors/shortcuts';
|
||||
import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
|
||||
import initBoards from '~/boards';
|
||||
import { ISSUE_WIT_FEEDBACK_BADGE } from '~/work_items/constants';
|
||||
|
||||
addShortcutsExtension(ShortcutsNavigation);
|
||||
initBoards();
|
||||
|
||||
if (gon.features.workItemsViewPreference) {
|
||||
let feedback = {};
|
||||
|
||||
if (gon.features.workItemViewForIssues) {
|
||||
feedback = {
|
||||
...ISSUE_WIT_FEEDBACK_BADGE,
|
||||
};
|
||||
}
|
||||
|
||||
if (gon.features.workItemsViewPreference || gon.features.workItemViewForIssues) {
|
||||
import(/* webpackChunkName: 'work_items_feedback' */ '~/work_items_feedback')
|
||||
.then(({ initWorkItemsFeedback }) => {
|
||||
initWorkItemsFeedback();
|
||||
initWorkItemsFeedback(feedback);
|
||||
})
|
||||
.catch({});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,20 @@
|
|||
import { mountIssuesListApp } from '~/issues/list';
|
||||
import { ISSUE_WIT_FEEDBACK_BADGE } from '~/work_items/constants';
|
||||
|
||||
mountIssuesListApp();
|
||||
|
||||
if (gon.features.workItemsViewPreference) {
|
||||
let feedback = {};
|
||||
|
||||
if (gon.features.workItemViewForIssues) {
|
||||
feedback = {
|
||||
...ISSUE_WIT_FEEDBACK_BADGE,
|
||||
};
|
||||
}
|
||||
|
||||
if (gon.features.workItemsViewPreference || gon.features.workItemViewForIssues) {
|
||||
import(/* webpackChunkName: 'work_items_feedback' */ '~/work_items_feedback')
|
||||
.then(({ initWorkItemsFeedback }) => {
|
||||
initWorkItemsFeedback();
|
||||
initWorkItemsFeedback(feedback);
|
||||
})
|
||||
.catch({});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -291,6 +291,7 @@ export default {
|
|||
:option="selectedProjectOption"
|
||||
:namespace="namespace"
|
||||
data-testid="new-project-step2"
|
||||
@onSelectNamespace="onSelectNamespace"
|
||||
@back="onBack"
|
||||
@next="onNext"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
<script>
|
||||
import { GlButton } from '@gitlab/ui';
|
||||
import MultiStepFormTemplate from '~/vue_shared/components/multi_step_form_template.vue';
|
||||
import SharedProjectCreationFields from './shared_project_creation_fields.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GlButton,
|
||||
MultiStepFormTemplate,
|
||||
SharedProjectCreationFields,
|
||||
},
|
||||
props: {
|
||||
option: {
|
||||
|
|
@ -13,12 +15,30 @@ export default {
|
|||
required: false,
|
||||
default: () => ({}),
|
||||
},
|
||||
namespace: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onSelectNamespace(newNamespace) {
|
||||
this.$emit('onSelectNamespace', newNamespace);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<multi-step-form-template :title="option.title" :current-step="2" :steps-total="2">
|
||||
<template #form>
|
||||
<shared-project-creation-fields
|
||||
:namespace="namespace"
|
||||
@onSelectNamespace="onSelectNamespace"
|
||||
/>
|
||||
<!-- Project Configuration and Experimental features will be added here in: https://gitlab.com/gitlab-org/gitlab/-/issues/514700 -->
|
||||
|
||||
<!-- Two checkboxes from JiHu should be added here in: https://gitlab.com/gitlab-org/gitlab/-/issues/514700 -->
|
||||
</template>
|
||||
<template #next>
|
||||
<gl-button
|
||||
category="primary"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,116 @@
|
|||
<script>
|
||||
import { GlFormGroup, GlFormInput } from '@gitlab/ui';
|
||||
import { kebabCase } from 'lodash';
|
||||
import validation, { initForm } from '~/vue_shared/directives/validation';
|
||||
import NewProjectDestinationSelect from './project_destination_select.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GlFormGroup,
|
||||
GlFormInput,
|
||||
NewProjectDestinationSelect,
|
||||
},
|
||||
directives: {
|
||||
validation: validation(),
|
||||
},
|
||||
props: {
|
||||
namespace: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
const form = initForm({
|
||||
fields: {
|
||||
'project[name]': { value: null },
|
||||
'project[path]': { value: null },
|
||||
},
|
||||
});
|
||||
return {
|
||||
form,
|
||||
selectedNamespace: this.namespace,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
updateSlug() {
|
||||
this.form.fields['project[path]'].value = kebabCase(this.form.fields['project[name]'].value);
|
||||
},
|
||||
onSelectNamespace(newNamespace) {
|
||||
this.$emit('onSelectNamespace', newNamespace);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<gl-form-group
|
||||
:label="s__('ProjectsNew|Project name')"
|
||||
label-for="project[name]"
|
||||
:description="
|
||||
s__(
|
||||
'ProjectsNew|Must start with a lowercase or uppercase letter, digit, emoji, or underscore. Can also contain dots, pluses, dashes, or spaces.',
|
||||
)
|
||||
"
|
||||
:invalid-feedback="form.fields['project[name]'].feedback"
|
||||
data-testid="project-name-group"
|
||||
>
|
||||
<gl-form-input
|
||||
id="project[name]"
|
||||
v-model="form.fields['project[name]'].value"
|
||||
v-validation:[form.showValidation]
|
||||
:validation-message="s__('ProjectsNew|Please enter project name.')"
|
||||
:state="form.fields['project[name]'].state"
|
||||
name="project[name]"
|
||||
required
|
||||
:placeholder="s__('ProjectsNew|My awesome project')"
|
||||
data-testid="project-name-input"
|
||||
@input="updateSlug"
|
||||
/>
|
||||
</gl-form-group>
|
||||
|
||||
<div class="gl-flex gl-flex-col gl-gap-4 sm:gl-flex-row">
|
||||
<gl-form-group
|
||||
:label="s__('ProjectsNew|Choose a group or namespace')"
|
||||
class="sm:gl-w-1/2"
|
||||
label-for="namespace"
|
||||
:invalid-feedback="
|
||||
s__('ProjectsNew|Pick a group or namespace where you want to create this project.')
|
||||
"
|
||||
:state="selectedNamespace.id !== null"
|
||||
data-testid="project-namespace-group"
|
||||
>
|
||||
<new-project-destination-select
|
||||
toggle-aria-labelled-by="namespace"
|
||||
:namespace-id="selectedNamespace.id"
|
||||
:namespace-full-path="selectedNamespace.fullPath"
|
||||
@onSelectNamespace="onSelectNamespace"
|
||||
/>
|
||||
</gl-form-group>
|
||||
|
||||
<div class="gl-mt-2 gl-hidden gl-pt-6 sm:gl-block">/</div>
|
||||
|
||||
<gl-form-group
|
||||
:label="s__('ProjectsNew|Project slug')"
|
||||
label-for="project[path]"
|
||||
class="sm:gl-w-1/2"
|
||||
:invalid-feedback="form.fields['project[path]'].feedback"
|
||||
data-testid="project-slug-group"
|
||||
>
|
||||
<gl-form-input
|
||||
id="project[path]"
|
||||
v-model="form.fields['project[path]'].value"
|
||||
v-validation:[form.showValidation]
|
||||
:validation-message="s__('ProjectsNew|Please enter project slug.')"
|
||||
:state="form.fields['project[path]'].state"
|
||||
name="project[path]"
|
||||
required
|
||||
:placeholder="s__('ProjectsNew|my-awesome-project')"
|
||||
data-testid="project-slug-input"
|
||||
/>
|
||||
</gl-form-group>
|
||||
</div>
|
||||
|
||||
<!-- Deployment Target and Visibility Level should be added in: https://gitlab.com/gitlab-org/gitlab/-/issues/514700 -->
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -55,6 +55,7 @@ export default {
|
|||
this.observer.disconnect();
|
||||
},
|
||||
methods: {
|
||||
// eslint-disable-next-line vue/no-unused-properties -- addTooltips is part of the component's public API for adding tooltips dynamically.
|
||||
addTooltips(elements, config) {
|
||||
const newTooltips = elements
|
||||
.filter((element) => !this.tooltipExists(element))
|
||||
|
|
@ -81,6 +82,7 @@ export default {
|
|||
}
|
||||
}
|
||||
},
|
||||
// eslint-disable-next-line vue/no-unused-properties -- fixTitle is part of the component's public API for updating tooltip titles.
|
||||
fixTitle(target) {
|
||||
const tooltip = this.findTooltipByTarget(target);
|
||||
|
||||
|
|
@ -88,6 +90,7 @@ export default {
|
|||
tooltip.title = target.getAttribute('title');
|
||||
}
|
||||
},
|
||||
// eslint-disable-next-line vue/no-unused-properties -- triggerEvent is part of the component's public API for triggering tooltip events.
|
||||
triggerEvent(target, event) {
|
||||
const tooltip = this.findTooltipByTarget(target);
|
||||
const tooltipRef = this.$refs[tooltip?.id];
|
||||
|
|
|
|||
|
|
@ -185,6 +185,11 @@ export default {
|
|||
required: false,
|
||||
default: false,
|
||||
},
|
||||
namespaceFullName: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
@ -863,6 +868,7 @@ export default {
|
|||
v-model="selectedProjectFullPath"
|
||||
:full-path="fullPath"
|
||||
:is-group="isGroup"
|
||||
:current-project-name="namespaceFullName"
|
||||
/>
|
||||
</gl-form-group>
|
||||
|
||||
|
|
|
|||
|
|
@ -89,6 +89,11 @@ export default {
|
|||
validator: (i) => i.id && i.type && i.reference && i.webUrl,
|
||||
default: null,
|
||||
},
|
||||
namespaceFullName: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
@ -320,6 +325,7 @@ export default {
|
|||
:work-item-type-name="selectedWorkItemTypeName"
|
||||
:related-item="relatedItem"
|
||||
:should-discard-draft="shouldDiscardDraft"
|
||||
:namespace-full-name="namespaceFullName"
|
||||
:is-modal="true"
|
||||
@changeType="selectedWorkItemTypeName = $event"
|
||||
@confirmCancel="handleConfirmCancellation"
|
||||
|
|
|
|||
|
|
@ -267,7 +267,7 @@ export default {
|
|||
this.$emit('replied');
|
||||
clearDraft(this.autosaveKey);
|
||||
this.cancelEditing();
|
||||
this.doFullPageReloadIfIncident(commentText);
|
||||
this.doFullPageReloadIfUnsupportedTypeChange(commentText);
|
||||
} catch (error) {
|
||||
this.$emit('error', error.message);
|
||||
Sentry.captureException(error);
|
||||
|
|
@ -275,16 +275,16 @@ export default {
|
|||
this.isSubmitting = false;
|
||||
}
|
||||
},
|
||||
// Until incidents are fully migrated to work items
|
||||
// Until incidents and Service Desk issues are fully migrated to work items
|
||||
// we need to browse to the detail page again
|
||||
// so the legacy detail view is rendered.
|
||||
// https://gitlab.com/gitlab-org/gitlab/-/issues/502823
|
||||
doFullPageReloadIfIncident(commentText) {
|
||||
// Matches quick actions /promote_to incident /promote_to_incident and /type incident case insensitive
|
||||
const incidentTypeChangeRegex =
|
||||
/\/(promote_to(?:_incident|\s{1,3}incident)|type\s{1,3}incident)(?!\S)/im;
|
||||
doFullPageReloadIfUnsupportedTypeChange(commentText) {
|
||||
// Matches quick actions /promote_to incident /promote_to_incident /type incident and /convert_to_ticket case insensitive
|
||||
const unsupportedTypeChangeRegex =
|
||||
/\/(promote_to(?:_incident|\s{1,3}incident)|type\s{1,3}incident|convert_to_ticket)(?!\S)/im;
|
||||
|
||||
if (incidentTypeChangeRegex.test(commentText)) {
|
||||
if (unsupportedTypeChangeRegex.test(commentText)) {
|
||||
visitUrl(this.workItem.webUrl);
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -793,6 +793,7 @@ export default {
|
|||
:related-item="relatedItemData"
|
||||
:preselected-work-item-type="workItemTypeNameEnum"
|
||||
:show-project-selector="!isEpic"
|
||||
:namespace-full-name="namespaceFullName"
|
||||
:is-group="isGroup"
|
||||
hide-button
|
||||
@workItemCreated="$emit('workItemCreated')"
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ module Types
|
|||
class GroupType < NamespaceType
|
||||
graphql_name 'Group'
|
||||
|
||||
include ::NamespacesHelper
|
||||
|
||||
implements ::Types::Namespaces::GroupInterface
|
||||
|
||||
authorize :read_group
|
||||
|
|
@ -356,6 +358,22 @@ module Types
|
|||
description: 'Cluster agents associated with projects in the group and its subgroups.',
|
||||
resolver: ::Resolvers::Clusters::AgentsResolver
|
||||
|
||||
field :marked_for_deletion_on, ::Types::TimeType,
|
||||
null: true,
|
||||
description: 'Date when group was scheduled to be deleted.',
|
||||
experiment: { milestone: '16.11' }
|
||||
|
||||
field :is_adjourned_deletion_enabled, GraphQL::Types::Boolean,
|
||||
null: false,
|
||||
description: 'Indicates if delayed group deletion is enabled.',
|
||||
method: :adjourned_deletion?,
|
||||
experiment: { milestone: '16.11' }
|
||||
|
||||
field :permanent_deletion_date, GraphQL::Types::String,
|
||||
null: true,
|
||||
description: 'Date when group will be deleted if delayed group deletion is enabled.',
|
||||
experiment: { milestone: '16.11' }
|
||||
|
||||
def label(title:)
|
||||
BatchLoader::GraphQL.for(title).batch(key: group) do |titles, loader, args|
|
||||
LabelsFinder
|
||||
|
|
@ -451,6 +469,18 @@ module Types
|
|||
)
|
||||
end
|
||||
|
||||
def marked_for_deletion_on
|
||||
return unless group.adjourned_deletion?
|
||||
|
||||
group.marked_for_deletion_on
|
||||
end
|
||||
|
||||
def permanent_deletion_date
|
||||
return unless group.adjourned_deletion_configured?
|
||||
|
||||
permanent_deletion_date_formatted(Date.current)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def group
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ module Types
|
|||
class ProjectType < BaseObject
|
||||
graphql_name 'Project'
|
||||
|
||||
include ::NamespacesHelper
|
||||
|
||||
connection_type_class Types::CountableConnectionType
|
||||
|
||||
authorize :read_project
|
||||
|
|
@ -134,6 +136,22 @@ module Types
|
|||
null: true,
|
||||
description: 'Indicates the archived status of the project.'
|
||||
|
||||
field :marked_for_deletion_on, ::Types::TimeType,
|
||||
null: true,
|
||||
description: 'Date when project was scheduled to be deleted.',
|
||||
experiment: { milestone: '16.10' }
|
||||
|
||||
field :is_adjourned_deletion_enabled, GraphQL::Types::Boolean,
|
||||
null: false,
|
||||
description: 'Indicates if delayed project deletion is enabled.',
|
||||
method: :adjourned_deletion?,
|
||||
experiment: { milestone: '16.11' }
|
||||
|
||||
field :permanent_deletion_date, GraphQL::Types::String,
|
||||
null: true,
|
||||
description: 'Date when project will be deleted if delayed project deletion is enabled.',
|
||||
experiment: { milestone: '16.11' }
|
||||
|
||||
field :visibility, GraphQL::Types::String,
|
||||
null: true,
|
||||
description: 'Visibility of the project.'
|
||||
|
|
@ -1017,6 +1035,20 @@ module Types
|
|||
)
|
||||
end
|
||||
|
||||
def marked_for_deletion_on
|
||||
## marked_for_deletion_at is deprecated in our v5 REST API in favor of marked_for_deletion_on
|
||||
## https://docs.gitlab.com/ee/api/projects.html#removals-in-api-v5
|
||||
return unless project.adjourned_deletion?
|
||||
|
||||
project.marked_for_deletion_at
|
||||
end
|
||||
|
||||
def permanent_deletion_date
|
||||
return unless project.adjourned_deletion_configured?
|
||||
|
||||
permanent_deletion_date_formatted(Date.current)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def project
|
||||
|
|
|
|||
|
|
@ -126,6 +126,16 @@ module Ci
|
|||
}
|
||||
end
|
||||
|
||||
def project_runners_settings_data(project)
|
||||
{
|
||||
can_create_runner: can?(current_user, :create_runner, project).to_s,
|
||||
allow_registration_token: project.namespace.allow_runner_registration_token?.to_s,
|
||||
registration_token: can?(current_user, :read_runners_registration_token, project) ? project.runners_token : nil,
|
||||
group_full_path: project.group&.full_path,
|
||||
new_project_runner_path: new_project_runner_path(project)
|
||||
}
|
||||
end
|
||||
|
||||
def toggle_shared_runners_settings_data(project)
|
||||
data = {
|
||||
is_enabled: project.shared_runners_enabled?.to_s,
|
||||
|
|
|
|||
|
|
@ -6,12 +6,22 @@ class List < ApplicationRecord
|
|||
|
||||
belongs_to :board
|
||||
belongs_to :label
|
||||
belongs_to :group
|
||||
belongs_to :project
|
||||
|
||||
has_many :list_user_preferences
|
||||
|
||||
enum list_type: { backlog: 0, label: 1, closed: 2, assignee: 3, milestone: 4, iteration: 5 }
|
||||
|
||||
validates :board, :list_type, presence: true, unless: :importing?
|
||||
validates :label_id, uniqueness: { scope: :board_id }, if: :label?
|
||||
validates :group, presence: true, unless: :project
|
||||
validates :project, presence: true, unless: :group
|
||||
validates :group, absence: {
|
||||
message: ->(_object, _data) { _("can't be specified if a project was already provided") }
|
||||
}, if: :project
|
||||
|
||||
before_validation :ensure_group_or_project
|
||||
|
||||
scope :preload_associated_models, -> { preload(:board, label: :priorities) }
|
||||
|
||||
|
|
@ -47,6 +57,13 @@ class List < ApplicationRecord
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def ensure_group_or_project
|
||||
self.group_id = board&.group_id
|
||||
self.project_id = board&.project_id
|
||||
end
|
||||
end
|
||||
|
||||
List.prepend_mod_with('List')
|
||||
List.prepend_mod
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
- if Feature.enabled?(:vue_project_runners_settings, @project)
|
||||
#js-project-runners-settings
|
||||
#js-project-runners-settings{ data: project_runners_settings_data(@project) }
|
||||
- else
|
||||
.gl-flex.gl-flex-col.gl-gap-5.gl-mt-5
|
||||
= render 'projects/runners/project_runners'
|
||||
|
|
|
|||
|
|
@ -6,4 +6,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/534439
|
|||
milestone: '17.11'
|
||||
group: group::authentication
|
||||
type: beta
|
||||
default_enabled: false
|
||||
default_enabled: true
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/515960
|
|||
milestone: '17.10'
|
||||
type: development
|
||||
group: group::analytics instrumentation
|
||||
default_enabled: false
|
||||
default_enabled: true
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
migration_job_name: BackfillListsShardingKey
|
||||
description: Backfills group_id or project_id for records in the lists table using the boards table.
|
||||
feature_category: team_planning
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/186991
|
||||
milestone: '17.11'
|
||||
queued_migration_version: 20250404130722
|
||||
finalized_by: # version of the migration that finalized this BBM
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RemoveSeatAssignmentsNamespaceIdNotNull < Gitlab::Database::Migration[2.2]
|
||||
disable_ddl_transaction!
|
||||
milestone '17.11'
|
||||
|
||||
def up
|
||||
change_column_null :subscription_seat_assignments, :namespace_id, true
|
||||
end
|
||||
|
||||
def down
|
||||
change_column_null :subscription_seat_assignments, :namespace_id, false
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class CleanupRecordsWithNullNamespaceIdFromSeatAssignments < Gitlab::Database::Migration[2.2]
|
||||
restrict_gitlab_migration gitlab_schema: :gitlab_main
|
||||
disable_ddl_transaction!
|
||||
milestone '17.11'
|
||||
|
||||
BATCH_SIZE = 1000
|
||||
|
||||
class SeatAssignment < MigrationRecord
|
||||
include EachBatch
|
||||
|
||||
self.table_name = 'subscription_seat_assignments'
|
||||
end
|
||||
|
||||
def up
|
||||
# no-op - this migration is required to allow a rollback of `RemoveSeatAssignmentsNamespaceIdNotNull`
|
||||
end
|
||||
|
||||
def down
|
||||
SeatAssignment.each_batch(of: BATCH_SIZE) do |relation|
|
||||
relation
|
||||
.where(namespace_id: nil)
|
||||
.delete_all
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddShardingKeyToListsTable < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.11'
|
||||
|
||||
def change
|
||||
add_column :lists, :group_id, :bigint
|
||||
add_column :lists, :project_id, :bigint
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddDuoNanoEnabledToAiSettings < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.11'
|
||||
|
||||
def change
|
||||
add_column :ai_settings, :duo_nano_features_enabled, :boolean, null: true
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class DisableAiEventsBackfillToChForCom < Gitlab::Database::Migration[2.2]
|
||||
restrict_gitlab_migration gitlab_schema: :gitlab_main
|
||||
|
||||
milestone '17.11'
|
||||
|
||||
def up
|
||||
::Feature.disable(:ai_events_backfill_to_ch) if Gitlab.org_or_com?
|
||||
end
|
||||
|
||||
def down
|
||||
# no-op
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ReplaceSubscriptionSeatAssignmentsNamespaceIdIdx < Gitlab::Database::Migration[2.2]
|
||||
disable_ddl_transaction!
|
||||
milestone '17.11'
|
||||
|
||||
OLD_IDX_NAME = 'uniq_idx_subscription_seat_assignments_on_namespace_and_user'
|
||||
NEW_IDX_NAME = 'uniq_idx_subscription_seat_assignments_on_namespace_id_and_user'
|
||||
|
||||
def up
|
||||
remove_concurrent_index :subscription_seat_assignments, [:namespace_id, :user_id], name: OLD_IDX_NAME
|
||||
|
||||
add_concurrent_index :subscription_seat_assignments, [:namespace_id, :user_id],
|
||||
name: NEW_IDX_NAME, unique: true, where: "namespace_id IS NOT NULL"
|
||||
end
|
||||
|
||||
def down
|
||||
remove_concurrent_index :subscription_seat_assignments, [:namespace_id, :user_id], name: NEW_IDX_NAME
|
||||
add_concurrent_index :subscription_seat_assignments, [:namespace_id, :user_id], name: OLD_IDX_NAME, unique: true
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddListsShardingKeyNotNullConstraint < Gitlab::Database::Migration[2.2]
|
||||
disable_ddl_transaction!
|
||||
milestone '17.11'
|
||||
|
||||
def up
|
||||
add_multi_column_not_null_constraint(:lists, :group_id, :project_id, validate: false)
|
||||
end
|
||||
|
||||
def down
|
||||
remove_multi_column_not_null_constraint(:lists, :group_id, :project_id)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddListsProjectIdIndex < Gitlab::Database::Migration[2.2]
|
||||
INDEX_NAME = 'index_lists_on_project_id'
|
||||
|
||||
disable_ddl_transaction!
|
||||
milestone '17.11'
|
||||
|
||||
def up
|
||||
add_concurrent_index :lists, :project_id, name: INDEX_NAME
|
||||
end
|
||||
|
||||
def down
|
||||
remove_concurrent_index :lists, :project_id, name: INDEX_NAME
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddListsGroupIdIndex < Gitlab::Database::Migration[2.2]
|
||||
INDEX_NAME = 'index_lists_on_group_id'
|
||||
|
||||
disable_ddl_transaction!
|
||||
milestone '17.11'
|
||||
|
||||
def up
|
||||
add_concurrent_index :lists, :group_id, name: INDEX_NAME
|
||||
end
|
||||
|
||||
def down
|
||||
remove_concurrent_index :lists, :group_id, name: INDEX_NAME
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddListsEnsureShardingKeyTrigger < Gitlab::Database::Migration[2.2]
|
||||
include Gitlab::Database::SchemaHelpers
|
||||
|
||||
milestone '17.11'
|
||||
|
||||
LISTS_TABLE = 'lists'
|
||||
|
||||
TRIGGER_FUNCTION_NAME = 'ensure_lists_sharding_key'
|
||||
TRIGGER_NAME = 'trigger_ensure_lists_sharding_key'
|
||||
|
||||
def up
|
||||
create_trigger_function(TRIGGER_FUNCTION_NAME, replace: true) do
|
||||
<<~SQL
|
||||
IF NEW."project_id" IS NULL AND NEW."group_id" IS NULL THEN
|
||||
SELECT "boards"."project_id", "boards"."group_id"
|
||||
INTO NEW."project_id", NEW."group_id"
|
||||
FROM "boards"
|
||||
WHERE "boards"."id" = NEW."board_id";
|
||||
END IF;
|
||||
RETURN NEW;
|
||||
SQL
|
||||
end
|
||||
|
||||
create_trigger(
|
||||
LISTS_TABLE, TRIGGER_NAME, TRIGGER_FUNCTION_NAME, fires: 'BEFORE INSERT OR UPDATE'
|
||||
)
|
||||
end
|
||||
|
||||
def down
|
||||
drop_trigger(LISTS_TABLE, TRIGGER_NAME)
|
||||
drop_function(TRIGGER_FUNCTION_NAME)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddListsProjectIdInvalidFk < Gitlab::Database::Migration[2.2]
|
||||
disable_ddl_transaction!
|
||||
milestone '17.11'
|
||||
|
||||
def up
|
||||
add_concurrent_foreign_key :lists,
|
||||
:projects,
|
||||
column: :project_id,
|
||||
target_column: :id,
|
||||
reverse_lock_order: true,
|
||||
validate: false
|
||||
end
|
||||
|
||||
def down
|
||||
with_lock_retries do
|
||||
remove_foreign_key_if_exists :lists, column: :project_id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddListsGroupIdInvalidFk < Gitlab::Database::Migration[2.2]
|
||||
disable_ddl_transaction!
|
||||
milestone '17.11'
|
||||
|
||||
def up
|
||||
add_concurrent_foreign_key :lists,
|
||||
:namespaces,
|
||||
column: :group_id,
|
||||
target_column: :id,
|
||||
reverse_lock_order: true,
|
||||
validate: false
|
||||
end
|
||||
|
||||
def down
|
||||
with_lock_retries do
|
||||
remove_foreign_key_if_exists :lists, column: :group_id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class QueueBackfillListsShardingKey < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.11'
|
||||
|
||||
restrict_gitlab_migration gitlab_schema: :gitlab_main
|
||||
|
||||
MIGRATION = "BackfillListsShardingKey"
|
||||
BATCH_SIZE = 10000
|
||||
SUB_BATCH_SIZE = 100
|
||||
|
||||
def up
|
||||
queue_batched_background_migration(
|
||||
MIGRATION,
|
||||
:lists,
|
||||
:id,
|
||||
batch_size: BATCH_SIZE,
|
||||
sub_batch_size: SUB_BATCH_SIZE
|
||||
)
|
||||
end
|
||||
|
||||
def down
|
||||
delete_batched_background_migration(MIGRATION, :lists, :id, [])
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
a7ed53fbcc4f62e91897564af3d70dd51ebc9c16bd56ce8faf8dfc0ca5a562e9
|
||||
|
|
@ -0,0 +1 @@
|
|||
f63803345b7ab36f8257fc2fda3953821cec06c5aead52676a0ba47e429e0c87
|
||||
|
|
@ -0,0 +1 @@
|
|||
2e3b372b99288c7bcac5c1aac8bd0a50b848e4b198d69b6739b8666619a6b61b
|
||||
|
|
@ -0,0 +1 @@
|
|||
650dcba158095849fb8e5e4532a41b3731eaf9f04daccf6e7f28cb0a0bef3a23
|
||||
|
|
@ -0,0 +1 @@
|
|||
11b1c67e7353d6b65a23d6949622b2e10ccd5e7c95f072e25bc8f943bbc24ff5
|
||||
|
|
@ -0,0 +1 @@
|
|||
9cc37f08cdf8c98884d78155a0c3289c1efabbcbf6439377ffce65231ac79520
|
||||
|
|
@ -0,0 +1 @@
|
|||
e3835afdbfa2d06ef31f4eb0d47d8a7463ac7b38415e378f759b66296145cff5
|
||||
|
|
@ -0,0 +1 @@
|
|||
4173ca3d43f3a8e990cf729fc6eda5b86979ebfa79e7bc185487e8d06c427c73
|
||||
|
|
@ -0,0 +1 @@
|
|||
7afb4e884d0cb08ee0dec7d8043e28277ccae844a0c51cacf59c648eaca4ee78
|
||||
|
|
@ -0,0 +1 @@
|
|||
db46e72b7285377b0e7a6de03f82366789d4d90106efdf9824a0e98aadde4985
|
||||
|
|
@ -0,0 +1 @@
|
|||
9b89315a16190eb416e6eb76621a1cebf6df98e1fe135a3b0411063c1a1e14b6
|
||||
|
|
@ -0,0 +1 @@
|
|||
7be31444f198efaee82f4c5835657b54fda852472c3753af9c6e04e1c59bb82b
|
||||
|
|
@ -0,0 +1 @@
|
|||
46f7d7fcc1345c80d5b2ecca2a7023c1693f1ec247c7dd18a9b3e556ca56bee6
|
||||
|
|
@ -178,6 +178,21 @@ RETURN NULL;
|
|||
END
|
||||
$$;
|
||||
|
||||
CREATE FUNCTION ensure_lists_sharding_key() RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
BEGIN
|
||||
IF NEW."project_id" IS NULL AND NEW."group_id" IS NULL THEN
|
||||
SELECT "boards"."project_id", "boards"."group_id"
|
||||
INTO NEW."project_id", NEW."group_id"
|
||||
FROM "boards"
|
||||
WHERE "boards"."id" = NEW."board_id";
|
||||
END IF;
|
||||
RETURN NEW;
|
||||
|
||||
END
|
||||
$$;
|
||||
|
||||
CREATE TABLE namespaces (
|
||||
id bigint NOT NULL,
|
||||
name character varying NOT NULL,
|
||||
|
|
@ -7984,6 +7999,7 @@ CREATE TABLE ai_settings (
|
|||
amazon_q_role_arn text,
|
||||
duo_workflow_service_account_user_id bigint,
|
||||
duo_workflow_oauth_application_id bigint,
|
||||
duo_nano_features_enabled boolean,
|
||||
CONSTRAINT check_3cf9826589 CHECK ((char_length(ai_gateway_url) <= 2048)),
|
||||
CONSTRAINT check_a02bd8868c CHECK ((char_length(amazon_q_role_arn) <= 2048)),
|
||||
CONSTRAINT check_singleton CHECK ((singleton IS TRUE))
|
||||
|
|
@ -16807,7 +16823,9 @@ CREATE TABLE lists (
|
|||
max_issue_count integer DEFAULT 0 NOT NULL,
|
||||
max_issue_weight integer DEFAULT 0 NOT NULL,
|
||||
limit_metric character varying(20),
|
||||
iteration_id bigint
|
||||
iteration_id bigint,
|
||||
group_id bigint,
|
||||
project_id bigint
|
||||
);
|
||||
|
||||
CREATE SEQUENCE lists_id_seq
|
||||
|
|
@ -23338,7 +23356,7 @@ ALTER SEQUENCE subscription_add_ons_id_seq OWNED BY subscription_add_ons.id;
|
|||
|
||||
CREATE TABLE subscription_seat_assignments (
|
||||
id bigint NOT NULL,
|
||||
namespace_id bigint NOT NULL,
|
||||
namespace_id bigint,
|
||||
user_id bigint NOT NULL,
|
||||
last_activity_on timestamp with time zone,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
|
|
@ -29033,6 +29051,9 @@ ALTER TABLE ONLY instance_type_ci_runners
|
|||
ALTER TABLE ONLY project_type_ci_runners
|
||||
ADD CONSTRAINT check_619c71f3a2 UNIQUE (id);
|
||||
|
||||
ALTER TABLE lists
|
||||
ADD CONSTRAINT check_6dadb82d36 CHECK ((num_nonnulls(group_id, project_id) = 1)) NOT VALID;
|
||||
|
||||
ALTER TABLE description_versions
|
||||
ADD CONSTRAINT check_76c1eb7122 CHECK ((num_nonnulls(epic_id, issue_id, merge_request_id) = 1)) NOT VALID;
|
||||
|
||||
|
|
@ -35634,6 +35655,8 @@ CREATE UNIQUE INDEX index_list_user_preferences_on_user_id_and_list_id ON list_u
|
|||
|
||||
CREATE UNIQUE INDEX index_lists_on_board_id_and_label_id ON lists USING btree (board_id, label_id);
|
||||
|
||||
CREATE INDEX index_lists_on_group_id ON lists USING btree (group_id);
|
||||
|
||||
CREATE INDEX index_lists_on_iteration_id ON lists USING btree (iteration_id);
|
||||
|
||||
CREATE INDEX index_lists_on_label_id ON lists USING btree (label_id);
|
||||
|
|
@ -35642,6 +35665,8 @@ CREATE INDEX index_lists_on_list_type ON lists USING btree (list_type);
|
|||
|
||||
CREATE INDEX index_lists_on_milestone_id ON lists USING btree (milestone_id);
|
||||
|
||||
CREATE INDEX index_lists_on_project_id ON lists USING btree (project_id);
|
||||
|
||||
CREATE INDEX index_lists_on_user_id ON lists USING btree (user_id);
|
||||
|
||||
CREATE INDEX index_loose_foreign_keys_deleted_records_for_partitioned_query ON ONLY loose_foreign_keys_deleted_records USING btree (partition, fully_qualified_table_name, consume_after, id) WHERE (status = 1);
|
||||
|
|
@ -38488,7 +38513,7 @@ CREATE UNIQUE INDEX uniq_idx_streaming_destination_id_and_namespace_id ON audit_
|
|||
|
||||
CREATE UNIQUE INDEX uniq_idx_streaming_group_destination_id_and_namespace_id ON audit_events_streaming_group_namespace_filters USING btree (external_streaming_destination_id, namespace_id);
|
||||
|
||||
CREATE UNIQUE INDEX uniq_idx_subscription_seat_assignments_on_namespace_and_user ON subscription_seat_assignments USING btree (namespace_id, user_id);
|
||||
CREATE UNIQUE INDEX uniq_idx_subscription_seat_assignments_on_namespace_id_and_user ON subscription_seat_assignments USING btree (namespace_id, user_id) WHERE (namespace_id IS NOT NULL);
|
||||
|
||||
CREATE UNIQUE INDEX uniq_idx_user_add_on_assignments_on_add_on_purchase_and_user ON subscription_user_add_on_assignments USING btree (add_on_purchase_id, user_id);
|
||||
|
||||
|
|
@ -41580,6 +41605,8 @@ CREATE TRIGGER trigger_efb9d354f05a BEFORE INSERT OR UPDATE ON incident_manageme
|
|||
|
||||
CREATE TRIGGER trigger_eff80ead42ac BEFORE INSERT OR UPDATE ON ci_unit_test_failures FOR EACH ROW EXECUTE FUNCTION trigger_eff80ead42ac();
|
||||
|
||||
CREATE TRIGGER trigger_ensure_lists_sharding_key BEFORE INSERT OR UPDATE ON lists FOR EACH ROW EXECUTE FUNCTION ensure_lists_sharding_key();
|
||||
|
||||
CREATE TRIGGER trigger_f6c61cdddf31 BEFORE INSERT OR UPDATE ON ml_model_metadata FOR EACH ROW EXECUTE FUNCTION trigger_f6c61cdddf31();
|
||||
|
||||
CREATE TRIGGER trigger_f6f59d8216b3 BEFORE INSERT OR UPDATE ON protected_environment_deploy_access_levels FOR EACH ROW EXECUTE FUNCTION trigger_f6f59d8216b3();
|
||||
|
|
@ -42518,6 +42545,9 @@ ALTER TABLE p_ci_builds
|
|||
ALTER TABLE ONLY routes
|
||||
ADD CONSTRAINT fk_679ff8213d FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE NOT VALID;
|
||||
|
||||
ALTER TABLE ONLY lists
|
||||
ADD CONSTRAINT fk_67f2498cc9 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE NOT VALID;
|
||||
|
||||
ALTER TABLE ONLY merge_requests_approval_rules_approver_groups
|
||||
ADD CONSTRAINT fk_67fa93ad4b FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
|
||||
|
||||
|
|
@ -43742,6 +43772,9 @@ ALTER TABLE ONLY cluster_agents
|
|||
ALTER TABLE ONLY protected_tag_create_access_levels
|
||||
ADD CONSTRAINT fk_f7dfda8c51 FOREIGN KEY (protected_tag_id) REFERENCES protected_tags(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY lists
|
||||
ADD CONSTRAINT fk_f8b2e8680c FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE NOT VALID;
|
||||
|
||||
ALTER TABLE ONLY project_requirement_compliance_statuses
|
||||
ADD CONSTRAINT fk_f9109a4712 FOREIGN KEY (compliance_framework_id) REFERENCES compliance_management_frameworks(id) ON DELETE CASCADE;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ title: Auditor users
|
|||
{{< details >}}
|
||||
|
||||
- Tier: Premium, Ultimate
|
||||
- Offering: GitLab Self-Managed
|
||||
- Offering: GitLab Self-Managed, GitLab Dedicated
|
||||
|
||||
{{< /details >}}
|
||||
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ IPv6 address. If you don't have IPv6, you can omit the `AAAA` record.
|
|||
To configure GitLab Pages DNS for single-domain sites without wildcard DNS:
|
||||
|
||||
1. Enable the GitLab Pages flag for this feature by adding
|
||||
`gitlab_pages["namespace_in_path"] = true` to `/etc/gitlab/gitlab.rb`.
|
||||
`gitlab_pages['namespace_in_path'] = true` to `/etc/gitlab/gitlab.rb`.
|
||||
1. In your DNS provider, add entries for `example.io`.
|
||||
Replace `example.io` with your domain name, and `192.0.0.0` with
|
||||
the IPv4 version of your IP address. The entries look like this:
|
||||
|
|
@ -268,7 +268,7 @@ To configure GitLab Pages to use single-domain sites:
|
|||
pages_external_url 'http://example.io' # Important: not a subdomain of external_url, so cannot be http://pages.example.com
|
||||
|
||||
# Set this flag to enable this feature
|
||||
gitlab_pages["namespace_in_path"] = true
|
||||
gitlab_pages['namespace_in_path'] = true
|
||||
```
|
||||
|
||||
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation).
|
||||
|
|
@ -363,7 +363,7 @@ daemon doesn't listen to the public internet:
|
|||
pages_nginx['redirect_http_to_https'] = true
|
||||
|
||||
# Set this flag to enable this feature
|
||||
gitlab_pages["namespace_in_path"] = true
|
||||
gitlab_pages['namespace_in_path'] = true
|
||||
```
|
||||
|
||||
1. If your TLS certificate and key don't match the name of your domain, like
|
||||
|
|
|
|||
|
|
@ -41738,6 +41738,7 @@ AI features that can be configured through the Duo self-hosted feature settings.
|
|||
| <a id="aifeaturesduo_chat_explain_vulnerability"></a>`DUO_CHAT_EXPLAIN_VULNERABILITY` | Duo chat explain vulnerability feature setting. |
|
||||
| <a id="aifeaturesduo_chat_fix_code"></a>`DUO_CHAT_FIX_CODE` | Duo chat fix code feature setting. |
|
||||
| <a id="aifeaturesduo_chat_refactor_code"></a>`DUO_CHAT_REFACTOR_CODE` | Duo chat refactor code feature setting. |
|
||||
| <a id="aifeaturesduo_chat_summarize_comments"></a>`DUO_CHAT_SUMMARIZE_COMMENTS` | Duo chat summarize comment feature setting. |
|
||||
| <a id="aifeaturesduo_chat_troubleshoot_job"></a>`DUO_CHAT_TROUBLESHOOT_JOB` | Duo chat troubleshoot job feature setting. |
|
||||
| <a id="aifeaturesduo_chat_write_tests"></a>`DUO_CHAT_WRITE_TESTS` | Duo chat write test feature setting. |
|
||||
| <a id="aifeaturesgenerate_commit_message"></a>`GENERATE_COMMIT_MESSAGE` | Generate commit message feature setting. |
|
||||
|
|
|
|||
|
|
@ -25,20 +25,13 @@ see [Conan packages in the package registry](../../user/packages/conan_repositor
|
|||
Generally, these endpoints are used by the [Conan 1 package manager client](https://docs.conan.io/en/latest/)
|
||||
and are not meant for manual consumption.
|
||||
|
||||
For instructions on how to upload and install Conan packages from the GitLab
|
||||
package registry, see the [Conan package registry documentation](../../user/packages/conan_repository/_index.md).
|
||||
|
||||
{{< alert type="note" >}}
|
||||
|
||||
These endpoints do not adhere to the standard API authentication methods.
|
||||
- These endpoints do not adhere to the standard API authentication methods.
|
||||
See each route for details on how credentials are expected to be passed. Undocumented authentication methods might be removed in the future.
|
||||
|
||||
{{< /alert >}}
|
||||
|
||||
{{< alert type="note" >}}
|
||||
|
||||
The Conan registry is not FIPS compliant and is disabled when [FIPS mode](../../development/fips_gitlab.md) is enabled.
|
||||
These endpoints will all return 404 Not Found.
|
||||
- The Conan registry is not FIPS compliant and is disabled when [FIPS mode](../../development/fips_gitlab.md) is enabled.
|
||||
These endpoints all return `404 Not Found`.
|
||||
|
||||
{{< /alert >}}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,37 +18,30 @@ title: Conan v2 API
|
|||
|
||||
{{< /history >}}
|
||||
|
||||
{{< alert type="note" >}}
|
||||
|
||||
For Conan v1 operations, see [Conan v1 API](conan_v1.md).
|
||||
|
||||
{{< /alert >}}
|
||||
|
||||
Use this API to interact with the Conan v2 package manager. For more information, see [Conan packages in the package registry](../../user/packages/conan_repository/_index.md).
|
||||
|
||||
{{< alert type="flag" >}}
|
||||
|
||||
The availability of this feature is controlled by a feature flag. For more information, see the history.
|
||||
|
||||
{{< /alert >}}
|
||||
|
||||
Generally, these endpoints are used by the [Conan 2 package manager client](https://docs.conan.io/2/index.html)
|
||||
and are not meant for manual consumption.
|
||||
|
||||
For instructions on how to upload and install Conan packages from the GitLab
|
||||
package registry, see the [Conan package registry documentation](../../user/packages/conan_repository/_index.md) and [Conan 2 package manager client](https://docs.conan.io/2/index.html).
|
||||
|
||||
{{< alert type="note" >}}
|
||||
|
||||
These endpoints do not adhere to the standard API authentication methods.
|
||||
See each route for details on how credentials are expected to be passed. Undocumented authentication methods might be removed in the future.
|
||||
For Conan v1 operations, see [Conan v1 API](conan_v1.md).
|
||||
|
||||
{{< /alert >}}
|
||||
|
||||
Use this API to interact with the Conan v2 package manager. For more information, see [Conan packages in the package registry](../../user/packages/conan_repository/_index.md) or [Conan 2 package manager client](https://docs.conan.io/2/index.html).
|
||||
|
||||
Generally, these endpoints are used by the [Conan 2 package manager client](https://docs.conan.io/2/index.html)
|
||||
and are not meant for manual consumption.
|
||||
|
||||
{{< alert type="note" >}}
|
||||
|
||||
The Conan registry is not FIPS compliant and is disabled when [FIPS mode](../../development/fips_gitlab.md) is enabled.
|
||||
These endpoints will all return 404 Not Found.
|
||||
- These endpoints do not adhere to the standard API authentication methods.
|
||||
See each route for details on how credentials are expected to be passed. Undocumented authentication methods might be removed in the future.
|
||||
|
||||
- The Conan registry is not FIPS compliant and is disabled when [FIPS mode](../../development/fips_gitlab.md) is enabled.
|
||||
These endpoints all return `404 Not Found`.
|
||||
{{< /alert >}}
|
||||
|
||||
## Route prefix
|
||||
|
|
|
|||
|
|
@ -9,11 +9,7 @@ Now for the fun part. Let's edit some code.
|
|||
|
||||
In this example, I found some UI text I'd like to change.
|
||||
In the upper-right corner in GitLab, I selected my avatar and then **Preferences**.
|
||||
I want to change `Customize the color of GitLab` to `Customize the color theme of the GitLab UI`:
|
||||
|
||||

|
||||
|
||||
[View an interactive demo of this section](https://gitlab.navattic.com/uu5a0dc5).
|
||||
I want to change `Syntax highlighting theme` to `Code syntax highlighting theme`:
|
||||
|
||||
Use your local IDE to make changes to the code in the GDK directory.
|
||||
|
||||
|
|
@ -23,13 +19,12 @@ Use your local IDE to make changes to the code in the GDK directory.
|
|||
git checkout -b ui-updates
|
||||
```
|
||||
|
||||
1. Search the `gitlab-development-kit/gitlab` directory for the string `Customize the color of GitLab`.
|
||||
|
||||
1. Search the `gitlab-development-kit/gitlab` directory for the string `Syntax highlighting theme`.
|
||||
The results show one `.haml` file and several `.po` files.
|
||||
|
||||
1. Open the `app/views/profiles/preferences/show.html.haml` file.
|
||||
1. Update the string from `Customize the color of GitLab` to
|
||||
`Customize the color theme of the GitLab UI`.
|
||||
1. Update the string from `Syntax highlighting theme` to
|
||||
`Code syntax highlighting theme`.
|
||||
1. Save the file.
|
||||
1. You can check that you were successful:
|
||||
|
||||
|
|
@ -43,8 +38,6 @@ Use your local IDE to make changes to the code in the GDK directory.
|
|||
1. Refresh the web browser where you're viewing the GDK.
|
||||
The changes should be displayed. Take a screenshot.
|
||||
|
||||

|
||||
|
||||
1. Commit the changes:
|
||||
|
||||
```shell
|
||||
|
|
|
|||
|
|
@ -9,9 +9,7 @@ Now for the fun part. Let's edit some code.
|
|||
|
||||
In this example, I found some UI text I'd like to change.
|
||||
In the upper-right corner in GitLab, I selected my avatar and then **Preferences**.
|
||||
I want to change `Customize the color of GitLab` to `Customize the color theme of the GitLab UI`:
|
||||
|
||||

|
||||
I want to change `Syntax highlighting theme` to `Code syntax highlighting theme`:
|
||||
|
||||
1. Create a new branch for your changes:
|
||||
|
||||
|
|
@ -22,12 +20,12 @@ I want to change `Customize the color of GitLab` to `Customize the color theme o
|
|||
|
||||
The examples in this doc use a new branch called `ui-updates`.
|
||||
|
||||
1. Search the repository for the string `Customize the color of GitLab`:
|
||||
1. Search the repository for the string `Syntax highlighting theme`:
|
||||
|
||||
- In VS Code, select the search icon <i class="fa fa-search fa-flip-horizontal" aria-hidden="true"></i> from the side toolbar.
|
||||
|
||||
1. Select the `app/views/profiles/preferences/show.html.haml` file.
|
||||
1. Update the string to `Customize the color theme of the GitLab UI`.
|
||||
1. Update the string to `Code syntax highlighting theme`.
|
||||
1. Save your changes.
|
||||
1. Use the IDE **Terminal** tab to commit the changes:
|
||||
|
||||
|
|
@ -36,7 +34,7 @@ I want to change `Customize the color of GitLab` to `Customize the color theme o
|
|||
|
||||
Standardizing the text on this page so
|
||||
that each area uses consistent language."
|
||||
```
|
||||
```
|
||||
|
||||
Follow the GitLab
|
||||
[commit message guidelines](../merge_request_workflow.md#commit-messages-guidelines).
|
||||
|
|
|
|||
|
|
@ -12,21 +12,21 @@ to GitLab code using the Web IDE.
|
|||
|
||||
1. Go to the [GitLab community fork](https://gitlab.com/gitlab-community/gitlab).
|
||||
|
||||
1. Search the GitLab code for the string `Customize the color of GitLab`.
|
||||
1. Search the GitLab code for the string `Syntax highlighting theme`.
|
||||
From the [GitLab Community Fork](https://gitlab.com/gitlab-community/gitlab):
|
||||
|
||||
1. On the left sidebar, select **Search or go to**.
|
||||
1. Enter the search string `"Customize the color of GitLab"`.
|
||||
1. Enter the search string `"Syntax highlighting theme"`.
|
||||
|
||||
1. Select the filename
|
||||
[from the results](https://gitlab.com/search?search=%22Customize+the+color+of+GitLab%22&nav_source=navbar&project_id=41372369&group_id=60717473&search_code=true).
|
||||
[from the results](https://gitlab.com/search?search=%22Syntax+highlighting+theme%22&nav_source=navbar&project_id=41372369&group_id=60717473&search_code=true).
|
||||
In this case, `app/views/profiles/preferences/show.html.haml`.
|
||||
|
||||
1. Open the file in Web IDE. Select **Edit > Open in Web IDE**.
|
||||
|
||||
- Keyboard shortcut: <kbd>.</kbd>
|
||||
|
||||
1. Update the string from `Customize the color of GitLab` to `Customize the color theme of the GitLab UI`.
|
||||
1. Update the string from `Syntax highlighting theme` to `Code syntax highlighting theme`.
|
||||
|
||||
1. Save your changes.
|
||||
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ See also [guidelines for heading levels in Markdown](../styleguide/_index.md#hea
|
|||
|
||||
## Related topics
|
||||
|
||||
If inline links are not sufficient, you can create a topic called **Related topics**
|
||||
If inline links are not sufficient, you can create a section called **Related topics**
|
||||
and include an unordered list of related topics. This topic should be above the Troubleshooting section.
|
||||
|
||||
Links in this section should be brief and scannable. They are usually not
|
||||
|
|
|
|||
|
|
@ -148,7 +148,6 @@ install, and upgrade your Docker-based GitLab installation:
|
|||
1. Create a `docker-compose.yml` file. For example:
|
||||
|
||||
```yaml
|
||||
version: '3.6'
|
||||
services:
|
||||
gitlab:
|
||||
image: gitlab/gitlab-ee:<version>-ee.0
|
||||
|
|
@ -182,7 +181,6 @@ install, and upgrade your Docker-based GitLab installation:
|
|||
`ports` section:
|
||||
|
||||
```yaml
|
||||
version: '3.6'
|
||||
services:
|
||||
gitlab:
|
||||
image: gitlab/gitlab-ee:<version>-ee.0
|
||||
|
|
@ -302,7 +300,6 @@ Here's an example that deploys GitLab with four runners as a [stack](https://doc
|
|||
1. Create a `docker-compose.yml` file:
|
||||
|
||||
```yaml
|
||||
version: "3.6"
|
||||
services:
|
||||
gitlab:
|
||||
image: gitlab/gitlab-ee:<version>-ee.0
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ For more information on:
|
|||
label: "Provider name", # optional label for login button, defaults to "Saml"
|
||||
args: {
|
||||
assertion_consumer_service_url: "https://gitlab.example.com/users/auth/saml/callback",
|
||||
idp_cert_fingerprint: "43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8",
|
||||
idp_cert_fingerprint: "2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6",
|
||||
idp_sso_target_url: "https://login.example.com/idp",
|
||||
issuer: "https://gitlab.example.com",
|
||||
name_identifier_format: "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
|
||||
|
|
@ -83,18 +83,15 @@ For more information on:
|
|||
]
|
||||
```
|
||||
|
||||
Where:
|
||||
| Argument | Description |
|
||||
| -------------------------------- | ----------- |
|
||||
| `assertion_consumer_service_url` | The GitLab HTTPS endpoint (append `/users/auth/saml/callback` to the HTTPS URL of your GitLab installation). |
|
||||
| `idp_cert_fingerprint` | Your IdP value. To generate the SHA256 fingerprint from the certificate, see [calculate the fingerprint](../user/group/saml_sso/troubleshooting.md#calculate-the-fingerprint). |
|
||||
| `idp_sso_target_url` | Your IdP value. |
|
||||
| `issuer` | Change to a unique name, which identifies the application to the IdP. |
|
||||
| `name_identifier_format` | Your IdP value. |
|
||||
|
||||
- `assertion_consumer_service_url`: The GitLab HTTPS endpoint
|
||||
(append `/users/auth/saml/callback` to the HTTPS URL of your GitLab installation).
|
||||
- `idp_cert_fingerprint`: Your IdP value. It must be a SHA1 fingerprint.
|
||||
For more information on these values, see the
|
||||
[OmniAuth SAML documentation](https://github.com/omniauth/omniauth-saml).
|
||||
For more information on other configuration settings, see
|
||||
[configuring SAML on your IdP](#configure-saml-on-your-idp).
|
||||
- `idp_sso_target_url`: Your IdP value.
|
||||
- `issuer`: Change to a unique name, which identifies the application to the IdP.
|
||||
- `name_identifier_format`: Your IdP value.
|
||||
For more information on these values, see the [OmniAuth SAML documentation](https://github.com/omniauth/omniauth-saml). For more information on other configuration settings, see [configuring SAML on your IdP](#configure-saml-on-your-idp).
|
||||
|
||||
1. Save the file and reconfigure GitLab:
|
||||
|
||||
|
|
@ -158,24 +155,21 @@ For more information on:
|
|||
label: 'Provider name' # optional label for login button, defaults to "Saml"
|
||||
args:
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback'
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8'
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6'
|
||||
idp_sso_target_url: 'https://login.example.com/idp'
|
||||
issuer: 'https://gitlab.example.com'
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
|
||||
```
|
||||
|
||||
Where:
|
||||
| Argument | Description |
|
||||
| -------------------------------- | ----------- |
|
||||
| `assertion_consumer_service_url` | The GitLab HTTPS endpoint (append `/users/auth/saml/callback` to the HTTPS URL of your GitLab installation). |
|
||||
| `idp_cert_fingerprint` | Your IdP value. To generate the SHA256 fingerprint from the certificate, see [calculate the fingerprint](../user/group/saml_sso/troubleshooting.md#calculate-the-fingerprint). |
|
||||
| `idp_sso_target_url` | Your IdP value. |
|
||||
| `issuer` | Change to a unique name, which identifies the application to the IdP. |
|
||||
| `name_identifier_format` | Your IdP value. |
|
||||
|
||||
- `assertion_consumer_service_url`: The GitLab HTTPS endpoint
|
||||
(append `/users/auth/saml/callback` to the HTTPS URL of your GitLab installation).
|
||||
- `idp_cert_fingerprint`: Your IdP value. It must be a SHA1 fingerprint.
|
||||
For more information on these values, see the
|
||||
[OmniAuth SAML documentation](https://github.com/omniauth/omniauth-saml).
|
||||
For more information on other configuration settings, see
|
||||
[configuring SAML on your IdP](#configure-saml-on-your-idp).
|
||||
- `idp_sso_target_url`: Your IdP value.
|
||||
- `issuer`: Change to a unique name, which identifies the application to the IdP.
|
||||
- `name_identifier_format`: Your IdP value.
|
||||
For more information on these values, see the [OmniAuth SAML documentation](https://github.com/omniauth/omniauth-saml). For more information on other configuration settings, see [configuring SAML on your IdP](#configure-saml-on-your-idp).
|
||||
|
||||
1. Create the Kubernetes Secret:
|
||||
|
||||
|
|
@ -258,7 +252,7 @@ For more information on:
|
|||
label: "Provider name", # optional label for login button, defaults to "Saml"
|
||||
args: {
|
||||
assertion_consumer_service_url: "https://gitlab.example.com/users/auth/saml/callback",
|
||||
idp_cert_fingerprint: "43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8",
|
||||
idp_cert_fingerprint: "2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6",
|
||||
idp_sso_target_url: "https://login.example.com/idp",
|
||||
issuer: "https://gitlab.example.com",
|
||||
name_identifier_format: "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
|
||||
|
|
@ -267,18 +261,15 @@ For more information on:
|
|||
]
|
||||
```
|
||||
|
||||
Where:
|
||||
| Argument | Description |
|
||||
| -------------------------------- | ----------- |
|
||||
| `assertion_consumer_service_url` | The GitLab HTTPS endpoint (append `/users/auth/saml/callback` to the HTTPS URL of your GitLab installation). |
|
||||
| `idp_cert_fingerprint` | Your IdP value. To generate the SHA256 fingerprint from the certificate, see [calculate the fingerprint](../user/group/saml_sso/troubleshooting.md#calculate-the-fingerprint). |
|
||||
| `idp_sso_target_url` | Your IdP value. |
|
||||
| `issuer` | Change to a unique name, which identifies the application to the IdP. |
|
||||
| `name_identifier_format` | Your IdP value. |
|
||||
|
||||
- `assertion_consumer_service_url`: The GitLab HTTPS endpoint
|
||||
(append `/users/auth/saml/callback` to the HTTPS URL of your GitLab installation).
|
||||
- `idp_cert_fingerprint`: Your IdP value. It must be a SHA1 fingerprint.
|
||||
For more information on these values, see the
|
||||
[OmniAuth SAML documentation](https://github.com/omniauth/omniauth-saml).
|
||||
For more information on other configuration settings, see
|
||||
[configuring SAML on your IdP](#configure-saml-on-your-idp).
|
||||
- `idp_sso_target_url`: Your IdP value.
|
||||
- `issuer`: Change to a unique name, which identifies the application to the IdP.
|
||||
- `name_identifier_format`: Your IdP value.
|
||||
For more information on these values, see the [OmniAuth SAML documentation](https://github.com/omniauth/omniauth-saml). For more information on other configuration settings, see [configuring SAML on your IdP](#configure-saml-on-your-idp).
|
||||
|
||||
1. Save the file and restart GitLab:
|
||||
|
||||
|
|
@ -336,7 +327,7 @@ For more information on:
|
|||
label: 'Provider name', # optional label for login button, defaults to "Saml"
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
|
||||
|
|
@ -344,18 +335,15 @@ For more information on:
|
|||
}
|
||||
```
|
||||
|
||||
Where:
|
||||
| Argument | Description |
|
||||
| -------------------------------- | ----------- |
|
||||
| `assertion_consumer_service_url` | The GitLab HTTPS endpoint (append `/users/auth/saml/callback` to the HTTPS URL of your GitLab installation). |
|
||||
| `idp_cert_fingerprint` | Your IdP value. To generate the SHA256 fingerprint from the certificate, see [calculate the fingerprint](../user/group/saml_sso/troubleshooting.md#calculate-the-fingerprint). |
|
||||
| `idp_sso_target_url` | Your IdP value. |
|
||||
| `issuer` | Change to a unique name, which identifies the application to the IdP. |
|
||||
| `name_identifier_format` | Your IdP value. |
|
||||
|
||||
- `assertion_consumer_service_url`: The GitLab HTTPS endpoint
|
||||
(append `/users/auth/saml/callback` to the HTTPS URL of your GitLab installation).
|
||||
- `idp_cert_fingerprint`: Your IdP value. It must be a SHA1 fingerprint.
|
||||
For more information on these values, see the
|
||||
[OmniAuth SAML documentation](https://github.com/omniauth/omniauth-saml).
|
||||
For more information on other configuration settings, see
|
||||
[configuring SAML on your IdP](#configure-saml-on-your-idp).
|
||||
- `idp_sso_target_url`: Your IdP value.
|
||||
- `issuer`: Change to a unique name, which identifies the application to the IdP.
|
||||
- `name_identifier_format`: Your IdP value.
|
||||
For more information on these values, see the [OmniAuth SAML documentation](https://github.com/omniauth/omniauth-saml). For more information on other configuration settings, see [configuring SAML on your IdP](#configure-saml-on-your-idp).
|
||||
|
||||
1. Save the file and restart GitLab:
|
||||
|
||||
|
|
@ -720,10 +708,11 @@ To set up a Google Workspace:
|
|||
|
||||
When configuring the Google Workspace SAML application, record the following information:
|
||||
|
||||
| | Value | Description |
|
||||
|-------------|--------------|-----------------------------------------------------------------------------------|
|
||||
| SSO URL | Depends | Google Identity Provider details. Set to the GitLab `idp_sso_target_url` setting. |
|
||||
| Certificate | Downloadable | Run `openssl x509 -in <your_certificate.crt> -noout -fingerprint -sha1` to generate the SHA1 fingerprint that can be used in the `idp_cert_fingerprint` setting. |
|
||||
| | Value | Description |
|
||||
| ------------------ | ------------ | ----------- |
|
||||
| SSO URL | Depends | Google Identity Provider details. Set to the GitLab `idp_sso_target_url` setting. |
|
||||
| Certificate | Downloadable | Google SAML certificate. |
|
||||
| SHA256 fingerprint | Depends | Available when you download the certificate. To generate the SHA256 fingerprint from the certificate, see [calculate the fingerprint](../user/group/saml_sso/troubleshooting.md#calculate-the-fingerprint). |
|
||||
|
||||
Google Workspace Administrator also provides the IdP metadata, Entity ID, and SHA-256
|
||||
fingerprint. However, GitLab does not need this information to connect to the
|
||||
|
|
@ -940,7 +929,7 @@ If the attribute specified in `groups_attribute` is incorrect or missing then al
|
|||
required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors'],
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
|
||||
|
|
@ -969,7 +958,7 @@ If the attribute specified in `groups_attribute` is incorrect or missing then al
|
|||
required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors']
|
||||
args:
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback'
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8'
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6'
|
||||
idp_sso_target_url: 'https://login.example.com/idp'
|
||||
issuer: 'https://gitlab.example.com'
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
|
||||
|
|
@ -1022,7 +1011,7 @@ If the attribute specified in `groups_attribute` is incorrect or missing then al
|
|||
required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors'],
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
|
||||
|
|
@ -1053,7 +1042,7 @@ If the attribute specified in `groups_attribute` is incorrect or missing then al
|
|||
required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors'],
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
|
||||
|
|
@ -1111,7 +1100,7 @@ Example configuration:
|
|||
external_groups: ['Freelancers'],
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
|
||||
|
|
@ -1140,7 +1129,7 @@ Example configuration:
|
|||
external_groups: ['Freelancers']
|
||||
args:
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback'
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8'
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6'
|
||||
idp_sso_target_url: 'https://login.example.com/idp'
|
||||
issuer: 'https://gitlab.example.com'
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
|
||||
|
|
@ -1193,7 +1182,7 @@ Example configuration:
|
|||
external_groups: ['Freelancers'],
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
|
||||
|
|
@ -1224,7 +1213,7 @@ Example configuration:
|
|||
external_groups: ['Freelancers'],
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
|
||||
|
|
@ -1275,7 +1264,7 @@ Example configuration:
|
|||
admin_groups: ['Admins'],
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
|
||||
|
|
@ -1304,7 +1293,7 @@ Example configuration:
|
|||
admin_groups: ['Admins']
|
||||
args:
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback'
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8'
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6'
|
||||
idp_sso_target_url: 'https://login.example.com/idp'
|
||||
issuer: 'https://gitlab.example.com'
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
|
||||
|
|
@ -1357,7 +1346,7 @@ Example configuration:
|
|||
admin_groups: ['Admins'],
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
|
||||
|
|
@ -1388,7 +1377,7 @@ Example configuration:
|
|||
admin_groups: ['Admins'],
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
|
||||
|
|
@ -1446,7 +1435,7 @@ Example configuration:
|
|||
auditor_groups: ['Auditors'],
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
|
||||
|
|
@ -1475,7 +1464,7 @@ Example configuration:
|
|||
auditor_groups: ['Auditors']
|
||||
args:
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback'
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8'
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6'
|
||||
idp_sso_target_url: 'https://login.example.com/idp'
|
||||
issuer: 'https://gitlab.example.com'
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
|
||||
|
|
@ -1528,7 +1517,7 @@ Example configuration:
|
|||
auditor_groups: ['Auditors'],
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
|
||||
|
|
@ -1559,7 +1548,7 @@ Example configuration:
|
|||
auditor_groups: ['Auditors'],
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
|
||||
|
|
@ -1623,7 +1612,7 @@ list.
|
|||
label: 'Our SAML Provider',
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
|
||||
|
|
@ -1656,7 +1645,7 @@ list.
|
|||
label: 'Our SAML Provider'
|
||||
args:
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback'
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8'
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6'
|
||||
idp_sso_target_url: 'https://login.example.com/idp'
|
||||
issuer: 'https://gitlab.example.com'
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
|
||||
|
|
@ -1711,7 +1700,7 @@ list.
|
|||
label: 'Our SAML Provider',
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
|
||||
|
|
@ -1746,7 +1735,7 @@ list.
|
|||
label: 'Our SAML Provider',
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
|
||||
|
|
@ -1798,7 +1787,7 @@ An example configuration:
|
|||
label: 'Our SAML Provider',
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
|
||||
|
|
@ -1825,7 +1814,7 @@ An example configuration:
|
|||
label: 'Our SAML Provider'
|
||||
args:
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback'
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8'
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6'
|
||||
idp_sso_target_url: 'https://login.example.com/idp'
|
||||
issuer: 'https://gitlab.example.com'
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
|
||||
|
|
@ -1876,7 +1865,7 @@ An example configuration:
|
|||
label: 'Our SAML Provider',
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
|
||||
|
|
@ -1905,7 +1894,7 @@ An example configuration:
|
|||
label: 'Our SAML Provider',
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
|
||||
|
|
@ -2237,7 +2226,7 @@ instead of `email`, let GitLab know by setting it on your configuration:
|
|||
label: 'Our SAML Provider',
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
|
||||
|
|
@ -2265,7 +2254,7 @@ instead of `email`, let GitLab know by setting it on your configuration:
|
|||
label: 'Our SAML Provider'
|
||||
args:
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback'
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8'
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6'
|
||||
idp_sso_target_url: 'https://login.example.com/idp'
|
||||
issuer: 'https://gitlab.example.com'
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
|
||||
|
|
@ -2318,7 +2307,7 @@ instead of `email`, let GitLab know by setting it on your configuration:
|
|||
label: 'Our SAML Provider',
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
|
||||
|
|
@ -2348,7 +2337,7 @@ instead of `email`, let GitLab know by setting it on your configuration:
|
|||
label: 'Our SAML Provider',
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
|
||||
|
|
@ -2390,7 +2379,7 @@ Configure [`username` or `nickname`](omniauth.md#per-provider-configuration) in
|
|||
label: 'Our SAML Provider',
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
|
||||
|
|
@ -2418,7 +2407,7 @@ Configure [`username` or `nickname`](omniauth.md#per-provider-configuration) in
|
|||
label: 'Our SAML Provider'
|
||||
args:
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback'
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8'
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6'
|
||||
idp_sso_target_url: 'https://login.example.com/idp'
|
||||
issuer: 'https://gitlab.example.com'
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
|
||||
|
|
@ -2473,7 +2462,7 @@ Configure [`username` or `nickname`](omniauth.md#per-provider-configuration) in
|
|||
required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors'],
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
|
||||
|
|
@ -2505,7 +2494,7 @@ Configure [`username` or `nickname`](omniauth.md#per-provider-configuration) in
|
|||
required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors'],
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
|
||||
|
|
@ -2560,7 +2549,7 @@ These attributes have no default mappings and do not sync unless explicitly conf
|
|||
label: 'Our SAML Provider',
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
|
||||
|
|
@ -2592,7 +2581,7 @@ These attributes have no default mappings and do not sync unless explicitly conf
|
|||
label: 'Our SAML Provider'
|
||||
args:
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback'
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8'
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6'
|
||||
idp_sso_target_url: 'https://login.example.com/idp'
|
||||
issuer: 'https://gitlab.example.com'
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
|
||||
|
|
@ -2647,7 +2636,7 @@ These attributes have no default mappings and do not sync unless explicitly conf
|
|||
label: 'Our SAML Provider',
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
|
||||
|
|
@ -2681,7 +2670,7 @@ These attributes have no default mappings and do not sync unless explicitly conf
|
|||
label: 'Our SAML Provider',
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
|
||||
|
|
@ -2728,7 +2717,7 @@ The value given is added to the current time at which the response is validated.
|
|||
required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors'],
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
|
||||
|
|
@ -2758,7 +2747,7 @@ The value given is added to the current time at which the response is validated.
|
|||
required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors']
|
||||
args:
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback'
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8'
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6'
|
||||
idp_sso_target_url: 'https://login.example.com/idp'
|
||||
issuer: 'https://gitlab.example.com'
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
|
||||
|
|
@ -2812,7 +2801,7 @@ The value given is added to the current time at which the response is validated.
|
|||
required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors'],
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
|
||||
|
|
@ -2844,7 +2833,7 @@ The value given is added to the current time at which the response is validated.
|
|||
required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors'],
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
|
||||
|
|
@ -2895,7 +2884,7 @@ In the following example, the value of `uid` attribute in the SAML response is s
|
|||
label: 'Our SAML Provider',
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
|
||||
|
|
@ -2925,7 +2914,7 @@ In the following example, the value of `uid` attribute in the SAML response is s
|
|||
required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors']
|
||||
args:
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback'
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8'
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6'
|
||||
idp_sso_target_url: 'https://login.example.com/idp'
|
||||
issuer: 'https://gitlab.example.com'
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
|
||||
|
|
@ -2979,7 +2968,7 @@ In the following example, the value of `uid` attribute in the SAML response is s
|
|||
required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors'],
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
|
||||
|
|
@ -3011,7 +3000,7 @@ In the following example, the value of `uid` attribute in the SAML response is s
|
|||
required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors'],
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
|
||||
|
|
@ -3075,7 +3064,7 @@ This makes the key file one long string with no line feeds.
|
|||
required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors'],
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
|
||||
|
|
@ -3106,7 +3095,7 @@ This makes the key file one long string with no line feeds.
|
|||
required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors']
|
||||
args:
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback'
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8'
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6'
|
||||
idp_sso_target_url: 'https://login.example.com/idp'
|
||||
issuer: 'https://gitlab.example.com'
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
|
||||
|
|
@ -3161,7 +3150,7 @@ This makes the key file one long string with no line feeds.
|
|||
required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors'],
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
|
||||
|
|
@ -3194,7 +3183,7 @@ This makes the key file one long string with no line feeds.
|
|||
required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors'],
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
|
||||
|
|
@ -3242,7 +3231,7 @@ To implement signing:
|
|||
label: 'Our SAML Provider',
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
|
||||
|
|
@ -3279,7 +3268,7 @@ To implement signing:
|
|||
label: 'Our SAML Provider'
|
||||
args:
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback'
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8'
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6'
|
||||
idp_sso_target_url: 'https://login.example.com/idp'
|
||||
issuer: 'https://gitlab.example.com'
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
|
||||
|
|
@ -3339,7 +3328,7 @@ To implement signing:
|
|||
label: 'Our SAML Provider',
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
|
||||
|
|
@ -3378,7 +3367,7 @@ To implement signing:
|
|||
label: 'Our SAML Provider',
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
idp_cert_fingerprint: '2f:cb:19:57:68:c3:9e:9a:94:ce:c2:c2:e3:2c:59:c0:aa:d7:a3:36:5c:10:89:2e:81:16:b5:d8:3d:40:96:b6',
|
||||
idp_sso_target_url: 'https://login.example.com/idp',
|
||||
issuer: 'https://gitlab.example.com',
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ If you're interested in a region not listed here, contact your account represent
|
|||
When setting up GitLab Dedicated, you select a secondary region to host a failover instance for
|
||||
disaster recovery. Some AWS regions are available only as secondary regions because they do not fully support certain AWS
|
||||
features that GitLab Dedicated relies on. If GitLab initiates a failover to your secondary region during
|
||||
a disaster recovery event or test, these limitations may impact available features.
|
||||
a disaster recovery event or test, these limitations impact available features.
|
||||
|
||||
The following regions are verified for use as a secondary region but with known limitations:
|
||||
|
||||
|
|
@ -80,13 +80,15 @@ The following regions are verified for use as a secondary region but with known
|
|||
|
||||
These limitations may affect your service in the following ways:
|
||||
|
||||
- **No io2 volume support**: Regions without io2 volume support use gp3 volumes instead, which offer lower
|
||||
data durability (99.8-99.9% compared to 99.999% for io2), potentially longer [RTO and RPO](https://handbook.gitlab.com/handbook/engineering/infrastructure/team/gitlab-dedicated/slas/) recovery times, and
|
||||
may affect failover capabilities if rebuilding is necessary.
|
||||
- **No io2 volume support**: In regions where AWS does not support io2 volumes, GitLab Dedicated uses GP3
|
||||
volumes instead. GP3 volumes have lower durability (99.8-99.9% compared to 99.999% for io2), which
|
||||
increases the risk of disk failures in your replica region. This can affect availability during failover
|
||||
or while operating in the failed-over state. As a result, these regions are not covered by our standard
|
||||
[RTO and RPO](https://handbook.gitlab.com/handbook/engineering/infrastructure/team/gitlab-dedicated/slas/) time objectives.
|
||||
|
||||
- **No SES support**: Regions without AWS Simple Email Service (SES) support cannot send email
|
||||
notifications using the default configuration. To maintain email functionality in these regions,
|
||||
you must set up your own [external SMTP mail service](../../administration/dedicated/configure_instance/users_notifications.md#smtp-email-service).
|
||||
- **No SES support**: In regions where AWS does not support Simple Email Service (SES), GitLab
|
||||
cannot send email notifications using the default configuration. To maintain email functionality
|
||||
in these regions, set up your own [external SMTP mail service](../../administration/dedicated/configure_instance/users_notifications.md#smtp-email-service).
|
||||
|
||||
During onboarding, regions with these limitations are clearly marked. You must acknowledge the
|
||||
associated risks before selecting one as your secondary region.
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ There are multiple ways to configure security scans in new projects:
|
|||
- In a scan execution policy to enforce that pipelines run specific security scanners.
|
||||
- In a pipeline execution policy to control which jobs must run in pipelines.
|
||||
|
||||
For simple use cases, you can use the project's CI/CD configuration. For a comprehensive security strategy, consider combining merge request approval policies with the other policy types.
|
||||
For simple use cases, you can use the project's CI/CD configuration. For a comprehensive security strategy, consider combining merge request approval policies with the other policy types.
|
||||
|
||||
To minimize unnecessary approval requirements and ensure accurate security evaluations:
|
||||
|
||||
|
|
@ -248,20 +248,42 @@ This rule enforces the defined actions based on security scan findings.
|
|||
- [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/8092) in GitLab 15.9 [with a flag](../../../administration/feature_flags.md) named `license_scanning_policies`.
|
||||
- [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/397644) in GitLab 15.11. Feature flag `license_scanning_policies` removed.
|
||||
- The `branch_exceptions` field was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/418741) in GitLab 16.3 [with a flag](../../../administration/feature_flags.md) named `security_policies_branch_exceptions`. Enabled by default. [Generally available](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/133753) in GitLab 16.5. Feature flag removed.
|
||||
- The `licenses` field was [introduced](https://gitlab.com/groups/gitlab-org/-/epics/10203) in GitLab 17.11 [with a flag](../../../administration/feature_flags.md) named `exclude_license_packages`. Disabled by default.
|
||||
|
||||
{{< /history >}}
|
||||
|
||||
This rule enforces the defined actions based on license findings.
|
||||
|
||||
| Field | Type | Required | Possible values | Description |
|
||||
|----------------------|---------------------|--------------------------------------------|------------------------------|-------------|
|
||||
| `type` | `string` | true | `license_finding` | The rule's type. |
|
||||
| `branches` | `array` of `string` | true if `branch_type` field does not exist | `[]` or the branch's name | Applicable only to protected target branches. An empty array, `[]`, applies the rule to all protected target branches. Cannot be used with the `branch_type` field. |
|
||||
| `branch_type` | `string` | true if `branches` field does not exist | `default` or `protected` | The types of protected branches the given policy applies to. Cannot be used with the `branches` field. Default branches must also be `protected`. |
|
||||
| `branch_exceptions` | `array` of `string` | false | Names of branches | Branches to exclude from this rule. |
|
||||
| `match_on_inclusion_license` | `boolean` | true | `true`, `false` | Whether the rule matches inclusion or exclusion of licenses listed in `license_types`. |
|
||||
| `license_types` | `array` of `string` | true | license types | [SPDX license names](https://spdx.org/licenses) to match on, for example `Affero General Public License v1.0` or `MIT License`. |
|
||||
| `license_states` | `array` of `string` | true | `newly_detected`, `detected` | Whether to match newly detected and/or previously detected licenses. The `newly_detected` state triggers approval when either a new package is introduced or when a new license for an existing package is detected. |
|
||||
| Field | Type | Required | Possible values | Description |
|
||||
|----------------|----------|-----------------------------------------------|------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `type` | `string` | true | `license_finding` | The rule's type. |
|
||||
| `branches` | `array` of `string` | true if `branch_type` field does not exist | `[]` or the branch's name | Applicable only to protected target branches. An empty array, `[]`, applies the rule to all protected target branches. Cannot be used with the `branch_type` field. |
|
||||
| `branch_type` | `string` | true if `branches` field does not exist | `default` or `protected` | The types of protected branches the given policy applies to. Cannot be used with the `branches` field. Default branches must also be `protected`. |
|
||||
| `branch_exceptions` | `array` of `string` | false | Names of branches | Branches to exclude from this rule. |
|
||||
| `match_on_inclusion_license` | `boolean` | true if `licenses` field does not exists | `true`, `false` | Whether the rule matches inclusion or exclusion of licenses listed in `license_types`. |
|
||||
| `license_types` | `array` of `string` | true if `licenses` field does not exists | license types | [SPDX license names](https://spdx.org/licenses) to match on, for example `Affero General Public License v1.0` or `MIT License`. |
|
||||
| `license_states` | `array` of `string` | true | `newly_detected`, `detected` | Whether to match newly detected and/or previously detected licenses. The `newly_detected` state triggers approval when either a new package is introduced or when a new license for an existing package is detected. |
|
||||
| `licenses` | `object` | true if `license_types` field does not exists | `licenses` object | [SPDX license names](https://spdx.org/licenses) to match on including package exceptions. |
|
||||
|
||||
### `licenses` object
|
||||
|
||||
| Field | Type | Required | Possible values | Description |
|
||||
|-----------|----------|-----------------------------------------|------------------------------------------------------|------------------------------------------------------------|
|
||||
| `denied` | `object` | true if `allowed` field does not exist | `array` of `licenses_with_package_exclusion` objects | The list of denied licenses including package exceptions. |
|
||||
| `allowed` | `object` | true if `denied` field does not exist | `array` of `licenses_with_package_exclusion` objects | The list of allowed licenses including package exceptions. |
|
||||
|
||||
### `licenses_with_package_exclusion` object
|
||||
|
||||
| Field | Type | Required | Possible values | Description |
|
||||
|--------|----------|----------|-------------------|----------------------------------------------------|
|
||||
| `name` | `string` | true | SPDX license name | [SPDX license name](https://spdx.org/licenses). |
|
||||
| `packages` | `object` | false | `packages` object | List of packages exceptions for the given license. |
|
||||
|
||||
### `packages` object
|
||||
|
||||
| Field | Type | Required | Possible values | Description |
|
||||
|--------|----------|----------|-------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `excluding` | `object` | true | {purls: `array` of `strings` using the `uri` format} | List of package exceptions for the given license. Define the list of packages exceptions using the [`purl`](https://github.com/package-url/purl-spec?tab=readme-ov-file#purl) components `scheme:type/name@version`. The `scheme:type/name` components are required. The `@` and `version` are optional. If a version is specified, only that version is considered an exception. If no version is specified and the `@` character is added at the end of the `purl`, only packages with the exact name is considered a match. If the `@` character is not added to the package name, all packages with the same prefix for the given license are matches. For example, a purl `pkg:gem/bundler` matches the `bundler` and `bundler-stats` packages because both packages use the same license. Defining a `purl` `pkg:gem/bundler@` matches only the `bundler` package. |
|
||||
|
||||
## `any_merge_request` rule type
|
||||
|
||||
|
|
|
|||
|
|
@ -87,14 +87,7 @@ To set up Google Workspace as your identity provider:
|
|||
| **GitLab single sign-on URL** | **Start URL** |
|
||||
| **Identity provider single sign-on URL** | **SSO URL** |
|
||||
|
||||
1. Google Workspace displays a SHA256 fingerprint. To retrieve the SHA1 fingerprint
|
||||
required by GitLab to [configure SAML](#configure-gitlab):
|
||||
1. Download the certificate.
|
||||
1. Run this command:
|
||||
|
||||
```shell
|
||||
openssl x509 -noout -fingerprint -sha1 -inform pem -in "GoogleIDPCertificate-domain.com.pem"
|
||||
```
|
||||
1. Google Workspace displays a SHA256 fingerprint when you retrieve the certificate. If you need to generate the SHA256 fingerprint later, see [calculate the fingerprint](troubleshooting.md#calculate-the-fingerprint).
|
||||
|
||||
1. Set these values:
|
||||
- For **Primary email**: `email`.
|
||||
|
|
@ -225,7 +218,7 @@ The following GitLab settings correspond to the Keycloak fields.
|
|||
1. Retrieve the certificate fingerprint.
|
||||
1. Note the value of the `<ds:X509Certificate>` tag.
|
||||
1. Convert the value to [PEM format](https://www.ssl.com/guide/pem-der-crt-and-cer-x-509-encodings-and-conversions/#ftoc-heading-3).
|
||||
1. [Calculate the fingerprint](../../group/saml_sso/troubleshooting.md#calculate-the-fingerprint).
|
||||
1. [Calculate the fingerprint](troubleshooting.md#calculate-the-fingerprint).
|
||||
|
||||
### Configure assertions
|
||||
|
||||
|
|
@ -323,12 +316,6 @@ After you set up your identity provider to work with GitLab, you must configure
|
|||
For more information, see the [SSO enforcement documentation](#sso-enforcement).
|
||||
1. Select **Save changes**.
|
||||
|
||||
{{< alert type="note" >}}
|
||||
|
||||
The certificate [fingerprint algorithm](../../../integration/saml.md#configure-saml-on-your-idp) must be in SHA1. When configuring the identity provider (such as [Google Workspace](#google-workspace)), use a secure signature algorithm.
|
||||
|
||||
{{< /alert >}}
|
||||
|
||||
If you are having issues configuring GitLab, see the [troubleshooting documentation](#troubleshooting).
|
||||
|
||||
## User access and management
|
||||
|
|
|
|||
|
|
@ -85,13 +85,6 @@ If available, you can add user-friendly group names instead. When setting up Azu
|
|||
|
||||
### IdP links and certificate
|
||||
|
||||
{{< alert type="note" >}}
|
||||
|
||||
Google Workspace displays a SHA256 fingerprint. To retrieve the SHA1 fingerprint required by GitLab for configuring SAML, download the certificate and calculate the SHA1 certificate
|
||||
fingerprint.
|
||||
|
||||
{{< /alert >}}
|
||||
|
||||

|
||||
|
||||
## Okta
|
||||
|
|
|
|||
|
|
@ -219,13 +219,13 @@ For convenience, we've included some [example resources](example_saml_config.md)
|
|||
|
||||
### Calculate the fingerprint
|
||||
|
||||
If you use a `idp_cert_fingerprint`, it must be a SHA1 fingerprint. To calculate a SHA1 fingerprint, download the certificate file and run:
|
||||
When configuring the `idp_cert_fingerprint` you should use a SHA256 fingerprint whenever possible. SHA1 is also supported, but is not recommended. You can calculate the fingerprint by running the following command on the certificate file:
|
||||
|
||||
```shell
|
||||
openssl x509 -in <filename.crt> -noout -fingerprint -sha1
|
||||
openssl x509 -in <certificate.crt> -noout -fingerprint -sha256
|
||||
```
|
||||
|
||||
Replace `filename.crt` with the name of the certificate file.
|
||||
Replace `<certificate.crt>` with the name of the certificate file.
|
||||
|
||||
## SSO Certificate updates
|
||||
|
||||
|
|
@ -248,8 +248,7 @@ must be validated using either a fingerprint, a certificate, or a validator.
|
|||
|
||||
For this requirement, be sure to take the following into account:
|
||||
|
||||
- If you use a fingerprint, it must be the correct SHA1 fingerprint. To confirm that you are using
|
||||
the correct SHA1 fingerprint:
|
||||
- If you use a fingerprint, confirm your SHA256 fingerprint:
|
||||
1. Re-download the certificate file.
|
||||
1. [Calculate the fingerprint](#calculate-the-fingerprint).
|
||||
1. Compare the fingerprint to the value provided in `idp_cert_fingerprint`. The values should be the same.
|
||||
|
|
|
|||
|
|
@ -48,13 +48,14 @@ A running workspace remains accessible to the user even if user permissions are
|
|||
{{< history >}}
|
||||
|
||||
- [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/125331) in GitLab 16.2.
|
||||
- Managing workspaces from the **Code** menu [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/178492) in GitLab 17.11.
|
||||
|
||||
{{< /history >}}
|
||||
|
||||
To manage workspaces from a project:
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your project.
|
||||
1. In the upper right, select **Edit**.
|
||||
1. In the upper right, select **Code**.
|
||||
1. From the dropdown list, under **Your workspaces**, you can:
|
||||
- Restart, stop, or terminate an existing workspace.
|
||||
- Create a new workspace.
|
||||
|
|
|
|||
|
|
@ -89,6 +89,9 @@ Instance methods required:
|
|||
- `operation`: determines the operation which can be one of `upsert` or `delete`
|
||||
- `identifier`: unique identifier
|
||||
|
||||
Optional methods:
|
||||
- `unique_identifiers`: array of identifiers to build a unique identifier for every document. For example, `[identifier, branch_name]`. Defaults to `[identifier]`
|
||||
|
||||
Example for a reference reading from a database relation, with preloading and bulk embedding generation:
|
||||
|
||||
```ruby
|
||||
|
|
|
|||
|
|
@ -88,10 +88,10 @@ module ActiveContext
|
|||
def build_index_operations(ref)
|
||||
return unless ref.operation.to_sym == :upsert
|
||||
|
||||
ref.jsons.map.with_index do |hash, index|
|
||||
ref.jsons.map do |hash|
|
||||
add_index_operation([
|
||||
{ update: { _index: ref.partition, _id: unique_identifier(ref, index), routing: ref.routing }.compact },
|
||||
{ doc: hash, doc_as_upsert: true }
|
||||
{ update: { _index: ref.partition, _id: hash[:unique_identifier], routing: ref.routing }.compact },
|
||||
{ doc: hash.except(:unique_identifier), doc_as_upsert: true }
|
||||
])
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -54,10 +54,6 @@ module ActiveContext
|
|||
# also reset anything that builds up from the refs array
|
||||
end
|
||||
|
||||
def unique_identifier(ref, index)
|
||||
"#{ref.identifier}:#{index}"
|
||||
end
|
||||
|
||||
def extract_identifier(string)
|
||||
string.split(':').first
|
||||
end
|
||||
|
|
|
|||
|
|
@ -29,8 +29,7 @@ module ActiveContext
|
|||
end
|
||||
|
||||
def process_bulk_errors(result)
|
||||
# we already return only failed references so nothing to do here
|
||||
result
|
||||
result.uniq { |ref| ref.unique_identifier(nil) }
|
||||
end
|
||||
|
||||
def reset
|
||||
|
|
@ -43,8 +42,8 @@ module ActiveContext
|
|||
def build_operation(ref)
|
||||
case ref.operation.to_sym
|
||||
when :upsert
|
||||
ref.jsons.each.with_index do |hash, index|
|
||||
@operations << { "#{ref.partition_name}": { upsert: build_indexed_json(hash, ref, index) }, ref: ref }
|
||||
ref.jsons.each do |hash|
|
||||
@operations << { "#{ref.partition_name}": { upsert: build_indexed_json(hash, ref) }, ref: ref }
|
||||
end
|
||||
@operations << build_delete_operation(ref: ref, include_ref_version: true)
|
||||
when :delete
|
||||
|
|
@ -54,12 +53,13 @@ module ActiveContext
|
|||
end
|
||||
end
|
||||
|
||||
def build_indexed_json(hash, ref, index)
|
||||
def build_indexed_json(hash, ref)
|
||||
hash
|
||||
.merge(
|
||||
partition_id: ref.partition_number,
|
||||
id: unique_identifier(ref, index)
|
||||
id: hash[:unique_identifier]
|
||||
)
|
||||
.except(:unique_identifier)
|
||||
.transform_values { |value| convert_pg_array(value) }
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -78,8 +78,9 @@ module ActiveContext
|
|||
docs = docs.map { |doc| base.merge(doc) }
|
||||
end
|
||||
|
||||
docs.map do |json|
|
||||
docs.map.with_index do |json, index|
|
||||
json.merge(
|
||||
unique_identifier: unique_identifier(index),
|
||||
ref_id: identifier,
|
||||
ref_version: ref_version
|
||||
)
|
||||
|
|
@ -100,6 +101,14 @@ module ActiveContext
|
|||
raise NotImplementedError
|
||||
end
|
||||
|
||||
def unique_identifier(index)
|
||||
[unique_identifiers, index].flatten.join(':')
|
||||
end
|
||||
|
||||
def unique_identifiers
|
||||
[identifier]
|
||||
end
|
||||
|
||||
def partition_name
|
||||
collection.name
|
||||
end
|
||||
|
|
|
|||
|
|
@ -59,6 +59,8 @@ module Keeps
|
|||
query = "SELECT EXISTS (SELECT 1 FROM #{table_name_quoted} LIMIT 1)"
|
||||
|
||||
pg_client.exec_params(query)
|
||||
rescue PG::UndefinedTable
|
||||
false
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ module Banzai
|
|||
multiline_block_quotes: true,
|
||||
relaxed_autolinks: true,
|
||||
sourcepos: true,
|
||||
experimental_inline_sourcepos: true,
|
||||
smart: false,
|
||||
strikethrough: true,
|
||||
table: true,
|
||||
|
|
@ -45,7 +44,6 @@ module Banzai
|
|||
|
||||
OPTIONS.merge(
|
||||
sourcepos: !sourcepos_disabled?,
|
||||
experimental_inline_sourcepos: sourcepos_disabled? ? false : OPTIONS[:experimental_inline_sourcepos],
|
||||
header_ids: headers_disabled? ? nil : OPTIONS[:header_ids],
|
||||
autolink: !autolink_disabled?,
|
||||
relaxed_autolinks: !autolink_disabled?,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module BackgroundMigration
|
||||
class BackfillListsShardingKey < BatchedMigrationJob
|
||||
operation_name :set_lists_sharding_key
|
||||
feature_category :team_planning
|
||||
|
||||
def perform
|
||||
each_sub_batch do |sub_batch|
|
||||
connection.execute(
|
||||
<<~SQL
|
||||
WITH sub_batch AS MATERIALIZED (#{sub_batch.select(:id, :board_id).limit(sub_batch_size).to_sql})
|
||||
UPDATE
|
||||
"lists"
|
||||
SET
|
||||
"group_id" = "boards"."group_id", "project_id" = "boards"."project_id"
|
||||
FROM
|
||||
"sub_batch"
|
||||
INNER JOIN "boards" ON "boards"."id" = "sub_batch"."board_id"
|
||||
WHERE
|
||||
"lists"."id" = "sub_batch"."id"
|
||||
SQL
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'base64'
|
||||
|
||||
module Gitlab
|
||||
module Doctor
|
||||
class EncryptionKeys
|
||||
attr_reader :logger
|
||||
|
||||
PRINT_PROGRESS_EVERY = 1000
|
||||
KEY_TYPES = Gitlab::Encryption::KeyProvider::KEY_PROVIDERS.keys.grep(/active_record/)
|
||||
Key = Struct.new(:type, :id, :truncated_secret)
|
||||
|
||||
def initialize(logger)
|
||||
@logger = logger
|
||||
end
|
||||
|
||||
def run!
|
||||
logger.info "Gathering existing encryption keys:"
|
||||
known_keys.each do |key|
|
||||
logger.info "- #{key.type}: ID => `#{key.id}`; truncated secret => `#{key.truncated_secret}`"
|
||||
end
|
||||
logger.info "\n"
|
||||
|
||||
logger.info "Gathering encryption keys for models with Active Record Encryption attributes"
|
||||
Rails.application.eager_load!
|
||||
|
||||
encryption_keys_usage_per_model =
|
||||
models_with_encrypted_attributes.index_with do |model|
|
||||
gather_encryption_keys(model)
|
||||
end
|
||||
|
||||
encryption_keys_usage_per_model.each do |model, encryption_keys_usage|
|
||||
logger.info "Encryption keys usage for #{model.name}:#{' NONE' if encryption_keys_usage.empty?}"
|
||||
encryption_keys_usage.each do |key, count|
|
||||
logger.info "- `#{key}`#{' (UNKNOWN KEY!)' unless known_keys.map(&:id).include?(key)} => #{count}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def known_keys
|
||||
@known_keys ||= KEY_TYPES.each_with_object([]) do |key_type, memo|
|
||||
Gitlab::Encryption::KeyProvider[key_type].decryption_keys.each do |key|
|
||||
memo << Key.new(key_type, key.id)
|
||||
end
|
||||
end.tap do |keys| # rubocop:disable Style/MultilineBlockChain -- avoid a local instance
|
||||
populate_actual_secrets!(keys)
|
||||
end
|
||||
end
|
||||
|
||||
def populate_actual_secrets!(keys)
|
||||
KEY_TYPES.each do |key_type|
|
||||
actual_secrets = Gitlab::Encryption::KeyProvider::KEY_PROVIDERS[key_type].secrets.call
|
||||
|
||||
keys.select { |k| k.type == key_type }.each_with_index do |key, index|
|
||||
key.truncated_secret = "#{actual_secrets[index][...3]}...#{actual_secrets[index][-3..]}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def gather_encryption_keys(model)
|
||||
encrypted_attributes = model.encrypted_attributes
|
||||
total_count = model.count
|
||||
return {} if total_count == 0
|
||||
|
||||
encryption_keys_usage = Hash.new { |hash, key| hash[key] = 0 }
|
||||
|
||||
model.find_each.with_index do |instance, index|
|
||||
encrypted_attributes.each do |attribute_name|
|
||||
encryption_keys_usage[encryption_key(instance, attribute_name)] += 1
|
||||
end
|
||||
|
||||
logger.info "Checked #{index + 1}/#{total_count} #{model.name.pluralize}" if index % PRINT_PROGRESS_EVERY == 0
|
||||
end
|
||||
logger.info "Checked #{total_count} #{model.name.pluralize}\n"
|
||||
|
||||
encryption_keys_usage
|
||||
end
|
||||
|
||||
def encryption_key(instance, attribute_name)
|
||||
Base64.decode64(Gitlab::Json.parse(instance.ciphertext_for(attribute_name))['h']['i'])
|
||||
end
|
||||
|
||||
def models_with_encrypted_attributes
|
||||
ApplicationRecord.descendants.select { |d| d.encrypted_attributes.present? }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -15,6 +15,11 @@ module Gitlab
|
|||
Gitlab::CryptoHelper.sha256("#{instance_id}#{user_id}")
|
||||
end
|
||||
|
||||
def self.instance_uuid
|
||||
instance_id = Gitlab::CryptoHelper.sha256('instance')
|
||||
Gitlab::UUID.v5(instance_id)
|
||||
end
|
||||
|
||||
def self.instance_id
|
||||
::Gitlab::CurrentSettings.uuid.presence || GITLAB_INSTANCE_UUID_NOT_SET
|
||||
end
|
||||
|
|
|
|||
|
|
@ -157,14 +157,16 @@ module Gitlab
|
|||
payload.merge!(::Gitlab::Instrumentation::Middleware::PathTraversalCheck.payload)
|
||||
end
|
||||
|
||||
# Returns the queuing duration for a Sidekiq job in seconds, as a float, if the
|
||||
# Returns the total queuing duration for a Sidekiq job in seconds, as a float, if the
|
||||
# `enqueued_at` field or `created_at` field is available.
|
||||
# Includes buffering duration if a job was buffered by ConcurrencyLimit middleware.
|
||||
#
|
||||
# * If the job doesn't contain sufficient information, returns nil
|
||||
# * If the job has a start time in the future, returns 0
|
||||
# * If the job contains an invalid start time value, returns nil
|
||||
# @param [Hash] job a Sidekiq job, represented as a hash
|
||||
def self.queue_duration_for_job(job)
|
||||
# @param [Boolean] with_buffering_duration whether to include buffering duration by ConcurrencyLimit
|
||||
def self.queue_duration_for_job(job, with_buffering_duration: true)
|
||||
# Old gitlab-shell messages don't provide enqueued_at/created_at attributes
|
||||
enqueued_at = job['enqueued_at'] || job['created_at']
|
||||
return unless enqueued_at
|
||||
|
|
@ -172,11 +174,18 @@ module Gitlab
|
|||
enqueued_at_time = convert_to_time(enqueued_at)
|
||||
return unless enqueued_at_time
|
||||
|
||||
round_elapsed_time(enqueued_at_time)
|
||||
buffering_duration = buffering_duration_for_job(job) # concurrency_limit_buffered_at -> enqueued_at
|
||||
queueing_duration = round_elapsed_time(enqueued_at_time) # enqueued_at -> now
|
||||
|
||||
if with_buffering_duration && !queueing_duration.nil? && !buffering_duration.nil?
|
||||
queueing_duration += buffering_duration
|
||||
end
|
||||
|
||||
queueing_duration
|
||||
end
|
||||
|
||||
# Returns the buffering duration for a Sidekiq job in seconds, as a float, if the
|
||||
# `concurrency_limit_buffered_at` field is available.
|
||||
# Returns the time a Sidekiq job waiting from being buffered until enqueued again in seconds, as a float, if the
|
||||
# `concurrency_limit_buffered_at` and `enqueued_at`/`created_at` field is available.
|
||||
#
|
||||
# * If the job doesn't contain sufficient information, returns nil
|
||||
# * If the job has a start time in the future, returns 0
|
||||
|
|
@ -186,10 +195,17 @@ module Gitlab
|
|||
buffered_at = job['concurrency_limit_buffered_at']
|
||||
return unless buffered_at
|
||||
|
||||
# Old gitlab-shell messages don't provide enqueued_at/created_at attributes
|
||||
enqueued_at = job['enqueued_at'] || job['created_at']
|
||||
return unless enqueued_at
|
||||
|
||||
buffered_at_time = convert_to_time(buffered_at)
|
||||
return unless buffered_at_time
|
||||
|
||||
round_elapsed_time(buffered_at_time)
|
||||
enqueued_at_time = convert_to_time(enqueued_at)
|
||||
return unless enqueued_at
|
||||
|
||||
round_elapsed_time(buffered_at_time, enqueued_at_time)
|
||||
end
|
||||
|
||||
# Returns the time it took for a scheduled job to be enqueued in seconds, as a float,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Redis
|
||||
class CursorStore
|
||||
def initialize(cache_key, ttl: 1.hour)
|
||||
@cache_key = cache_key
|
||||
@ttl = ttl.to_i
|
||||
end
|
||||
|
||||
def commit(payload)
|
||||
Gitlab::Redis::SharedState.with do |redis|
|
||||
redis.hset(cache_key, payload, ex: ttl)
|
||||
end
|
||||
end
|
||||
|
||||
def cursor
|
||||
Gitlab::Redis::SharedState.with do |redis|
|
||||
redis.hgetall(cache_key)
|
||||
end.except('ex')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :cache_key, :ttl
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -7,7 +7,8 @@ require 'sidekiq/job_retry'
|
|||
module Gitlab
|
||||
module SidekiqLogging
|
||||
class JSONFormatter
|
||||
TIMESTAMP_FIELDS = %w[created_at scheduled_at enqueued_at started_at retried_at failed_at completed_at].freeze
|
||||
TIMESTAMP_FIELDS = %w[created_at scheduled_at enqueued_at started_at retried_at failed_at completed_at
|
||||
concurrency_limit_buffered_at].freeze
|
||||
|
||||
def call(severity, timestamp, progname, data)
|
||||
output = {
|
||||
|
|
|
|||
|
|
@ -59,10 +59,12 @@ module Gitlab
|
|||
payload['concurrency_limit_buffering_duration_s'] = buffering_duration_s if buffering_duration_s
|
||||
|
||||
queue_duration_s = ::Gitlab::InstrumentationHelper.queue_duration_for_job(payload)
|
||||
scheduling_duration_s = ::Gitlab::InstrumentationHelper.queue_duration_for_job(job,
|
||||
with_buffering_duration: false)
|
||||
|
||||
if queue_duration_s
|
||||
payload['queue_duration_s'] = queue_duration_s
|
||||
payload['scheduling_latency_s'] = queue_duration_s + buffering_duration_s.to_f
|
||||
payload['scheduling_latency_s'] = scheduling_duration_s
|
||||
end
|
||||
|
||||
enqueue_latency_s = ::Gitlab::InstrumentationHelper.enqueue_latency_for_scheduled_job(payload)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
module Gitlab
|
||||
module Tracking
|
||||
class StandardContext
|
||||
GITLAB_STANDARD_SCHEMA_URL = 'iglu:com.gitlab/gitlab_standard/jsonschema/1-1-1'
|
||||
GITLAB_STANDARD_SCHEMA_URL = 'iglu:com.gitlab/gitlab_standard/jsonschema/1-1-5'
|
||||
GITLAB_RAILS_SOURCE = 'gitlab-rails'
|
||||
|
||||
def initialize(
|
||||
|
|
@ -61,6 +61,7 @@ module Gitlab
|
|||
feature_enabled_by_namespace_ids: feature_enabled_by_namespace_ids,
|
||||
realm: realm,
|
||||
instance_id: instance_id,
|
||||
unique_instance_id: Gitlab::GlobalAnonymousId.instance_uuid,
|
||||
host_name: Gitlab::Environment.hostname,
|
||||
instance_version: Gitlab.version_info.to_s,
|
||||
context_generated_at: Time.current
|
||||
|
|
|
|||
|
|
@ -26,5 +26,11 @@ namespace :gitlab do
|
|||
|
||||
Gitlab::Doctor::ResetTokens.new(logger, model_names: model_names, token_names: token_names, dry_run: dry_run).run!
|
||||
end
|
||||
|
||||
desc "GitLab | Check Active Record Encryption keys"
|
||||
task encryption_keys: :gitlab_environment do
|
||||
logger = Logger.new($stdout)
|
||||
Gitlab::Doctor::EncryptionKeys.new(logger).run!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3975,6 +3975,9 @@ msgstr ""
|
|||
msgid "AdminAIPoweredFeatures|An error occurred while loading the AI feature settings. Please try again."
|
||||
msgstr ""
|
||||
|
||||
msgid "AdminAIPoweredFeatures|Apply to all sub-features"
|
||||
msgstr ""
|
||||
|
||||
msgid "AdminAIPoweredFeatures|Assists developers by providing real-time code completions and recommendations. %{linkStart}Learn more.%{linkEnd}"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -4269,9 +4272,18 @@ msgstr ""
|
|||
msgid "AdminSelfHostedModels|An error occurred while loading the self-hosted model. Please try again."
|
||||
msgstr ""
|
||||
|
||||
msgid "AdminSelfHostedModels|An error occurred while updating the %{mainFeature} sub-feature settings. Please try again."
|
||||
msgstr ""
|
||||
|
||||
msgid "AdminSelfHostedModels|An error occurred while updating the self-hosted model, please try again."
|
||||
msgstr ""
|
||||
|
||||
msgid "AdminSelfHostedModels|Apply to all %{mainFeature} sub-features"
|
||||
msgstr ""
|
||||
|
||||
msgid "AdminSelfHostedModels|Assign a setting to the %{subFeatureTitle} sub-feature before applying to all"
|
||||
msgstr ""
|
||||
|
||||
msgid "AdminSelfHostedModels|Create self-hosted model"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -48244,6 +48256,9 @@ msgstr ""
|
|||
msgid "ProjectsNew|Choose a group"
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectsNew|Choose a group or namespace"
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectsNew|Connect your external repository to GitLab CI/CD."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -48382,6 +48397,12 @@ msgstr ""
|
|||
msgid "ProjectsNew|Please enter a valid username."
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectsNew|Please enter project name."
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectsNew|Please enter project slug."
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectsNew|Please upload a valid GitLab project export file."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -55508,9 +55529,6 @@ msgstr ""
|
|||
msgid "SecurityReports|Export"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityReports|Export as CSV"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityReports|Failed to get security report information. Please reload the page or try again later."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -69135,9 +69153,6 @@ msgstr ""
|
|||
msgid "Workspaces|When no devfile is provided, the GitLab default devfile will be used."
|
||||
msgstr ""
|
||||
|
||||
msgid "Workspaces|Workspace automatically terminates after"
|
||||
msgstr ""
|
||||
|
||||
msgid "Workspaces|Workspaces"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,10 @@ RSpec.describe 'Triggers', :js, feature_category: :continuous_integration do
|
|||
let_it_be(:guest_user) { create(:user) }
|
||||
let_it_be(:project) { create(:project) }
|
||||
|
||||
before do
|
||||
stub_feature_flags(vue_project_runners_settings: false)
|
||||
end
|
||||
|
||||
before_all do
|
||||
project.add_maintainer(user)
|
||||
project.add_maintainer(user2)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import MultiStepFormTemplate from '~/vue_shared/components/multi_step_form_template.vue';
|
||||
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import BlankProjectForm from '~/projects/new_v2/components/blank_project_form.vue';
|
||||
import SharedProjectCreationFields from '~/projects/new_v2/components/shared_project_creation_fields.vue';
|
||||
|
||||
describe('Blank Project Form', () => {
|
||||
let wrapper;
|
||||
|
|
@ -25,6 +26,7 @@ describe('Blank Project Form', () => {
|
|||
});
|
||||
|
||||
const findMultiStepFormTemplate = () => wrapper.findComponent(MultiStepFormTemplate);
|
||||
const findSharedProjectCreationFields = () => wrapper.findComponent(SharedProjectCreationFields);
|
||||
const findCreateButton = () => wrapper.findByTestId('create-project-button');
|
||||
const findBackButton = () => wrapper.findByTestId('create-project-back-button');
|
||||
|
||||
|
|
@ -36,6 +38,12 @@ describe('Blank Project Form', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('form', () => {
|
||||
it('renders the SharedProjectCreationFields component', () => {
|
||||
expect(findSharedProjectCreationFields().exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
it('renders the option to Create Project as disabled', () => {
|
||||
expect(findCreateButton().text()).toBe('Create project');
|
||||
expect(findCreateButton().props('disabled')).toBe(true);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,83 @@
|
|||
import { nextTick } from 'vue';
|
||||
import { GlFormInput } from '@gitlab/ui';
|
||||
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import SharedProjectCreationFields from '~/projects/new_v2/components/shared_project_creation_fields.vue';
|
||||
import NewProjectDestinationSelect from '~/projects/new_v2/components/project_destination_select.vue';
|
||||
|
||||
describe('Project creation form fields component', () => {
|
||||
let wrapper;
|
||||
|
||||
const defaultProps = {
|
||||
namespace: {
|
||||
id: '1',
|
||||
fullPath: 'root',
|
||||
isPersonal: true,
|
||||
},
|
||||
};
|
||||
|
||||
const createComponent = (props = {}) => {
|
||||
wrapper = shallowMountExtended(SharedProjectCreationFields, {
|
||||
propsData: {
|
||||
...defaultProps,
|
||||
...props,
|
||||
},
|
||||
stubs: {
|
||||
GlFormInput,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
createComponent();
|
||||
});
|
||||
|
||||
const findProjectNameInput = () => wrapper.findByTestId('project-name-input');
|
||||
const findProjectSlugInput = () => wrapper.findByTestId('project-slug-input');
|
||||
const findNamespaceSelect = () => wrapper.findComponent(NewProjectDestinationSelect);
|
||||
|
||||
it('updates project slug according to a project name', async () => {
|
||||
// NOTE: vue3 test needs the .setValue(value) and the vm.$emit('input'),
|
||||
// while the vue2 needs either .setValue(value) or vm.$emit('input', value)
|
||||
const value = 'My Awesome Project 123';
|
||||
findProjectNameInput().setValue(value);
|
||||
findProjectNameInput().vm.$emit('input', value);
|
||||
await nextTick();
|
||||
|
||||
expect(findProjectSlugInput().element.value).toBe('my-awesome-project-123');
|
||||
});
|
||||
|
||||
it('emits namespace change', () => {
|
||||
findNamespaceSelect().vm.$emit('onSelectNamespace', {
|
||||
id: '2',
|
||||
fullPath: 'group/subgroup',
|
||||
isPersonal: false,
|
||||
});
|
||||
|
||||
expect(wrapper.emitted('onSelectNamespace')).toHaveLength(1);
|
||||
expect(wrapper.emitted('onSelectNamespace')[0][0]).toEqual({
|
||||
id: '2',
|
||||
fullPath: 'group/subgroup',
|
||||
isPersonal: false,
|
||||
});
|
||||
});
|
||||
|
||||
describe('validation', () => {
|
||||
it('shows an error message when project name is cleared', async () => {
|
||||
findProjectNameInput().setValue('');
|
||||
findProjectNameInput().trigger('blur');
|
||||
await nextTick();
|
||||
|
||||
const formGroup = wrapper.findByTestId('project-name-group');
|
||||
expect(formGroup.vm.$attrs['invalid-feedback']).toBe('Please enter project name.');
|
||||
});
|
||||
|
||||
it('shows an error message when slug is cleared', async () => {
|
||||
findProjectSlugInput().setValue('');
|
||||
findProjectSlugInput().trigger('blur');
|
||||
await nextTick();
|
||||
|
||||
const formGroup = wrapper.findByTestId('project-slug-group');
|
||||
expect(formGroup.vm.$attrs['invalid-feedback']).toBe('Please enter project slug.');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -43,6 +43,7 @@ describe('CreateWorkItemModal', () => {
|
|||
preselectedWorkItemType = 'EPIC',
|
||||
relatedItem = null,
|
||||
alwaysShowWorkItemTypeSelect = false,
|
||||
namespaceFullName = 'GitLab.org / GitLab',
|
||||
} = {}) => {
|
||||
wrapper = shallowMount(CreateWorkItemModal, {
|
||||
propsData: {
|
||||
|
|
@ -51,6 +52,7 @@ describe('CreateWorkItemModal', () => {
|
|||
hideButton,
|
||||
relatedItem,
|
||||
alwaysShowWorkItemTypeSelect,
|
||||
namespaceFullName,
|
||||
},
|
||||
provide: {
|
||||
fullPath: 'full-path',
|
||||
|
|
@ -88,6 +90,7 @@ describe('CreateWorkItemModal', () => {
|
|||
await nextTick();
|
||||
|
||||
expect(findCreateModal().props('visible')).toBe(true);
|
||||
expect(findForm().props('namespaceFullName')).toBe('GitLab.org / GitLab');
|
||||
expect(mockEvent.preventDefault).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -241,9 +241,13 @@ describe('Create work item component', () => {
|
|||
);
|
||||
|
||||
it('defaults the selected project to the injected `fullPath` value', async () => {
|
||||
createComponent({ props: { showProjectSelector: true } });
|
||||
const namespaceFullName = 'GitLab.org / GitLab';
|
||||
createComponent({
|
||||
props: { showProjectSelector: true, namespaceFullName },
|
||||
});
|
||||
await waitForPromises();
|
||||
|
||||
expect(findProjectsSelector().props('currentProjectName')).toBe(namespaceFullName);
|
||||
expect(findProjectsSelector().props('selectedProjectFullPath')).toBe('full-path');
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -299,16 +299,17 @@ describe('Work item add note', () => {
|
|||
|
||||
describe('when the work item type is changed to incident', () => {
|
||||
it.each`
|
||||
command | shouldPerformReload
|
||||
${'/promote_to_incident'} | ${true}
|
||||
${'/type Incident'} | ${true}
|
||||
${'/type incident'} | ${true}
|
||||
${'/promote_to Incident'} | ${true}
|
||||
${'/promote_to incident'} | ${true}
|
||||
${'/promote_to Epic'} | ${false}
|
||||
${'/type Issue'} | ${false}
|
||||
${'/type Task'} | ${false}
|
||||
${'No quick action'} | ${false}
|
||||
command | shouldPerformReload
|
||||
${'/promote_to_incident'} | ${true}
|
||||
${'/type Incident'} | ${true}
|
||||
${'/type incident'} | ${true}
|
||||
${'/promote_to Incident'} | ${true}
|
||||
${'/promote_to incident'} | ${true}
|
||||
${'/convert_to_ticket user@example.com'} | ${true}
|
||||
${'/promote_to Epic'} | ${false}
|
||||
${'/type Issue'} | ${false}
|
||||
${'/type Task'} | ${false}
|
||||
${'No quick action'} | ${false}
|
||||
`(
|
||||
'calls visitUrl $shouldPerformReload when note was added with command: $command',
|
||||
async ({ command, shouldPerformReload }) => {
|
||||
|
|
|
|||
|
|
@ -143,6 +143,7 @@ describe('WorkItemActions component', () => {
|
|||
workItemsBeta = true,
|
||||
parentId = null,
|
||||
projectId = 'gid://gitlab/Project/1',
|
||||
namespaceFullName = 'GitLab.org / GitLab Test',
|
||||
} = {}) => {
|
||||
wrapper = shallowMountExtended(WorkItemActions, {
|
||||
isLoggedIn: isLoggedIn(),
|
||||
|
|
@ -179,6 +180,7 @@ describe('WorkItemActions component', () => {
|
|||
canCreateRelatedItem,
|
||||
parentId,
|
||||
projectId,
|
||||
namespaceFullName,
|
||||
showSidebar: true,
|
||||
truncationEnabled: true,
|
||||
},
|
||||
|
|
@ -666,6 +668,7 @@ describe('WorkItemActions component', () => {
|
|||
it('passes related item data to create work item modal', () => {
|
||||
createComponent();
|
||||
|
||||
expect(findCreateWorkItemModal().props('namespaceFullName')).toBe('GitLab.org / GitLab Test');
|
||||
expect(findCreateWorkItemModal().props('relatedItem')).toEqual({
|
||||
id: 'gid://gitlab/WorkItem/1',
|
||||
reference: 'gitlab-org/gitlab-test#1',
|
||||
|
|
|
|||
|
|
@ -251,6 +251,7 @@ and more text
|
|||
and even more`,
|
||||
hideButton: true,
|
||||
isGroup: false,
|
||||
namespaceFullName: '',
|
||||
parentId: 'gid://gitlab/WorkItem/818',
|
||||
relatedItem: null,
|
||||
showProjectSelector: false,
|
||||
|
|
|
|||
|
|
@ -33,7 +33,8 @@ RSpec.describe GitlabSchema.types['Group'], feature_category: :groups_and_projec
|
|||
contact_state_counts contacts work_item_types
|
||||
recent_issue_boards ci_variables releases environment_scopes work_items autocomplete_users
|
||||
lock_math_rendering_limits_enabled math_rendering_limits_enabled created_at updated_at
|
||||
organization_edit_path is_linked_to_subscription cluster_agents
|
||||
organization_edit_path is_linked_to_subscription cluster_agents marked_for_deletion_on
|
||||
is_adjourned_deletion_enabled permanent_deletion_date
|
||||
]
|
||||
|
||||
expect(described_class).to include_graphql_fields(*expected_fields)
|
||||
|
|
@ -290,4 +291,88 @@ RSpec.describe GitlabSchema.types['Group'], feature_category: :groups_and_projec
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'group adjourned deletion fields', feature_category: :groups_and_projects do
|
||||
let_it_be(:user) { create(:user) }
|
||||
let_it_be(:pending_delete_group) do
|
||||
create(:group_with_deletion_schedule, marked_for_deletion_on: Time.current, developers: user)
|
||||
end
|
||||
|
||||
let_it_be(:query) do
|
||||
%(
|
||||
query {
|
||||
group(fullPath: "#{pending_delete_group.full_path}") {
|
||||
markedForDeletionOn
|
||||
isAdjournedDeletionEnabled
|
||||
permanentDeletionDate
|
||||
}
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
subject(:group_data) do
|
||||
result = GitlabSchema.execute(query, context: { current_user: user }).as_json
|
||||
{
|
||||
marked_for_deletion_on: result.dig('data', 'group', 'markedForDeletionOn'),
|
||||
is_adjourned_deletion_enabled: result.dig('data', 'group', 'isAdjournedDeletionEnabled'),
|
||||
permanent_deletion_date: result.dig('data', 'group', 'permanentDeletionDate')
|
||||
}
|
||||
end
|
||||
|
||||
context 'with adjourned deletion disabled' do
|
||||
before do
|
||||
allow_next_found_instance_of(Group) do |group|
|
||||
allow(group).to receive_messages(adjourned_deletion?: false, adjourned_deletion_configured?: false)
|
||||
end
|
||||
end
|
||||
|
||||
it 'marked_for_deletion_on returns nil' do
|
||||
expect(group_data[:marked_for_deletion_on]).to be_nil
|
||||
end
|
||||
|
||||
it 'is_adjourned_deletion_enabled returns false' do
|
||||
expect(group_data[:is_adjourned_deletion_enabled]).to be false
|
||||
end
|
||||
|
||||
it 'permanent_deletion_date returns nil' do
|
||||
expect(group_data[:permanent_deletion_date]).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'with adjourned deletion enabled' do
|
||||
before do
|
||||
allow_next_found_instance_of(Group) do |group|
|
||||
allow(group).to receive_messages(adjourned_deletion?: true, adjourned_deletion_configured?: true)
|
||||
end
|
||||
end
|
||||
|
||||
it 'marked_for_deletion_on returns correct date' do
|
||||
marked_for_deletion_on_time = Time.zone.parse(group_data[:marked_for_deletion_on])
|
||||
|
||||
expect(marked_for_deletion_on_time).to eq(pending_delete_group.marked_for_deletion_on.iso8601)
|
||||
end
|
||||
|
||||
it 'is_adjourned_deletion_enabled returns true' do
|
||||
expect(group_data[:is_adjourned_deletion_enabled]).to be true
|
||||
end
|
||||
|
||||
it 'permanent_deletion_date returns correct date', :freeze_time do
|
||||
expect(group_data[:permanent_deletion_date])
|
||||
.to eq(::Gitlab::CurrentSettings.deletion_adjourned_period.days.since(Date.current).strftime('%F'))
|
||||
end
|
||||
end
|
||||
|
||||
context 'with adjourned deletion enabled globally' do
|
||||
before do
|
||||
allow_next_found_instance_of(Group) do |group|
|
||||
allow(group).to receive_messages(adjourned_deletion?: false, adjourned_deletion_configured?: true)
|
||||
end
|
||||
end
|
||||
|
||||
it 'permanent_deletion_date returns correct date', :freeze_time do
|
||||
expect(group_data[:permanent_deletion_date])
|
||||
.to eq(::Gitlab::CurrentSettings.deletion_adjourned_period.days.since(Date.current).strftime('%F'))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue