Add latest changes from gitlab-org/gitlab@master
|
@ -44,7 +44,6 @@ Graphql/Descriptions:
|
|||
# WIP See https://gitlab.com/gitlab-org/gitlab/-/issues/267606
|
||||
FactoryBot/InlineAssociation:
|
||||
Exclude:
|
||||
- 'ee/spec/factories/geo/event_log.rb'
|
||||
- 'ee/spec/factories/merge_request_blocks.rb'
|
||||
- 'ee/spec/factories/vulnerabilities/feedback.rb'
|
||||
- 'spec/factories/atlassian_identities.rb'
|
||||
|
|
|
@ -1 +1 @@
|
|||
d1f4340a1123d2436c7544d6ba64635c4c8f6104
|
||||
58bf16b78b3c99757a2f283a5befe57a2cb7f009
|
||||
|
|
|
@ -54,15 +54,17 @@ export default {
|
|||
required: false,
|
||||
},
|
||||
},
|
||||
data: () => ({
|
||||
currentServerSideSettings: {
|
||||
host: null,
|
||||
port: null,
|
||||
protocol: null,
|
||||
wafLogEnabled: null,
|
||||
ciliumLogEnabled: null,
|
||||
},
|
||||
}),
|
||||
data() {
|
||||
return {
|
||||
currentServerSideSettings: {
|
||||
host: null,
|
||||
port: null,
|
||||
protocol: null,
|
||||
wafLogEnabled: null,
|
||||
ciliumLogEnabled: null,
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
isSaving() {
|
||||
return [UPDATING].includes(this.status);
|
||||
|
|
|
@ -53,11 +53,13 @@ export default {
|
|||
}),
|
||||
},
|
||||
},
|
||||
data: () => ({
|
||||
modSecurityLogo,
|
||||
initialValue: null,
|
||||
initialMode: null,
|
||||
}),
|
||||
data() {
|
||||
return {
|
||||
modSecurityLogo,
|
||||
initialValue: null,
|
||||
initialMode: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
modSecurityEnabled: {
|
||||
get() {
|
||||
|
|
|
@ -259,19 +259,28 @@ export default {
|
|||
class="line-resolve-btn note-action-button"
|
||||
@click="onResolve"
|
||||
/>
|
||||
<a
|
||||
<gl-button
|
||||
v-if="canAwardEmoji"
|
||||
v-gl-tooltip
|
||||
:class="{ 'js-user-authored': isAuthoredByCurrentUser }"
|
||||
class="note-action-button note-emoji-button js-add-award js-note-emoji gl-text-gray-600 gl-m-2"
|
||||
href="#"
|
||||
class="note-action-button note-emoji-button add-reaction-button js-add-award js-note-emoji"
|
||||
category="tertiary"
|
||||
variant="default"
|
||||
size="small"
|
||||
title="Add reaction"
|
||||
data-position="right"
|
||||
:aria-label="__('Add reaction')"
|
||||
>
|
||||
<gl-icon class="link-highlight award-control-icon-neutral" name="slight-smile" />
|
||||
<gl-icon class="link-highlight award-control-icon-positive" name="smiley" />
|
||||
<gl-icon class="link-highlight award-control-icon-super-positive" name="smile" />
|
||||
</a>
|
||||
<span class="reaction-control-icon reaction-control-icon-neutral">
|
||||
<gl-icon name="slight-smile" />
|
||||
</span>
|
||||
<span class="reaction-control-icon reaction-control-icon-positive">
|
||||
<gl-icon name="smiley" />
|
||||
</span>
|
||||
<span class="reaction-control-icon reaction-control-icon-super-positive">
|
||||
<gl-icon name="smile" />
|
||||
</span>
|
||||
</gl-button>
|
||||
<reply-button
|
||||
v-if="showReply"
|
||||
ref="replyButton"
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
<script>
|
||||
import ForkForm from './fork_form.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ForkForm,
|
||||
},
|
||||
props: {
|
||||
forkIllustration: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
endpoint: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
projectFullPath: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
projectId: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
projectName: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
projectPath: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
projectDescription: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
projectVisibility: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="row gl-mt-5">
|
||||
<div class="col-lg-3">
|
||||
<img :src="forkIllustration" />
|
||||
<h4 class="">{{ s__('ForkProject|Fork project') }}</h4>
|
||||
<p>
|
||||
{{ s__('ForkProject|A fork is a copy of a project.') }}
|
||||
<br />
|
||||
{{
|
||||
s__(
|
||||
'ForkProject|Forking a repository allows you to make changes without affecting the original project.',
|
||||
)
|
||||
}}
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-lg-9">
|
||||
<fork-form
|
||||
:endpoint="endpoint"
|
||||
:project-full-path="projectFullPath"
|
||||
:project-id="projectId"
|
||||
:project-name="projectName"
|
||||
:project-path="projectPath"
|
||||
:project-description="projectDescription"
|
||||
:project-visibility="projectVisibility"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
|
@ -45,23 +45,23 @@ export default {
|
|||
GlFormRadioGroup,
|
||||
GlFormSelect,
|
||||
},
|
||||
inject: {
|
||||
newGroupPath: {
|
||||
default: '',
|
||||
},
|
||||
visibilityHelpPath: {
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
props: {
|
||||
endpoint: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
newGroupPath: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
projectFullPath: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
visibilityHelpPath: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
projectId: {
|
||||
type: String,
|
||||
required: true,
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import Vue from 'vue';
|
||||
import ForkForm from './components/fork_form.vue';
|
||||
import App from './components/app.vue';
|
||||
import ForkGroupsList from './components/fork_groups_list.vue';
|
||||
|
||||
const mountElement = document.getElementById('fork-groups-mount-element');
|
||||
|
||||
if (gon.features.forkProjectForm) {
|
||||
const {
|
||||
forkIllustration,
|
||||
endpoint,
|
||||
newGroupPath,
|
||||
projectFullPath,
|
||||
|
@ -20,9 +21,14 @@ if (gon.features.forkProjectForm) {
|
|||
// eslint-disable-next-line no-new
|
||||
new Vue({
|
||||
el: mountElement,
|
||||
provide: {
|
||||
newGroupPath,
|
||||
visibilityHelpPath,
|
||||
},
|
||||
render(h) {
|
||||
return h(ForkForm, {
|
||||
return h(App, {
|
||||
props: {
|
||||
forkIllustration,
|
||||
endpoint,
|
||||
newGroupPath,
|
||||
projectFullPath,
|
||||
|
|
|
@ -86,12 +86,11 @@ export default {
|
|||
];
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
// eslint-disable-next-line promise/catch-or-return
|
||||
this.initializeRelease().then(() => {
|
||||
// Focus the first non-disabled input element
|
||||
this.$el.querySelector('input:enabled').focus();
|
||||
});
|
||||
async mounted() {
|
||||
await this.initializeRelease();
|
||||
|
||||
// Focus the first non-disabled input or button element
|
||||
this.$el.querySelector('input:enabled, button:enabled').focus();
|
||||
},
|
||||
methods: {
|
||||
...mapActions('detail', [
|
||||
|
|
|
@ -1,20 +1,29 @@
|
|||
<script>
|
||||
import { GlFormGroup, GlFormInput } from '@gitlab/ui';
|
||||
import { GlFormGroup, GlDropdownItem, GlSprintf } from '@gitlab/ui';
|
||||
import { uniqueId } from 'lodash';
|
||||
import { mapState, mapActions, mapGetters } from 'vuex';
|
||||
import { __ } from '~/locale';
|
||||
import RefSelector from '~/ref/components/ref_selector.vue';
|
||||
import { REF_TYPE_TAGS } from '~/ref/constants';
|
||||
import FormFieldContainer from './form_field_container.vue';
|
||||
|
||||
export default {
|
||||
name: 'TagFieldNew',
|
||||
components: { GlFormGroup, GlFormInput, RefSelector, FormFieldContainer },
|
||||
components: {
|
||||
GlFormGroup,
|
||||
RefSelector,
|
||||
FormFieldContainer,
|
||||
GlDropdownItem,
|
||||
GlSprintf,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// Keeps track of whether or not the user has interacted with
|
||||
// the input field. This is used to avoid showing validation
|
||||
// errors immediately when the page loads.
|
||||
isInputDirty: false,
|
||||
|
||||
showCreateFrom: true,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
@ -26,6 +35,12 @@ export default {
|
|||
},
|
||||
set(tagName) {
|
||||
this.updateReleaseTagName(tagName);
|
||||
|
||||
// This setter is used by the `v-model` on the `RefSelector`.
|
||||
// When this is called, the selection originated from the
|
||||
// dropdown list of existing tag names, so we know the tag
|
||||
// already exists and don't need to show the "create from" input
|
||||
this.showCreateFrom = false;
|
||||
},
|
||||
},
|
||||
createFromModel: {
|
||||
|
@ -51,12 +66,28 @@ export default {
|
|||
markInputAsDirty() {
|
||||
this.isInputDirty = true;
|
||||
},
|
||||
createTagClicked(newTagName) {
|
||||
this.updateReleaseTagName(newTagName);
|
||||
|
||||
// This method is called when the user selects the "create tag"
|
||||
// option, so the tag does not already exist. Because of this,
|
||||
// we need to show the "create from" input.
|
||||
this.showCreateFrom = true;
|
||||
},
|
||||
},
|
||||
translations: {
|
||||
noRefSelected: __('No source selected'),
|
||||
searchPlaceholder: __('Search branches, tags, and commits'),
|
||||
dropdownHeader: __('Select source'),
|
||||
tagName: {
|
||||
noRefSelected: __('No tag selected'),
|
||||
dropdownHeader: __('Tag name'),
|
||||
searchPlaceholder: __('Search or create tag'),
|
||||
},
|
||||
createFrom: {
|
||||
noRefSelected: __('No source selected'),
|
||||
searchPlaceholder: __('Search branches, tags, and commits'),
|
||||
dropdownHeader: __('Select source'),
|
||||
},
|
||||
},
|
||||
tagNameEnabledRefTypes: [REF_TYPE_TAGS],
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
|
@ -69,17 +100,34 @@ export default {
|
|||
:invalid-feedback="__('Tag name is required')"
|
||||
>
|
||||
<form-field-container>
|
||||
<gl-form-input
|
||||
<ref-selector
|
||||
:id="tagNameInputId"
|
||||
v-model="tagName"
|
||||
:project-id="projectId"
|
||||
:translations="$options.translations.tagName"
|
||||
:enabled-ref-types="$options.tagNameEnabledRefTypes"
|
||||
:state="!showTagNameValidationError"
|
||||
type="text"
|
||||
class="form-control"
|
||||
@blur.once="markInputAsDirty"
|
||||
/>
|
||||
@hide.once="markInputAsDirty"
|
||||
>
|
||||
<template #footer="{ isLoading, matches, query }">
|
||||
<gl-dropdown-item
|
||||
v-if="!isLoading && matches && matches.tags.totalCount === 0"
|
||||
is-check-item
|
||||
:is-checked="tagName === query"
|
||||
@click="createTagClicked(query)"
|
||||
>
|
||||
<gl-sprintf :message="__('Create tag %{tagName}')">
|
||||
<template #tagName>
|
||||
<b>{{ query }}</b>
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
</gl-dropdown-item>
|
||||
</template>
|
||||
</ref-selector>
|
||||
</form-field-container>
|
||||
</gl-form-group>
|
||||
<gl-form-group
|
||||
v-if="showCreateFrom"
|
||||
:label="__('Create from')"
|
||||
:label-for="createFromSelectorId"
|
||||
data-testid="create-from-field"
|
||||
|
@ -89,7 +137,7 @@ export default {
|
|||
:id="createFromSelectorId"
|
||||
v-model="createFromModel"
|
||||
:project-id="projectId"
|
||||
:translations="$options.translations"
|
||||
:translations="$options.translations.createFrom"
|
||||
/>
|
||||
</form-field-container>
|
||||
<template #description>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script>
|
||||
import { GlLink, GlSprintf, GlTable, GlAlert } from '@gitlab/ui';
|
||||
import { GlLink, GlTable, GlAlert } from '@gitlab/ui';
|
||||
import { s__, sprintf } from '~/locale';
|
||||
import {
|
||||
REPORT_TYPE_SAST,
|
||||
|
@ -8,10 +8,11 @@ import {
|
|||
REPORT_TYPE_DEPENDENCY_SCANNING,
|
||||
REPORT_TYPE_CONTAINER_SCANNING,
|
||||
REPORT_TYPE_COVERAGE_FUZZING,
|
||||
REPORT_TYPE_API_FUZZING,
|
||||
REPORT_TYPE_LICENSE_COMPLIANCE,
|
||||
} from '~/vue_shared/security_reports/constants';
|
||||
import { features } from './features_constants';
|
||||
import ManageSast from './manage_sast.vue';
|
||||
import { scanners } from './scanners_constants';
|
||||
import Upgrade from './upgrade.vue';
|
||||
|
||||
const borderClasses = 'gl-border-b-1! gl-border-b-solid! gl-border-gray-100!';
|
||||
|
@ -20,14 +21,14 @@ const thClass = `gl-text-gray-900 gl-bg-transparent! ${borderClasses}`;
|
|||
export default {
|
||||
components: {
|
||||
GlLink,
|
||||
GlSprintf,
|
||||
GlTable,
|
||||
GlAlert,
|
||||
},
|
||||
data: () => ({
|
||||
features,
|
||||
errorMessage: '',
|
||||
}),
|
||||
data() {
|
||||
return {
|
||||
errorMessage: '',
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
getFeatureDocumentationLinkLabel(item) {
|
||||
return sprintf(s__('SecurityConfiguration|Feature documentation for %{featureName}'), {
|
||||
|
@ -45,6 +46,7 @@ export default {
|
|||
[REPORT_TYPE_DEPENDENCY_SCANNING]: Upgrade,
|
||||
[REPORT_TYPE_CONTAINER_SCANNING]: Upgrade,
|
||||
[REPORT_TYPE_COVERAGE_FUZZING]: Upgrade,
|
||||
[REPORT_TYPE_API_FUZZING]: Upgrade,
|
||||
[REPORT_TYPE_LICENSE_COMPLIANCE]: Upgrade,
|
||||
};
|
||||
|
||||
|
@ -64,7 +66,7 @@ export default {
|
|||
thClass,
|
||||
},
|
||||
],
|
||||
items: features,
|
||||
items: scanners,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -14,9 +14,11 @@ export default {
|
|||
default: '',
|
||||
},
|
||||
},
|
||||
data: () => ({
|
||||
isLoading: false,
|
||||
}),
|
||||
data() {
|
||||
return {
|
||||
isLoading: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
async mutate() {
|
||||
this.isLoading = true;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { helpPagePath } from '~/helpers/help_page_helper';
|
||||
import { s__ } from '~/locale';
|
||||
import { __, s__ } from '~/locale';
|
||||
|
||||
import {
|
||||
REPORT_TYPE_SAST,
|
||||
|
@ -9,58 +9,65 @@ import {
|
|||
REPORT_TYPE_DEPENDENCY_SCANNING,
|
||||
REPORT_TYPE_CONTAINER_SCANNING,
|
||||
REPORT_TYPE_COVERAGE_FUZZING,
|
||||
REPORT_TYPE_API_FUZZING,
|
||||
REPORT_TYPE_LICENSE_COMPLIANCE,
|
||||
} from '~/vue_shared/security_reports/constants';
|
||||
|
||||
/**
|
||||
* Translations & helpPagePaths for Static Security Configuration Page
|
||||
*/
|
||||
export const SAST_NAME = s__('Static Application Security Testing (SAST)');
|
||||
export const SAST_DESCRIPTION = s__('Analyze your source code for known vulnerabilities.');
|
||||
export const SAST_NAME = __('Static Application Security Testing (SAST)');
|
||||
export const SAST_DESCRIPTION = __('Analyze your source code for known vulnerabilities.');
|
||||
export const SAST_HELP_PATH = helpPagePath('user/application_security/sast/index');
|
||||
|
||||
export const DAST_NAME = s__('Dynamic Application Security Testing (DAST)');
|
||||
export const DAST_DESCRIPTION = s__('Analyze a review version of your web application.');
|
||||
export const DAST_NAME = __('Dynamic Application Security Testing (DAST)');
|
||||
export const DAST_DESCRIPTION = __('Analyze a review version of your web application.');
|
||||
export const DAST_HELP_PATH = helpPagePath('user/application_security/dast/index');
|
||||
|
||||
export const DAST_PROFILES_NAME = s__('DAST Scans');
|
||||
export const DAST_PROFILES_DESCRIPTION = s__('Analyze a review version of your web application.');
|
||||
export const DAST_PROFILES_NAME = __('DAST Scans');
|
||||
export const DAST_PROFILES_DESCRIPTION = __(
|
||||
'Saved scan settings and target site settings which are reusable.',
|
||||
);
|
||||
export const DAST_PROFILES_HELP_PATH = helpPagePath('user/application_security/dast/index');
|
||||
|
||||
export const SECRET_DETECTION_NAME = s__('Secret Detection');
|
||||
export const SECRET_DETECTION_DESCRIPTION = s__(
|
||||
export const SECRET_DETECTION_NAME = __('Secret Detection');
|
||||
export const SECRET_DETECTION_DESCRIPTION = __(
|
||||
'Analyze your source code and git history for secrets.',
|
||||
);
|
||||
export const SECRET_DETECTION_HELP_PATH = helpPagePath(
|
||||
'user/application_security/secret_detection/index',
|
||||
);
|
||||
|
||||
export const DEPENDENCY_SCANNING_NAME = s__('Dependency Scanning');
|
||||
export const DEPENDENCY_SCANNING_DESCRIPTION = s__(
|
||||
export const DEPENDENCY_SCANNING_NAME = __('Dependency Scanning');
|
||||
export const DEPENDENCY_SCANNING_DESCRIPTION = __(
|
||||
'Analyze your dependencies for known vulnerabilities.',
|
||||
);
|
||||
export const DEPENDENCY_SCANNING_HELP_PATH = helpPagePath(
|
||||
'user/application_security/dependency_scanning/index',
|
||||
);
|
||||
|
||||
export const CONTAINER_SCANNING_NAME = s__('Container Scanning');
|
||||
export const CONTAINER_SCANNING_DESCRIPTION = s__(
|
||||
export const CONTAINER_SCANNING_NAME = __('Container Scanning');
|
||||
export const CONTAINER_SCANNING_DESCRIPTION = __(
|
||||
'Check your Docker images for known vulnerabilities.',
|
||||
);
|
||||
export const CONTAINER_SCANNING_HELP_PATH = helpPagePath(
|
||||
'user/application_security/container_scanning/index',
|
||||
);
|
||||
|
||||
export const COVERAGE_FUZZING_NAME = s__('Coverage Fuzzing');
|
||||
export const COVERAGE_FUZZING_DESCRIPTION = s__(
|
||||
export const COVERAGE_FUZZING_NAME = __('Coverage Fuzzing');
|
||||
export const COVERAGE_FUZZING_DESCRIPTION = __(
|
||||
'Find bugs in your code with coverage-guided fuzzing.',
|
||||
);
|
||||
export const COVERAGE_FUZZING_HELP_PATH = helpPagePath(
|
||||
'user/application_security/coverage_fuzzing/index',
|
||||
);
|
||||
|
||||
export const LICENSE_COMPLIANCE_NAME = s__('License Compliance');
|
||||
export const LICENSE_COMPLIANCE_DESCRIPTION = s__(
|
||||
export const API_FUZZING_NAME = __('API Fuzzing');
|
||||
export const API_FUZZING_DESCRIPTION = __('Find bugs in your code with API fuzzing.');
|
||||
export const API_FUZZING_HELP_PATH = helpPagePath('user/application_security/api_fuzzing/index');
|
||||
|
||||
export const LICENSE_COMPLIANCE_NAME = __('License Compliance');
|
||||
export const LICENSE_COMPLIANCE_DESCRIPTION = __(
|
||||
'Search your project dependencies for their licenses and apply policies.',
|
||||
);
|
||||
export const LICENSE_COMPLIANCE_HELP_PATH = helpPagePath(
|
||||
|
@ -71,7 +78,7 @@ export const UPGRADE_CTA = s__(
|
|||
'SecurityConfiguration|Available with %{linkStart}upgrade or free trial%{linkEnd}',
|
||||
);
|
||||
|
||||
export const features = [
|
||||
export const scanners = [
|
||||
{
|
||||
name: SAST_NAME,
|
||||
description: SAST_DESCRIPTION,
|
||||
|
@ -90,12 +97,6 @@ export const features = [
|
|||
helpPath: DAST_PROFILES_HELP_PATH,
|
||||
type: REPORT_TYPE_DAST_PROFILES,
|
||||
},
|
||||
{
|
||||
name: SECRET_DETECTION_NAME,
|
||||
description: SECRET_DETECTION_DESCRIPTION,
|
||||
helpPath: SECRET_DETECTION_HELP_PATH,
|
||||
type: REPORT_TYPE_SECRET_DETECTION,
|
||||
},
|
||||
{
|
||||
name: DEPENDENCY_SCANNING_NAME,
|
||||
description: DEPENDENCY_SCANNING_DESCRIPTION,
|
||||
|
@ -108,12 +109,24 @@ export const features = [
|
|||
helpPath: CONTAINER_SCANNING_HELP_PATH,
|
||||
type: REPORT_TYPE_CONTAINER_SCANNING,
|
||||
},
|
||||
{
|
||||
name: SECRET_DETECTION_NAME,
|
||||
description: SECRET_DETECTION_DESCRIPTION,
|
||||
helpPath: SECRET_DETECTION_HELP_PATH,
|
||||
type: REPORT_TYPE_SECRET_DETECTION,
|
||||
},
|
||||
{
|
||||
name: COVERAGE_FUZZING_NAME,
|
||||
description: COVERAGE_FUZZING_DESCRIPTION,
|
||||
helpPath: COVERAGE_FUZZING_HELP_PATH,
|
||||
type: REPORT_TYPE_COVERAGE_FUZZING,
|
||||
},
|
||||
{
|
||||
name: API_FUZZING_NAME,
|
||||
description: API_FUZZING_DESCRIPTION,
|
||||
helpPath: API_FUZZING_HELP_PATH,
|
||||
type: REPORT_TYPE_API_FUZZING,
|
||||
},
|
||||
{
|
||||
name: LICENSE_COMPLIANCE_NAME,
|
||||
description: LICENSE_COMPLIANCE_DESCRIPTION,
|
|
@ -1,6 +1,6 @@
|
|||
<script>
|
||||
import { GlLink, GlSprintf } from '@gitlab/ui';
|
||||
import { UPGRADE_CTA } from './features_constants';
|
||||
import { UPGRADE_CTA } from './scanners_constants';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
|
|
@ -70,7 +70,7 @@ export default {
|
|||
data: {
|
||||
mergeRequestSetWip: {
|
||||
errors,
|
||||
mergeRequest: { workInProgress, title },
|
||||
mergeRequest: { mergeableDiscussionsState, workInProgress, title },
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -87,6 +87,8 @@ export default {
|
|||
});
|
||||
|
||||
const data = produce(sourceData, (draftState) => {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
draftState.project.mergeRequest.mergeableDiscussionsState = mergeableDiscussionsState;
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
draftState.project.mergeRequest.workInProgress = workInProgress;
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
|
@ -107,6 +109,7 @@ export default {
|
|||
errors: [],
|
||||
mergeRequest: {
|
||||
__typename: 'MergeRequest',
|
||||
mergeableDiscussionsState: true,
|
||||
title: this.mr.title,
|
||||
workInProgress: false,
|
||||
},
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
mutation toggleWIPStatus($projectPath: ID!, $iid: String!, $wip: Boolean!) {
|
||||
mergeRequestSetWip(input: { projectPath: $projectPath, iid: $iid, wip: $wip }) {
|
||||
mergeRequest {
|
||||
mergeableDiscussionsState
|
||||
title
|
||||
workInProgress
|
||||
}
|
||||
|
|
|
@ -37,9 +37,11 @@ export default {
|
|||
required: true,
|
||||
},
|
||||
},
|
||||
data: () => ({
|
||||
state: STATE_IDLING,
|
||||
}),
|
||||
data() {
|
||||
return {
|
||||
state: STATE_IDLING,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
shortSha() {
|
||||
return truncateSha(this.diffFile.content_sha);
|
||||
|
|
|
@ -23,7 +23,7 @@ export const REPORT_TYPE_SECRET_DETECTION = 'secret_detection';
|
|||
export const REPORT_TYPE_DEPENDENCY_SCANNING = 'dependency_scanning';
|
||||
export const REPORT_TYPE_CONTAINER_SCANNING = 'container_scanning';
|
||||
export const REPORT_TYPE_COVERAGE_FUZZING = 'coverage_fuzzing';
|
||||
export const REPORT_TYPE_LICENSE_COMPLIANCE = 'license_compliance';
|
||||
export const REPORT_TYPE_LICENSE_COMPLIANCE = 'license_scanning';
|
||||
export const REPORT_TYPE_API_FUZZING = 'api_fuzzing';
|
||||
|
||||
/**
|
||||
|
|
|
@ -521,7 +521,7 @@ class ProjectsController < Projects::ApplicationController
|
|||
def export_rate_limit
|
||||
prefixed_action = "project_#{params[:action]}".to_sym
|
||||
|
||||
project_scope = params[:action] == :download_export ? @project : nil
|
||||
project_scope = params[:action] == 'download_export' ? @project : nil
|
||||
|
||||
if rate_limiter.throttled?(prefixed_action, scope: [current_user, project_scope].compact)
|
||||
rate_limiter.log_request(request, "#{prefixed_action}_request_limit".to_sym, current_user)
|
||||
|
|
|
@ -232,7 +232,7 @@ module DiffHelper
|
|||
# Always use HTML to handle case where JSON diff rendered this button
|
||||
params_copy.delete(:format)
|
||||
|
||||
link_to url_for(params_copy), id: "#{name}-diff-btn", class: (selected ? 'btn gl-button active' : 'btn gl-button'), data: { view_type: name } do
|
||||
link_to url_for(params_copy), id: "#{name}-diff-btn", class: (selected ? 'btn gl-button btn-default selected' : 'btn gl-button btn-default'), data: { view_type: name } do
|
||||
title
|
||||
end
|
||||
end
|
||||
|
|
|
@ -505,7 +505,7 @@ class Group < Namespace
|
|||
# @param only_concrete_membership [Bool] whether require admin concrete membership status
|
||||
def max_member_access_for_user(user, only_concrete_membership: false)
|
||||
return GroupMember::NO_ACCESS unless user
|
||||
return GroupMember::OWNER if user.admin? && !only_concrete_membership
|
||||
return GroupMember::OWNER if user.can_admin_all_resources? && !only_concrete_membership
|
||||
|
||||
max_member_access = members_with_parents.where(user_id: user)
|
||||
.reorder(access_level: :desc)
|
||||
|
|
|
@ -131,6 +131,10 @@ class Label < ApplicationRecord
|
|||
nil
|
||||
end
|
||||
|
||||
def self.ids_on_board(board_id)
|
||||
on_board(board_id).pluck(:label_id)
|
||||
end
|
||||
|
||||
# Searches for labels with a matching title or description.
|
||||
#
|
||||
# This method uses ILIKE on PostgreSQL.
|
||||
|
|
|
@ -191,8 +191,12 @@ class MergeRequest < ApplicationRecord
|
|||
end
|
||||
|
||||
state_machine :merge_status, initial: :unchecked do
|
||||
event :mark_as_preparing do
|
||||
transition unchecked: :preparing
|
||||
end
|
||||
|
||||
event :mark_as_unchecked do
|
||||
transition [:can_be_merged, :checking] => :unchecked
|
||||
transition [:preparing, :can_be_merged, :checking] => :unchecked
|
||||
transition [:cannot_be_merged, :cannot_be_merged_rechecking] => :cannot_be_merged_recheck
|
||||
end
|
||||
|
||||
|
@ -209,6 +213,7 @@ class MergeRequest < ApplicationRecord
|
|||
transition [:unchecked, :cannot_be_merged_recheck, :checking, :cannot_be_merged_rechecking] => :cannot_be_merged
|
||||
end
|
||||
|
||||
state :preparing
|
||||
state :unchecked
|
||||
state :cannot_be_merged_recheck
|
||||
state :checking
|
||||
|
@ -237,7 +242,7 @@ class MergeRequest < ApplicationRecord
|
|||
# Returns current merge_status except it returns `cannot_be_merged_rechecking` as `checking`
|
||||
# to avoid exposing unnecessary internal state
|
||||
def public_merge_status
|
||||
cannot_be_merged_rechecking? ? 'checking' : merge_status
|
||||
cannot_be_merged_rechecking? || preparing? ? 'checking' : merge_status
|
||||
end
|
||||
|
||||
validates :source_project, presence: true, unless: [:allow_broken, :importing?, :closed_or_merged_without_fork?]
|
||||
|
|
|
@ -1704,6 +1704,10 @@ class User < ApplicationRecord
|
|||
can?(:read_all_resources)
|
||||
end
|
||||
|
||||
def can_admin_all_resources?
|
||||
can?(:admin_all_resources)
|
||||
end
|
||||
|
||||
def update_two_factor_requirement
|
||||
periods = expanded_groups_requiring_two_factor_authentication.pluck(:two_factor_grace_period)
|
||||
|
||||
|
|
|
@ -55,14 +55,17 @@ class BasePolicy < DeclarativePolicy::Base
|
|||
prevent :read_cross_project
|
||||
end
|
||||
|
||||
# Policy extended in EE to also enable auditors
|
||||
rule { admin }.enable :read_all_resources
|
||||
rule { admin }.policy do
|
||||
# Only for actual administrator accounts, behaviour affected by admin mode application setting
|
||||
enable :admin_all_resources
|
||||
# Policy extended in EE to also enable auditors
|
||||
enable :read_all_resources
|
||||
enable :change_repository_storage
|
||||
end
|
||||
|
||||
rule { default }.enable :read_cross_project
|
||||
|
||||
condition(:is_gitlab_com) { ::Gitlab.dev_env_or_com? }
|
||||
|
||||
rule { admin }.enable :change_repository_storage
|
||||
end
|
||||
|
||||
BasePolicy.prepend_if_ee('EE::BasePolicy')
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Boards
|
||||
class BaseItemMoveService < Boards::BaseService
|
||||
def execute(issuable)
|
||||
issuable_modification_params = issuable_params(issuable)
|
||||
return false if issuable_modification_params.empty?
|
||||
|
||||
move_single_issuable(issuable, issuable_modification_params)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def issuable_params(issuable)
|
||||
attrs = {}
|
||||
|
||||
if move_between_lists?
|
||||
attrs.merge!(
|
||||
add_label_ids: add_label_ids,
|
||||
remove_label_ids: remove_label_ids,
|
||||
state_event: issuable_state
|
||||
)
|
||||
end
|
||||
|
||||
attrs
|
||||
end
|
||||
|
||||
def move_single_issuable(issuable, issuable_modification_params)
|
||||
ability_name = :"admin_#{issuable.to_ability_name}"
|
||||
return unless can?(current_user, ability_name, issuable)
|
||||
|
||||
update(issuable, issuable_modification_params)
|
||||
end
|
||||
|
||||
def move_between_lists?
|
||||
moving_from_list.present? && moving_to_list.present? &&
|
||||
moving_from_list != moving_to_list
|
||||
end
|
||||
|
||||
def moving_from_list
|
||||
return unless params[:from_list_id].present?
|
||||
|
||||
@moving_from_list ||= board.lists.id_in(params[:from_list_id]).first
|
||||
end
|
||||
|
||||
def moving_to_list
|
||||
return unless params[:to_list_id].present?
|
||||
|
||||
@moving_to_list ||= board.lists.id_in(params[:to_list_id]).first
|
||||
end
|
||||
|
||||
def issuable_state
|
||||
return 'reopen' if moving_from_list.closed?
|
||||
return 'close' if moving_to_list.closed?
|
||||
end
|
||||
|
||||
def add_label_ids
|
||||
[moving_to_list.label_id].compact
|
||||
end
|
||||
|
||||
def remove_label_ids
|
||||
label_ids =
|
||||
if moving_to_list.movable?
|
||||
moving_from_list.label_id
|
||||
else
|
||||
::Label.ids_on_board(board.id)
|
||||
end
|
||||
|
||||
Array(label_ids).compact
|
||||
end
|
||||
end
|
||||
end
|
|
@ -2,13 +2,8 @@
|
|||
|
||||
module Boards
|
||||
module Issues
|
||||
class MoveService < Boards::BaseService
|
||||
def execute(issue)
|
||||
issue_modification_params = issue_params(issue)
|
||||
return false if issue_modification_params.empty?
|
||||
|
||||
move_single_issue(issue, issue_modification_params)
|
||||
end
|
||||
class MoveService < Boards::BaseItemMoveService
|
||||
extend ::Gitlab::Utils::Override
|
||||
|
||||
def execute_multiple(issues)
|
||||
return execute_multiple_empty_result if issues.empty?
|
||||
|
@ -16,7 +11,7 @@ module Boards
|
|||
handled_issues = []
|
||||
last_inserted_issue_id = nil
|
||||
count = issues.each.inject(0) do |moved_count, issue|
|
||||
issue_modification_params = issue_params(issue)
|
||||
issue_modification_params = issuable_params(issue)
|
||||
next moved_count if issue_modification_params.empty?
|
||||
|
||||
if last_inserted_issue_id
|
||||
|
@ -24,7 +19,7 @@ module Boards
|
|||
end
|
||||
|
||||
last_inserted_issue_id = issue.id
|
||||
handled_issue = move_single_issue(issue, issue_modification_params)
|
||||
handled_issue = move_single_issuable(issue, issue_modification_params)
|
||||
handled_issues << present_issue_entity(handled_issue) if handled_issue
|
||||
handled_issue && handled_issue.valid? ? moved_count + 1 : moved_count
|
||||
end
|
||||
|
@ -54,51 +49,17 @@ module Boards
|
|||
move_between_ids({ move_after_id: nil, move_before_id: id })
|
||||
end
|
||||
|
||||
def move_single_issue(issue, issue_modification_params)
|
||||
return unless can?(current_user, :update_issue, issue)
|
||||
|
||||
update(issue, issue_modification_params)
|
||||
end
|
||||
|
||||
def board
|
||||
@board ||= parent.boards.find(params[:board_id])
|
||||
end
|
||||
|
||||
def move_between_lists?
|
||||
moving_from_list.present? && moving_to_list.present? &&
|
||||
moving_from_list != moving_to_list
|
||||
end
|
||||
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
def moving_from_list
|
||||
return unless params[:from_list_id].present?
|
||||
|
||||
@moving_from_list ||= board.lists.find_by(id: params[:from_list_id])
|
||||
end
|
||||
# rubocop: enable CodeReuse/ActiveRecord
|
||||
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
def moving_to_list
|
||||
return unless params[:to_list_id].present?
|
||||
|
||||
@moving_to_list ||= board.lists.find_by(id: params[:to_list_id])
|
||||
end
|
||||
# rubocop: enable CodeReuse/ActiveRecord
|
||||
|
||||
def update(issue, issue_modification_params)
|
||||
::Issues::UpdateService.new(issue.project, current_user, issue_modification_params).execute(issue)
|
||||
end
|
||||
|
||||
def issue_params(issue)
|
||||
attrs = {}
|
||||
|
||||
if move_between_lists?
|
||||
attrs.merge!(
|
||||
add_label_ids: add_label_ids,
|
||||
remove_label_ids: remove_label_ids,
|
||||
state_event: issue_state
|
||||
)
|
||||
end
|
||||
override :issuable_params
|
||||
def issuable_params(issuable)
|
||||
attrs = super
|
||||
|
||||
move_between_ids = move_between_ids(params)
|
||||
if move_between_ids
|
||||
|
@ -109,28 +70,6 @@ module Boards
|
|||
attrs
|
||||
end
|
||||
|
||||
def issue_state
|
||||
return 'reopen' if moving_from_list.closed?
|
||||
return 'close' if moving_to_list.closed?
|
||||
end
|
||||
|
||||
def add_label_ids
|
||||
[moving_to_list.label_id].compact
|
||||
end
|
||||
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
def remove_label_ids
|
||||
label_ids =
|
||||
if moving_to_list.movable?
|
||||
moving_from_list.label_id
|
||||
else
|
||||
::Label.on_board(board.id).pluck(:label_id)
|
||||
end
|
||||
|
||||
Array(label_ids).compact
|
||||
end
|
||||
# rubocop: enable CodeReuse/ActiveRecord
|
||||
|
||||
def move_between_ids(move_params)
|
||||
ids = [move_params[:move_after_id], move_params[:move_before_id]]
|
||||
.map(&:to_i)
|
||||
|
|
|
@ -3,6 +3,13 @@
|
|||
module MergeRequests
|
||||
class AfterCreateService < MergeRequests::BaseService
|
||||
def execute(merge_request)
|
||||
prepare_merge_request(merge_request)
|
||||
merge_request.mark_as_unchecked if merge_request.preparing?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def prepare_merge_request(merge_request)
|
||||
event_service.open_mr(merge_request, current_user)
|
||||
|
||||
merge_request_activity_counter.track_create_mr_action(user: current_user)
|
||||
|
|
|
@ -1,28 +1,29 @@
|
|||
- page_title _("Fork project")
|
||||
- page_title s_("ForkProject|Fork project")
|
||||
|
||||
.row.gl-mt-3
|
||||
.col-lg-3
|
||||
%h4.gl-mt-0
|
||||
= _("Fork project")
|
||||
%p
|
||||
= _("A fork is a copy of a project.")
|
||||
%br
|
||||
= _('Forking a repository allows you to make changes without affecting the original project.')
|
||||
.col-lg-9
|
||||
- if Feature.enabled?(:fork_project_form)
|
||||
#fork-groups-mount-element{ data: { endpoint: new_project_fork_path(@project, format: :json),
|
||||
new_group_path: new_group_path,
|
||||
project_full_path: project_path(@project),
|
||||
visibility_help_path: help_page_path("public_access/public_access"),
|
||||
project_id: @project.id,
|
||||
project_name: @project.name,
|
||||
project_path: @project.path,
|
||||
project_description: @project.description,
|
||||
project_visibility: @project.visibility } }
|
||||
- else
|
||||
- if Feature.enabled?(:fork_project_form)
|
||||
#fork-groups-mount-element{ data: { fork_illustration: image_path('illustrations/project-create-new-sm.svg'),
|
||||
endpoint: new_project_fork_path(@project, format: :json),
|
||||
new_group_path: new_group_path,
|
||||
project_full_path: project_path(@project),
|
||||
visibility_help_path: help_page_path("public_access/public_access"),
|
||||
project_id: @project.id,
|
||||
project_name: @project.name,
|
||||
project_path: @project.path,
|
||||
project_description: @project.description,
|
||||
project_visibility: @project.visibility } }
|
||||
- else
|
||||
.row.gl-mt-3
|
||||
.col-lg-3
|
||||
%h4.gl-mt-0
|
||||
= s_("ForkProject|Fork project")
|
||||
%p
|
||||
= s_("ForkProject|A fork is a copy of a project.")
|
||||
%br
|
||||
= s_('ForkProject|Forking a repository allows you to make changes without affecting the original project.')
|
||||
.col-lg-9
|
||||
- if @own_namespace.present?
|
||||
.fork-thumbnail-container.js-fork-content
|
||||
%h5.gl-mt-0.gl-mb-0.gl-ml-3.gl-mr-3
|
||||
= _("Select a namespace to fork the project")
|
||||
= s_("ForkProject|Select a namespace to fork the project")
|
||||
= render 'fork_button', namespace: @own_namespace
|
||||
#fork-groups-mount-element{ data: { endpoint: new_project_fork_path(@project, format: :json) } }
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
%section.qa-deploy-tokens-settings.settings.no-animate#js-deploy-tokens{ class: ('expanded' if expanded), data: { qa_selector: 'deploy_tokens_settings_content' } }
|
||||
.settings-header
|
||||
%h4= s_('DeployTokens|Deploy tokens')
|
||||
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only= s_('DeployTokens|Deploy tokens')
|
||||
%button.btn.gl-button.btn-default.js-settings-toggle.qa-expand-deploy-keys{ type: 'button' }
|
||||
= expanded ? 'Collapse' : 'Expand'
|
||||
%p
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Project Settings Repository Deploy tokens header expands/collapses on click / tap
|
||||
merge_request: 55233
|
||||
author: Daniel Schömer
|
||||
type: changed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add API Fuzzing to Security Configuration page, and re-order scanners
|
||||
merge_request: 56022
|
||||
author:
|
||||
type: changed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Temporary make `GC.compact` no-op
|
||||
merge_request: 56079
|
||||
author:
|
||||
type: changed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Fix Web Project Export rate limiting scope
|
||||
merge_request: 55975
|
||||
author:
|
||||
type: fixed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Move add reaction button of note to gl-button
|
||||
merge_request: 53565
|
||||
author: Yogi (@yo)
|
||||
type: other
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Allow release to be created on existing tag through the UI
|
||||
merge_request: 55697
|
||||
author:
|
||||
type: added
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Use policies for group access rights as admin
|
||||
merge_request: 55349
|
||||
author: Diego Louzán
|
||||
type: changed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add selected state for diff view in commit page
|
||||
merge_request: 54762
|
||||
author: Yogi (@yo)
|
||||
type: changed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Log large multipart messages from Rack
|
||||
merge_request: 55933
|
||||
author:
|
||||
type: added
|
|
@ -0,0 +1,40 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Rack
|
||||
module Multipart
|
||||
class << self
|
||||
module MultipartPatch
|
||||
def extract_multipart(req, params = Rack::Utils.default_query_parser)
|
||||
log_multipart_warning(req) if log_large_multipart?
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
def log_multipart_warning(req)
|
||||
content_length = req.content_length.to_i
|
||||
|
||||
return unless content_length > 500_000_000
|
||||
|
||||
message = {
|
||||
message: "Large multipart body detected",
|
||||
path: req.path,
|
||||
content_length: content_length,
|
||||
correlation_id: ::Labkit::Context.correlation_id
|
||||
}
|
||||
|
||||
log_warn(message)
|
||||
end
|
||||
|
||||
def log_warn(message)
|
||||
warn message.to_json
|
||||
end
|
||||
|
||||
def log_large_multipart?
|
||||
Gitlab::Utils.to_boolean(ENV['ENABLE_RACK_MULTIPART_LOGGING'], default: true) && Gitlab.com?
|
||||
end
|
||||
end
|
||||
|
||||
prepend MultipartPatch
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,21 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Be sure to restart your server when you modify this file.
|
||||
#
|
||||
# Disables `GC.compact` method via monkey-patching.
|
||||
# This is temporary measure to deal with reguarly appearing compacting issues (resulting in segfaults) in external gems.
|
||||
# Having this patch allow using `nakayoshi_fork` in `config/puma.rb`,
|
||||
# only without `GC.compact` (still invoking 4 GC cycles).
|
||||
# Refer to for details: https://github.com/puma/puma/blob/80274413b04fae77cac7a7fecab7d6e89204343b/lib/puma/util.rb#L27
|
||||
|
||||
# rubocop:disable Rails/Output
|
||||
module NakayoshiForkCompacting
|
||||
module MonkeyPatch
|
||||
def compact
|
||||
puts 'Note: GC compacting is currently disabled.'\
|
||||
' Refer to `config/initializers_before_autoloader/003_gc_compact.rb` for details.'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
GC.singleton_class.prepend NakayoshiForkCompacting::MonkeyPatch
|
|
@ -14,9 +14,8 @@ for updating Geo nodes.
|
|||
## Updating to GitLab 13.9
|
||||
|
||||
We've detected an issue [with a column rename](https://gitlab.com/gitlab-org/gitlab/-/issues/322991)
|
||||
that prevents regular downtime upgrades to GitLab 13.9.0 and 13.9.1. Zero-downtime upgrades are not
|
||||
affected. We are working on a patch and recommend delaying any upgrade attempt until a fixed version
|
||||
is released.
|
||||
that prevents regular downtime upgrades to GitLab 13.9.0, 13.9.1 and 13.9.2. Zero-downtime upgrades are not
|
||||
affected. To avoid this issue, upgrade to GitLab 13.9.3 or later.
|
||||
|
||||
More details are available [in this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/322991).
|
||||
|
||||
|
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 9.6 KiB |
|
@ -405,8 +405,8 @@ Rackspace Cloud is supported only with the storage-specific form.
|
|||
| `provider` | The provider name | `Rackspace` |
|
||||
| `rackspace_username` | The username of the Rackspace account with access to the container | `joe.smith` |
|
||||
| `rackspace_api_key` | The API key of the Rackspace account with access to the container | `ABC123DEF456ABC123DEF456ABC123DE` |
|
||||
| `rackspace_region` | The Rackspace storage region to use, a three letter code from the [list of service access endpoints](https://developer.rackspace.com/docs/cloud-files/v1/general-api-info/service-access/) | `iad` |
|
||||
| `rackspace_temp_url_key` | The private key you have set in the Rackspace API for [temporary URLs](https://developer.rackspace.com/docs/cloud-files/v1/use-cases/public-access-to-your-cloud-files-account/#tempurl). | `ABC123DEF456ABC123DEF456ABC123DE` |
|
||||
| `rackspace_region` | The Rackspace storage region to use, a three letter code from the [list of service access endpoints](https://docs.rackspace.com/docs/cloud-files/v1/general-api-info/service-access/) | `iad` |
|
||||
| `rackspace_temp_url_key` | The private key you have set in the Rackspace API for [temporary URLs](https://docs.rackspace.com/docs/cloud-files/v1/use-cases/public-access-to-your-cloud-files-account/#tempurl). | `ABC123DEF456ABC123DEF456ABC123DE` |
|
||||
|
||||
Regardless of whether the container has public access enabled or disabled, Fog
|
||||
uses the TempURL method to grant access to LFS objects. If you see error
|
||||
|
|
|
@ -1045,6 +1045,67 @@ project = Project.find_by_full_path('<group/project>')
|
|||
Geo::RepositorySyncService.new(project).execute
|
||||
```
|
||||
|
||||
### Blob types newer than uploads/artifacts/LFS
|
||||
|
||||
- `Packages::PackageFile`
|
||||
- `Terraform::StateVersion`
|
||||
- `MergeRequestDiff`
|
||||
|
||||
`Packages::PackageFile` is used in the following examples, but things generally work the same for the other Blob types.
|
||||
|
||||
#### The Replicator
|
||||
|
||||
The main kinds of classes are Registry, Model, and Replicator. If you have an instance of one of these classes, you can get the others. The Registry and Model mostly manage PostgreSQL DB state. The Replicator knows how to replicate/verify (or it can call a service to do it):
|
||||
|
||||
```ruby
|
||||
model_record = Packages::PackageFile.last
|
||||
model_record.replicator.registry.replicator.model_record # just showing that these methods exist
|
||||
```
|
||||
|
||||
#### Replicate a package file, synchronously, given an ID
|
||||
|
||||
```ruby
|
||||
model_record = Packages::PackageFile.find(id)
|
||||
model_record.replicator.send(:download)
|
||||
```
|
||||
|
||||
#### Replicate a package file, synchronously, given a registry ID
|
||||
|
||||
```ruby
|
||||
registry = Geo::PackageFileRegistry.find(registry_id)
|
||||
registry.replicator.send(:download)
|
||||
```
|
||||
|
||||
### Repository types newer than project/wiki repositories
|
||||
|
||||
- `SnippetRepository`
|
||||
- `GroupWikiRepository`
|
||||
|
||||
`SnippetRepository` is used in the examples below, but things generally work the same for the other Repository types.
|
||||
|
||||
#### The Replicator
|
||||
|
||||
The main kinds of classes are Registry, Model, and Replicator. If you have an instance of one of these classes, you can get the others. The Registry and Model mostly manage PostgreSQL DB state. The Replicator knows how to replicate/verify (or it can call a service to do it).
|
||||
|
||||
```ruby
|
||||
model_record = SnippetRepository.last
|
||||
model_record.replicator.registry.replicator.model_record # just showing that these methods exist
|
||||
```
|
||||
|
||||
#### Replicate a snippet repository, synchronously, given an ID
|
||||
|
||||
```ruby
|
||||
model_record = SnippetRepository.find(id)
|
||||
model_record.replicator.send(:sync_repository)
|
||||
```
|
||||
|
||||
#### Replicate a snippet repository, synchronously, given a registry ID
|
||||
|
||||
```ruby
|
||||
registry = Geo::SnippetRepositoryRegistry.find(registry_id)
|
||||
registry.replicator.send(:sync_repository)
|
||||
```
|
||||
|
||||
### Generate usage ping
|
||||
|
||||
#### Generate or get the cached usage ping
|
||||
|
|
|
@ -5,13 +5,13 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
type: reference, api
|
||||
---
|
||||
|
||||
# DORA4 Analytics Group API **(ULTIMATE ONLY)**
|
||||
# DORA4 Analytics Group API **(ULTIMATE SELF)**
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/291747) in GitLab 13.9.
|
||||
> - It's [deployed behind a feature flag](../user/feature_flags.md), disabled by default.
|
||||
> - It's disabled on GitLab.com.
|
||||
> - It's not recommended for production use.
|
||||
> - To use it in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-dora4-analytics-group-api). **(ULTIMATE ONLY)**
|
||||
> - To use it in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-dora4-analytics-group-api). **(ULTIMATE SELF)**
|
||||
|
||||
WARNING:
|
||||
This feature might not be available to you. Check the **version history** note above for details.
|
||||
|
@ -64,7 +64,7 @@ Example response:
|
|||
]
|
||||
```
|
||||
|
||||
## Enable or disable DORA4 Analytics Group API **(ULTIMATE ONLY)**
|
||||
## Enable or disable DORA4 Analytics Group API **(ULTIMATE SELF)**
|
||||
|
||||
DORA4 Analytics Group API is under development and not ready for production use. It is
|
||||
deployed behind a feature flag that is **disabled by default**.
|
||||
|
|
|
@ -5,7 +5,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
type: reference, api
|
||||
---
|
||||
|
||||
# DORA4 Analytics Project API **(ULTIMATE ONLY)**
|
||||
# DORA4 Analytics Project API **(ULTIMATE)**
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/279039) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.7.
|
||||
|
||||
|
|
|
@ -149,7 +149,7 @@ POST /projects/:id/feature_flags
|
|||
| `description` | string | no | The description of the feature flag. |
|
||||
| `active` | boolean | no | The active state of the flag. Defaults to true. [Supported](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38350) in GitLab 13.3 and later. |
|
||||
| `strategies` | JSON | no | The feature flag [strategies](../operations/feature_flags.md#feature-flag-strategies). |
|
||||
| `strategies:name` | JSON | no | The strategy name. Can be `default`, `gradualRolloutUserId`, `userWithId`, or `gitlabUserList`. In [GitLab 13.5](https://gitlab.com/gitlab-org/gitlab/-/issues/36380) and later, can be [`flexibleRollout`](https://unleash.github.io/docs/activation_strategy#flexiblerollout). |
|
||||
| `strategies:name` | JSON | no | The strategy name. Can be `default`, `gradualRolloutUserId`, `userWithId`, or `gitlabUserList`. In [GitLab 13.5](https://gitlab.com/gitlab-org/gitlab/-/issues/36380) and later, can be [`flexibleRollout`](https://docs.getunleash.io/docs/activation_strategy#flexiblerollout). |
|
||||
| `strategies:parameters` | JSON | no | The strategy parameters. |
|
||||
| `strategies:scopes` | JSON | no | The scopes for the strategy. |
|
||||
| `strategies:scopes:environment_scope` | string | no | The environment spec for the scope. |
|
||||
|
|
|
@ -2063,6 +2063,15 @@ Represents an epic board list.
|
|||
| `position` | Int | Position of the list within the board. |
|
||||
| `title` | String! | Title of the list. |
|
||||
|
||||
### `EpicMoveListPayload`
|
||||
|
||||
Autogenerated return type of EpicMoveList.
|
||||
|
||||
| Field | Type | Description |
|
||||
| ----- | ---- | ----------- |
|
||||
| `clientMutationId` | String | A unique identifier for the client performing the mutation. |
|
||||
| `errors` | String! => Array | Errors encountered during execution of the mutation. |
|
||||
|
||||
### `EpicPermissions`
|
||||
|
||||
Check permissions for the current user on an epic.
|
||||
|
@ -2602,6 +2611,30 @@ Represents an iteration object.
|
|||
| `webPath` | String! | Web path of the iteration. |
|
||||
| `webUrl` | String! | Web URL of the iteration. |
|
||||
|
||||
### `IterationCadence`
|
||||
|
||||
Represents an iteration cadence.
|
||||
|
||||
| Field | Type | Description |
|
||||
| ----- | ---- | ----------- |
|
||||
| `active` | Boolean | Whether the iteration cadence is active. |
|
||||
| `automatic` | Boolean | Whether the iteration cadence should automatically generate future iterations. |
|
||||
| `durationInWeeks` | Int! | Duration in weeks of the iterations within this cadence. |
|
||||
| `id` | IterationsCadenceID! | Global ID of the iteration cadence. |
|
||||
| `iterationsInAdvance` | Int! | Future iterations to be created when iteration cadence is set to automatic. |
|
||||
| `startDate` | Time | Timestamp of the iteration cadence start date. |
|
||||
| `title` | String! | Title of the iteration cadence. |
|
||||
|
||||
### `IterationCadenceCreatePayload`
|
||||
|
||||
Autogenerated return type of IterationCadenceCreate.
|
||||
|
||||
| Field | Type | Description |
|
||||
| ----- | ---- | ----------- |
|
||||
| `clientMutationId` | String | A unique identifier for the client performing the mutation. |
|
||||
| `errors` | String! => Array | Errors encountered during execution of the mutation. |
|
||||
| `iterationCadence` | IterationCadence | The created iteration cadence. |
|
||||
|
||||
### `JiraImport`
|
||||
|
||||
| Field | Type | Description |
|
||||
|
|
|
@ -1005,6 +1005,20 @@ If the project is a fork, and you provide a valid token to authenticate, the
|
|||
}
|
||||
```
|
||||
|
||||
Users of [GitLab Premium or higher](https://about.gitlab.com/pricing/)
|
||||
can also see the `issues_template` and `merge_requests_template` parameters:
|
||||
[introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55718)
|
||||
in GitLab 13.10.
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 3,
|
||||
"issues_template": null,
|
||||
"merge_requests_template": null,
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
## Get project users
|
||||
|
||||
Get the users list of a project.
|
||||
|
@ -1303,6 +1317,8 @@ PUT /projects/:id
|
|||
| `visibility` | string | **{dotted-circle}** No | See [project visibility level](#project-visibility-level). |
|
||||
| `wiki_access_level` | string | **{dotted-circle}** No | One of `disabled`, `private`, or `enabled`. |
|
||||
| `wiki_enabled` | boolean | **{dotted-circle}** No | _(Deprecated)_ Enable wiki for this project. Use `wiki_access_level` instead. |
|
||||
| `issues_template` **(PREMIUM)** | string | **{dotted-circle}** No | Default description for Issues. Description is parsed with GitLab Flavored Markdown. |
|
||||
| `merge_requests_template` **(PREMIUM)** | string | **{dotted-circle}** No | Default description for Merge Requests. Description is parsed with GitLab Flavored Markdown. |
|
||||
|
||||
## Fork project
|
||||
|
||||
|
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 8.0 KiB |
|
@ -7,7 +7,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
# Getting started with Continuous Deployment to AWS Elastic Container Service **(FREE)**
|
||||
|
||||
This step-by-step guide helps you use [Continuous Deployment to ECS](../index.md#deploy-your-application-to-the-aws-elastic-container-service-ecs)
|
||||
that deploys a project hosted on GitLab.com to [Elastic Container Service](https://aws.amazon.com/ecs)
|
||||
that deploys a project hosted on GitLab.com to [Elastic Container Service](https://aws.amazon.com/ecs/)
|
||||
(ECS) on AWS.
|
||||
|
||||
In this guide, you begin by creating an ECS cluster manually using the AWS console. You create and
|
||||
|
@ -59,7 +59,7 @@ container registry.
|
|||
|
||||
### Push a containerized application image to GitLab Container Registry
|
||||
|
||||
[ECS](https://aws.amazon.com/ecs) is a container orchestration service, meaning that you must
|
||||
[ECS](https://aws.amazon.com/ecs/) is a container orchestration service, meaning that you must
|
||||
provide a containerized application image during the infrastructure build. To do so, you can use
|
||||
GitLab [Auto Build](../../../topics/autodevops/stages.md#auto-build)
|
||||
and [Container Registry](../../../user/packages/container_registry/index.md).
|
||||
|
|
|
@ -23,7 +23,7 @@ it easier to [deploy to AWS](#deploy-your-application-to-the-aws-elastic-contain
|
|||
### Quick start
|
||||
|
||||
If you're using GitLab.com, see the [quick start guide](ecs/quick_start_guide.md)
|
||||
for setting up Continuous Deployment to [AWS Elastic Container Service](https://aws.amazon.com/ecs) (ECS).
|
||||
for setting up Continuous Deployment to [AWS Elastic Container Service](https://aws.amazon.com/ecs/) (ECS).
|
||||
|
||||
### Run AWS commands from GitLab CI/CD
|
||||
|
||||
|
|
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 52 KiB |
After Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 41 KiB |
After Width: | Height: | Size: 52 KiB |
|
@ -18,7 +18,7 @@ a deployment is created.
|
|||
GitLab:
|
||||
|
||||
- Provides a full history of deployments to each environment.
|
||||
- Tracks your deployments, so you always know what is currently deployed on your
|
||||
- Tracks your deployments, so you always know what is deployed on your
|
||||
servers.
|
||||
|
||||
If you have a deployment service like [Kubernetes](../../user/project/clusters/index.md)
|
||||
|
@ -116,8 +116,7 @@ In this example:
|
|||
use `$CI_ENVIRONMENT_SLUG` instead. The `$CI_ENVIRONMENT_SLUG` variable is guaranteed to be unique.
|
||||
|
||||
You do not have to use the same prefix or only slashes (`/`) in the dynamic environment name.
|
||||
However, when you use this format, you can use the [grouping similar environments](#grouping-similar-environments)
|
||||
feature.
|
||||
However, when you use this format, you can [group similar environments](#group-similar-environments).
|
||||
|
||||
NOTE:
|
||||
Some variables cannot be used as environment names or URLs.
|
||||
|
@ -184,8 +183,8 @@ deploy:
|
|||
- master
|
||||
```
|
||||
|
||||
When deploying to a Kubernetes cluster using the GitLab Kubernetes integration,
|
||||
information about the cluster and namespace is displayed above the job
|
||||
When you use the GitLab Kubernetes integration to deploy to a Kubernetes cluster,
|
||||
cluster and namespace information is displayed above the job
|
||||
trace on the deployment job page:
|
||||
|
||||
![Deployment cluster information](../img/environments_deployment_cluster_v12_8.png)
|
||||
|
@ -202,8 +201,8 @@ When you create an environment, you specify the name and URL.
|
|||
If you want to use the name or URL in another job, you can use:
|
||||
|
||||
- `$CI_ENVIRONMENT_NAME`. The name defined in the `.gitlab-ci.yml` file.
|
||||
- `$CI_ENVIRONMENT_SLUG`. A "cleaned-up" version of the name, suitable for use in URLs,
|
||||
DNS, etc. This variable is guaranteed to be unique.
|
||||
- `$CI_ENVIRONMENT_SLUG`. A "cleaned-up" version of the name, suitable for use in URL and DNS, for example.
|
||||
This variable is guaranteed to be unique.
|
||||
- `$CI_ENVIRONMENT_URL`. The environment's URL, which was specified in the
|
||||
`.gitlab-ci.yml` file or automatically assigned.
|
||||
|
||||
|
@ -220,12 +219,12 @@ If you change the name of an existing environment, the:
|
|||
In a job script, you can specify a static environment URL.
|
||||
However, there may be times when you want a dynamic URL. For example,
|
||||
if you deploy a Review App to an external hosting
|
||||
service that generates a random URL per deployment, like `https://94dd65b.amazonaws.com/qa-lambda-1234567`,
|
||||
you don't know the URL before the deployment script finishes.
|
||||
service that generates a random URL per deployment, like `https://94dd65b.amazonaws.com/qa-lambda-1234567`.
|
||||
In this case, you don't know the URL before the deployment script finishes.
|
||||
If you want to use the environment URL in GitLab, you would have to update it manually.
|
||||
|
||||
To address this problem, you can configure a deployment job to report back a set of
|
||||
variables, including the URL that was dynamically-generated by the external service.
|
||||
variables. These variables include the URL that was dynamically-generated by the external service.
|
||||
GitLab supports the [dotenv (`.env`)](https://github.com/bkeepers/dotenv) file format,
|
||||
and expands the `environment:url` value with variables defined in the `.env` file.
|
||||
|
||||
|
@ -286,23 +285,6 @@ Note the following:
|
|||
for these jobs. This ensures that runners can fetch the repository even after a feature branch is
|
||||
deleted. For more information, see [Ref Specs for Runners](../pipelines/index.md#ref-specs-for-runners).
|
||||
|
||||
## Deployment safety
|
||||
|
||||
Deployment jobs can be more sensitive than other jobs in a pipeline,
|
||||
and might need to be treated with an extra care. There are multiple features
|
||||
in GitLab that help maintain deployment security and stability.
|
||||
|
||||
- [Restrict write-access to a critical environment](deployment_safety.md#restrict-write-access-to-a-critical-environment)
|
||||
- [Limit the job-concurrency for deployment jobs](deployment_safety.md#ensure-only-one-deployment-job-runs-at-a-time)
|
||||
- [Skip outdated deployment jobs](deployment_safety.md#skip-outdated-deployment-jobs)
|
||||
- [Prevent deployments during deploy freeze windows](deployment_safety.md#prevent-deployments-during-deploy-freeze-windows)
|
||||
|
||||
## Protected environments
|
||||
|
||||
Environments can be "protected", restricting access to them.
|
||||
|
||||
For more information, see [Protected environments](protected_environments.md).
|
||||
|
||||
## Working with environments
|
||||
|
||||
Once environments are configured, GitLab provides many features for working with them,
|
||||
|
@ -331,8 +313,8 @@ To retry or rollback a deployment:
|
|||
|
||||
### Environment URL
|
||||
|
||||
The [environment URL](../yaml/README.md#environmenturl) is exposed in a few
|
||||
places within GitLab:
|
||||
The [environment URL](../yaml/README.md#environmenturl) is displayed in a few
|
||||
places in GitLab:
|
||||
|
||||
- In a merge request as a link:
|
||||
![Environment URL in merge request](../img/environments_mr_review_app.png)
|
||||
|
@ -359,8 +341,8 @@ from source files to public pages in the environment set for Review Apps.
|
|||
|
||||
When you stop an environment:
|
||||
|
||||
- It moves from the list of **Available** environments to the list of **Stopped**
|
||||
environments on the [**Environments** page](#view-environments-and-deployments).
|
||||
- On the **Environments** page, it moves from the list of **Available** environments
|
||||
to the list of **Stopped** environments.
|
||||
- An [`on_stop` action](../yaml/README.md#environmenton_stop), if defined, is executed.
|
||||
|
||||
Dynamic environments stop automatically when their associated branch is
|
||||
|
@ -368,10 +350,16 @@ deleted.
|
|||
|
||||
#### Stop an environment when a branch is deleted
|
||||
|
||||
Environments can be stopped automatically using special configuration.
|
||||
You can configure environments to stop when a branch is deleted.
|
||||
|
||||
Consider the following example where the `deploy_review` job calls `stop_review`
|
||||
to clean up and stop the environment:
|
||||
The following example shows a `deploy_review` job that calls a `stop_review` job
|
||||
to clean up and stop the environment. The `stop_review` job must be in the same
|
||||
`stage` as the `deploy_review` job.
|
||||
|
||||
Both jobs must have the same [`rules`](../yaml/README.md#onlyexcept-basic)
|
||||
or [`only/except`](../yaml/README.md#onlyexcept-basic) configuration. Otherwise,
|
||||
the `stop_review` job might not be included in all pipelines that include the
|
||||
`deploy_review` job, and you cannot trigger `action: stop` to stop the environment automatically.
|
||||
|
||||
```yaml
|
||||
deploy_review:
|
||||
|
@ -397,55 +385,30 @@ stop_review:
|
|||
when: manual
|
||||
```
|
||||
|
||||
If you can't use [Pipelines for merge requests](../merge_request_pipelines/index.md),
|
||||
setting the [`GIT_STRATEGY`](../runners/README.md#git-strategy) to `none` is necessary in the
|
||||
`stop_review` job so that the [runner](https://docs.gitlab.com/runner/) doesn't
|
||||
If you can't use [pipelines for merge requests](../merge_request_pipelines/index.md),
|
||||
set the [`GIT_STRATEGY`](../runners/README.md#git-strategy) to `none` in the
|
||||
`stop_review` job. Then the [runner](https://docs.gitlab.com/runner/) doesn't
|
||||
try to check out the code after the branch is deleted.
|
||||
|
||||
When you have an environment that has a stop action defined (typically when
|
||||
the environment describes a Review App), GitLab automatically triggers a
|
||||
stop action when the associated branch is deleted. The `stop_review` job must
|
||||
be in the same `stage` as the `deploy_review` job in order for the environment
|
||||
to automatically stop.
|
||||
|
||||
Additionally, both jobs should have matching [`rules`](../yaml/README.md#onlyexcept-basic)
|
||||
or [`only/except`](../yaml/README.md#onlyexcept-basic) configuration. In the example
|
||||
above, if the configuration isn't identical, the `stop_review` job might not be
|
||||
included in all pipelines that include the `deploy_review` job, and it isn't
|
||||
possible to trigger `action: stop` to stop the environment automatically.
|
||||
|
||||
You can read more in the [`.gitlab-ci.yml` reference](../yaml/README.md#environmenton_stop).
|
||||
Read more in the [`.gitlab-ci.yml` reference](../yaml/README.md#environmenton_stop).
|
||||
|
||||
#### Stop an environment after a certain time period
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/20956) in GitLab 12.8.
|
||||
|
||||
You can set an expiry time for environments and stop them automatically after a certain period.
|
||||
You can set environments to stop automatically after a certain time period.
|
||||
|
||||
For example, consider the use of this feature with Review App environments. When you set up Review
|
||||
Apps, sometimes they keep running for a long time because some merge requests are left open and
|
||||
forgotten. Such idle environments waste resources and should be terminated as soon as possible.
|
||||
In your `.gitlab-ci.yml` file, specify the [`environment:auto_stop_in`](../yaml/README.md#environmentauto_stop_in)
|
||||
keyword. You can specify a human-friendly date as the value, such as `1 hour and 30 minutes` or `1 day`.
|
||||
After the time period passes, GitLab automatically triggers a job to stop the environment.
|
||||
|
||||
To address this problem, you can specify an optional expiration date for Review App environments.
|
||||
When the expiry time is reached, GitLab automatically triggers a job to stop the environment,
|
||||
eliminating the need of manually doing so. In case an environment is updated, the expiration is
|
||||
renewed ensuring that only active merge requests keep running Review Apps.
|
||||
|
||||
To enable this feature, you must specify the [`environment:auto_stop_in`](../yaml/README.md#environmentauto_stop_in)
|
||||
keyword in `.gitlab-ci.yml`. You can specify a human-friendly date as the value, such as
|
||||
`1 hour and 30 minutes` or `1 day`. `auto_stop_in` uses the same format of
|
||||
[`artifacts:expire_in` docs](../yaml/README.md#artifactsexpire_in).
|
||||
|
||||
Note that due to resource limitation, a background worker for stopping environments only runs once
|
||||
Due to resource limitations, a background worker for stopping environments only runs once
|
||||
every hour. This means that environments aren't stopped at the exact timestamp specified, but are
|
||||
instead stopped when the hourly cron worker detects expired environments.
|
||||
|
||||
##### Auto-stop example
|
||||
|
||||
In the following example, there is a basic review app setup that creates a new environment
|
||||
per merge request. The `review_app` job is triggered by every push and
|
||||
creates or updates an environment named `review/your-branch-name`.
|
||||
The environment keeps running until `stop_review_app` is executed:
|
||||
In the following example, each merge request creates a new Review App environment.
|
||||
Each push triggers the `review_app` job and an environment named `review/your-branch-name`
|
||||
is created or updated. The environment runs until `stop_review_app` is executed:
|
||||
|
||||
```yaml
|
||||
review_app:
|
||||
|
@ -467,48 +430,48 @@ stop_review_app:
|
|||
when: manual
|
||||
```
|
||||
|
||||
As long as a merge request is active and keeps getting new commits,
|
||||
the review app doesn't stop, so developers don't need to worry about
|
||||
re-initiating review app.
|
||||
As long as the merge request is active and keeps getting new commits,
|
||||
the Review App doesn't stop. Developers don't need to worry about
|
||||
re-initiating Review App.
|
||||
|
||||
On the other hand, since `stop_review_app` is set to `auto_stop_in: 1 week`,
|
||||
if a merge request becomes inactive for more than a week,
|
||||
Because `stop_review_app` is set to `auto_stop_in: 1 week`,
|
||||
if a merge request is inactive for more than a week,
|
||||
GitLab automatically triggers the `stop_review_app` job to stop the environment.
|
||||
|
||||
You can also check the expiration date of environments through the GitLab UI. To do so,
|
||||
go to **Operations > Environments > Environment**. You can see the auto-stop period
|
||||
at the left-top section and a pin-mark button at the right-top section. This pin-mark
|
||||
button can be used to prevent auto-stopping the environment. By clicking this button, the
|
||||
`auto_stop_in` setting is overwritten and the environment is active until it's stopped manually.
|
||||
#### View a deployment's scheduled stop time
|
||||
|
||||
![Environment auto stop](../img/environment_auto_stop_v12_8.png)
|
||||
You can view a deployment's expiration date in the GitLab UI.
|
||||
|
||||
1. Go to the project's **Operations > Environments** page.
|
||||
1. Select the name of the deployment.
|
||||
|
||||
In the top left, next to the environment name, the expiration date is displayed.
|
||||
|
||||
#### Override a deployment's scheduled stop time
|
||||
|
||||
You can manually override a deployment's expiration date.
|
||||
|
||||
1. Go to the project's **Operations > Environments** page.
|
||||
1. Select the deployment name.
|
||||
1. In the top right, select the thumbtack (**{thumbtack}**).
|
||||
|
||||
![Environment auto stop](img/environment_auto_stop_v13_10.png)
|
||||
|
||||
The `auto_stop_in` setting is overwritten and the environment remains active until it's stopped manually.
|
||||
|
||||
#### Delete a stopped environment
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/20620) in GitLab 12.10.
|
||||
|
||||
You can delete [stopped environments](#stopping-an-environment) in one of two
|
||||
ways: through the GitLab UI or through the API.
|
||||
You can delete [stopped environments](#stopping-an-environment) in the GitLab UI or by using
|
||||
[the API](../../api/environments.md#delete-an-environment).
|
||||
|
||||
##### Delete environments through the UI
|
||||
To delete a stopped environment in the GitLab UI:
|
||||
|
||||
To view the list of **Stopped** environments, navigate to **Operations > Environments**
|
||||
and click the **Stopped** tab.
|
||||
|
||||
From there, you can click the **Delete** button directly, or you can click the
|
||||
environment name to see its details and **Delete** it from there.
|
||||
|
||||
You can also delete environments by viewing the details for a
|
||||
stopped environment:
|
||||
|
||||
1. Go to the project's **Operations > Environments** page.
|
||||
1. Click on the name of an environment within the **Stopped** environments list.
|
||||
1. Click on the **Delete** button that appears at the top for all stopped environments.
|
||||
1. Finally, confirm your chosen environment in the modal that appears to delete it.
|
||||
|
||||
##### Delete environments through the API
|
||||
|
||||
Environments can also be deleted by using the [Environments API](../../api/environments.md#delete-an-environment).
|
||||
1. Go to the project's **Operations > Environments** page.
|
||||
1. Select the **Stopped** tab.
|
||||
1. Next to the environment you want to delete, select **Delete environment**.
|
||||
1. On the confirmation dialog box, select **Delete environment**.
|
||||
|
||||
### Prepare an environment
|
||||
|
||||
|
@ -535,19 +498,19 @@ build:
|
|||
url: https://staging.example.com
|
||||
```
|
||||
|
||||
### Grouping similar environments
|
||||
### Group similar environments
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/7015) in GitLab 8.14.
|
||||
|
||||
As documented in [Create a dynamic environment](#create-a-dynamic-environment), you can
|
||||
prepend environment name with a word, followed by a `/`, and finally the branch
|
||||
name, which is automatically defined by the `CI_COMMIT_REF_NAME` predefined CI/CD variable.
|
||||
You can group environments into collapsible sections in the UI.
|
||||
|
||||
In short, environments that are named like `type/foo` are all presented under the same
|
||||
group, named `type`.
|
||||
For example, if all of your environments start with the name `review`,
|
||||
then in the UI, the environments are grouped under that heading:
|
||||
|
||||
If you name the environments `review/$CI_COMMIT_REF_NAME`
|
||||
where `$CI_COMMIT_REF_NAME` is the branch name:
|
||||
![Environment groups](img/environments_dynamic_groups_v13_10.png)
|
||||
|
||||
The following example shows how to start your environment names with `review`.
|
||||
The `$CI_COMMIT_REF_NAME` variable is populated with the branch name at runtime:
|
||||
|
||||
```yaml
|
||||
deploy_review:
|
||||
|
@ -558,11 +521,6 @@ deploy_review:
|
|||
name: review/$CI_COMMIT_REF_NAME
|
||||
```
|
||||
|
||||
If you visit the **Environments** page and the branches
|
||||
exist, you should see something like:
|
||||
|
||||
![Environment groups](../img/environments_dynamic_groups.png)
|
||||
|
||||
### Environment incident management
|
||||
|
||||
You have successfully setup a Continuous Delivery/Deployment workflow in your project.
|
||||
|
@ -634,8 +592,6 @@ Once configured, GitLab attempts to retrieve [supported performance metrics](../
|
|||
for any environment that has had a successful deployment. If monitoring data was
|
||||
successfully retrieved, a **Monitoring** button appears for each environment.
|
||||
|
||||
![Environment Detail with Metrics](../img/deployments_view.png)
|
||||
|
||||
Clicking the **Monitoring** button displays a new page showing up to the last
|
||||
8 hours of performance data. It may take a minute or two for data to appear
|
||||
after initial deployment.
|
||||
|
@ -666,13 +622,13 @@ Note that container-based deployments often lack basic tools (like an editor), a
|
|||
be stopped or restarted at any time. If this happens, you lose all your
|
||||
changes. Treat this as a debugging tool, not a comprehensive online IDE.
|
||||
|
||||
Once enabled, your environments gain a **Terminal** button:
|
||||
Once enabled, your environments display a **Terminal** button:
|
||||
|
||||
![Terminal button on environment index](../img/environments_terminal_button_on_index.png)
|
||||
![Terminal button on environment index](img/environments_terminal_button_on_index_v13_10.png)
|
||||
|
||||
You can also access the terminal button from the page for a specific environment:
|
||||
|
||||
![Terminal button for an environment](../img/environments_terminal_button_on_show.png)
|
||||
![Terminal button for an environment](img/environments_terminal_button_on_show_v13_10.png)
|
||||
|
||||
Wherever you find it, clicking the button takes you to a separate page to
|
||||
establish the terminal session:
|
||||
|
@ -749,24 +705,15 @@ such as [Review Apps](../review_apps/index.md) (`review/*`).
|
|||
Note that the most _specific_ spec takes precedence over the other wildcard matching. In this case,
|
||||
the `review/feature-1` spec takes precedence over `review/*` and `*` specs.
|
||||
|
||||
### Environments Dashboard **(PREMIUM)**
|
||||
## Related topics
|
||||
|
||||
See [Environments Dashboard](../environments/environments_dashboard.md) for a summary of each
|
||||
environment's operational health.
|
||||
|
||||
## Limitations
|
||||
|
||||
In the `environment: name`, you are limited to only the [predefined CI/CD variables](../variables/predefined_variables.md).
|
||||
Re-using variables defined inside `script` as part of the environment name doesn't work.
|
||||
|
||||
## Further reading
|
||||
|
||||
Below are some links you may find interesting:
|
||||
|
||||
- [The `.gitlab-ci.yml` definition of environments](../yaml/README.md#environment)
|
||||
- [A blog post on Deployments & Environments](https://about.gitlab.com/blog/2021/02/05/ci-deployment-and-environments/)
|
||||
- [Review Apps - Use dynamic environments to deploy your code for every branch](../review_apps/index.md)
|
||||
- [Deploy Boards for your applications running on Kubernetes](../../user/project/deploy_boards.md)
|
||||
- [Use GitLab CI to deploy to multiple environments (blog post)](https://about.gitlab.com/blog/2021/02/05/ci-deployment-and-environments/)
|
||||
- [Review Apps](../review_apps/index.md): Use dynamic environments to deploy your code for every branch.
|
||||
- [Deploy Boards](../../user/project/deploy_boards.md): View the status of your applications running on Kubernetes.
|
||||
- [Protected environments](protected_environments.md): Determine who can deploy code to your environments.
|
||||
- [Environments Dashboard](../environments/environments_dashboard.md): View a summary of each
|
||||
environment's operational health. **(PREMIUM)**
|
||||
- [Deployment safety](deployment_safety.md#restrict-write-access-to-a-critical-environment): Secure your deployments.
|
||||
|
||||
<!-- ## Troubleshooting
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ description: 'Confidence checking your entire app every time a new feature is ad
|
|||
---
|
||||
|
||||
<!-- vale off -->
|
||||
<!-- Needs review for fixing the broken Webdriver links, which link to a deprecated version of Webdriver. -->
|
||||
|
||||
# End-to-end testing with GitLab CI/CD and WebdriverIO
|
||||
|
||||
|
@ -51,14 +50,14 @@ infrastructure is up and running, and that your units of code work well together
|
|||
[Selenium](https://www.selenium.dev/) is a piece of software that can control web browsers, e.g., to make them
|
||||
visit a specific URL or interact with elements on the page. It can be programmatically controlled
|
||||
from a variety of programming languages. In this article we're going to be using the
|
||||
[WebdriverIO](https://webdriver.io/) JavaScript bindings, but the general concept should carry over
|
||||
[WebdriverIO](http://v4.webdriver.io/) JavaScript bindings, but the general concept should carry over
|
||||
pretty well to
|
||||
[other programming languages supported by Selenium](https://www.selenium.dev/documentation/en/legacy_docs/selenium_rc/).
|
||||
|
||||
## Writing tests
|
||||
|
||||
You can write tests using
|
||||
[several testing frameworks supported by WebdriverIO](https://webdriver.io/guide/testrunner/frameworks.html).
|
||||
[several testing frameworks supported by WebdriverIO](http://v4.webdriver.io/guide/testrunner/frameworks.html).
|
||||
We will be using [Jasmine](https://jasmine.github.io/) here:
|
||||
|
||||
```javascript
|
||||
|
@ -83,14 +82,14 @@ multiple tests, such as making sure you are logged in.
|
|||
|
||||
The function `it` defines an individual test.
|
||||
|
||||
[The `browser` object](https://webdriver.io/guide/testrunner/browserobject.html) is WebdriverIO's
|
||||
special sauce. It provides most of [the WebdriverIO API methods](https://webdriver.io/docs/api/) that are the key to
|
||||
[The `browser` object](http://v4.webdriver.io/guide/testrunner/browserobject.html) is WebdriverIO's
|
||||
special sauce. It provides most of [the WebdriverIO API methods](http://v4.webdriver.io/docs/api/) that are the key to
|
||||
steering the browser. In this case, we can use
|
||||
[`browser.url`](https://webdriver.io/api/protocol/url.html) to visit `/page-that-does-not-exist` to
|
||||
hit our 404 page. We can then use [`browser.getUrl`](https://webdriver.io/api/property/getUrl.html)
|
||||
[`browser.url`](http://v4.webdriver.io/api/protocol/url.html) to visit `/page-that-does-not-exist` to
|
||||
hit our 404 page. We can then use [`browser.getUrl`](http://v4.webdriver.io/api/property/getUrl.html)
|
||||
to verify that the current page is indeed at the location we specified. To interact with the page,
|
||||
we can simply pass CSS selectors to
|
||||
[`browser.element`](https://webdriver.io/api/protocol/element.html) to get access to elements on the
|
||||
[`browser.element`](http://v4.webdriver.io/api/protocol/element.html) to get access to elements on the
|
||||
page and to interact with them - for example, to click on the link back to the home page.
|
||||
|
||||
The simple test shown above
|
||||
|
@ -112,9 +111,9 @@ you can use [the Webpack Dev Server WebdriverIO plugin](https://www.npmjs.com/pa
|
|||
that automatically starts a development server before executing the tests.
|
||||
|
||||
The WebdriverIO documentation has
|
||||
[an overview of all configuration options](https://webdriver.io/guide/getstarted/configuration.html), but the
|
||||
[an overview of all configuration options](http://v4.webdriver.io/guide/getstarted/configuration.html), but the
|
||||
easiest way to get started is to start with
|
||||
[WebdriverIO's default configuration](https://webdriver.io/guide/testrunner/configurationfile.html), which
|
||||
[WebdriverIO's default configuration](http://v4.webdriver.io/guide/testrunner/configurationfile.html), which
|
||||
provides an overview of all available options. The two options that are going to be most relevant now are the
|
||||
`specs` option, which is an array of paths to your tests, and the `baseUrl` option, which points to where your app is
|
||||
running. And finally, we will need to tell WebdriverIO in which browsers we would like to run our
|
||||
|
@ -187,7 +186,7 @@ e2e:chrome:
|
|||
|
||||
Now that we have a job to run the end-to-end tests in, we need to tell WebdriverIO how to connect to
|
||||
the Selenium servers running alongside it. We've already cheated a bit above by
|
||||
passing the value of the [`host`](https://webdriver.io/guide/getstarted/configuration.html#host)
|
||||
passing the value of the [`host`](http://v4.webdriver.io/guide/getstarted/configuration.html#host)
|
||||
option as an argument to `npm run confidence-check` on the command line.
|
||||
However, we still need to tell WebdriverIO which browser is available for it to use.
|
||||
|
||||
|
@ -254,7 +253,7 @@ production project, see:
|
|||
- [Flockademic's `.gitlab-ci.yml`](https://gitlab.com/Flockademic/Flockademic/blob/dev/.gitlab-ci.yml)
|
||||
- [Flockademic's tests](https://gitlab.com/Flockademic/Flockademic/tree/dev/__e2e__)
|
||||
|
||||
There's plenty more that WebdriverIO can do. For example, you can configure a [`screenshotPath`](https://webdriver.io/guide/getstarted/configuration.html#screenshotPath) to tell WebdriverIO to take
|
||||
There's plenty more that WebdriverIO can do. For example, you can configure a [`screenshotPath`](http://v4.webdriver.io/guide/getstarted/configuration.html#screenshotPath) to tell WebdriverIO to take
|
||||
a screenshot when tests are failing. Then tell GitLab CI/CD to store those
|
||||
[artifacts](../../yaml/README.md#artifacts), and you'll be able to see what went
|
||||
wrong within GitLab.
|
||||
|
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 7.5 KiB |
|
@ -321,7 +321,3 @@ the user must enter a [personal access token](../../user/profile/personal_access
|
|||
with `api` scope before submitting feedback.
|
||||
|
||||
This same method can be used to require authentication for any public projects.
|
||||
|
||||
## Limitations
|
||||
|
||||
Review App limitations are the same as [environments limitations](../environments/index.md#limitations).
|
||||
|
|
|
@ -53,6 +53,6 @@ issue for discussion around setting up Auto DevOps development environments.
|
|||
## Monitoring on GitLab.com
|
||||
|
||||
The metric
|
||||
[`auto_devops_completed_pipelines_total`](https://thanos-query.ops.gitlab.net/graph?g0.range_input=72h&g0.max_source_resolution=0s&g0.expr=sum(increase(auto_devops_pipelines_completed_total%7Benvironment%3D%22gprd%22%7D%5B60m%5D))%20by%20(status)&g0.tab=0)
|
||||
[`auto_devops_completed_pipelines_total`](https://thanos.gitlab.net/graph?g0.range_input=72h&g0.max_source_resolution=0s&g0.expr=sum(increase(auto_devops_pipelines_completed_total%7Benvironment%3D%22gprd%22%7D%5B60m%5D))%20by%20(status)&g0.tab=0)
|
||||
(only available to GitLab team members) counts completed Auto DevOps
|
||||
pipelines, labeled by status.
|
||||
|
|
|
@ -43,7 +43,7 @@ hardcoded value (10).
|
|||
At this point, we need to investigate what is using more connections
|
||||
than we anticipated. To do that, we can use the
|
||||
`gitlab_ruby_threads_running_threads` metric. For example, [this
|
||||
graph](https://thanos-query.ops.gitlab.net/graph?g0.range_input=1h&g0.max_source_resolution=0s&g0.expr=sum%20by%20(thread_name)%20(%20gitlab_ruby_threads_running_threads%7Buses_db_connection%3D%22yes%22%7D%20)&g0.tab=0)
|
||||
graph](https://thanos.gitlab.net/graph?g0.range_input=1h&g0.max_source_resolution=0s&g0.expr=sum%20by%20(thread_name)%20(%20gitlab_ruby_threads_running_threads%7Buses_db_connection%3D%22yes%22%7D%20)&g0.tab=0)
|
||||
shows all running threads that connect to the database by their
|
||||
name. Threads labeled `puma worker` or `sidekiq_worker_thread` are
|
||||
the threads that define `Gitlab::Runtime.max_threads` so those are
|
||||
|
|
|
@ -14,6 +14,10 @@ feature flag depends on its state (enabled or disabled). When the state
|
|||
changes, the developer who made the change **must update the documentation**
|
||||
accordingly.
|
||||
|
||||
Every feature introduced to the codebase, even if it's behind a feature flag,
|
||||
must be documented. For context, see the
|
||||
[latest merge request that updated this guideline](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/47917#note_459984428).
|
||||
|
||||
## Criteria
|
||||
|
||||
According to the process of [deploying GitLab features behind feature flags](../feature_flags/process.md):
|
||||
|
|
|
@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
Experiments can be conducted by any GitLab team, most often the teams from the [Growth Sub-department](https://about.gitlab.com/handbook/engineering/development/growth/). Experiments are not tied to releases because they primarily target GitLab.com.
|
||||
|
||||
Experiments are run as an A/B test and are behind a feature flag to turn the test on or off. Based on the data the experiment generates, the team decides if the experiment had a positive impact and should be made the new default or rolled back.
|
||||
Experiments are run as an A/B/n test, and are behind a feature flag to turn the test on or off. Based on the data the experiment generates, the team decides if the experiment had a positive impact and should be made the new default, or rolled back.
|
||||
|
||||
## Experiment tracking issue
|
||||
|
||||
|
@ -36,21 +36,39 @@ and link to the issue that resolves the experiment. If the experiment is
|
|||
successful and becomes part of the product, any follow up issues should be
|
||||
addressed.
|
||||
|
||||
## Experiments using `gitlab-experiment`
|
||||
## Implement an experiment
|
||||
|
||||
There are two options to conduct experiments:
|
||||
|
||||
1. [GitLab Experiment](https://gitlab.com/gitlab-org/gitlab-experiment/) is a gem included in GitLab.
|
||||
1. [`Experimentation Module`](https://gitlab.com/gitlab-org/gitlab/blob/master/lib%2Fgitlab%2Fexperimentation.rb) is built in the GitLab codebase.
|
||||
|
||||
Both methods use [experiment](../feature_flags/development.md#experiment-type) feature flags.
|
||||
|
||||
Historical Context: `Experimentation Module` was built iteratively with the needs that appeared while implementing Growth sub-department experiments. The `gitlab-experiment` gem was built with the learnings of the `Experimentation Module` and an easier to use API.
|
||||
|
||||
Currently both methods for running experiments are included in the codebase. The features are slightly different:
|
||||
|
||||
| Feature | `Experiment Module` | `gitlab-experiment` |
|
||||
| ------ | ------ | ------ |
|
||||
| Record user grouping | Yes | No (not natively) |
|
||||
| Uses feature flags | Yes | Yes |
|
||||
| Multivariate | No | Yes |
|
||||
|
||||
However, there is currently no strong suggestion to use one over the other.
|
||||
|
||||
### Experiments using `gitlab-experiment` **(FREE SAAS)**
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/300383) in GitLab 13.7.
|
||||
> - It's [deployed behind a feature flag](../../user/feature_flags.md), disabled by default.
|
||||
> - It's enabled on GitLab.com.
|
||||
> - It is not yet intended for use in GitLab self-managed instances.
|
||||
|
||||
[GitLab Experiment](https://gitlab.com/gitlab-org/gitlab-experiment/) is a gem included
|
||||
in GitLab that can be used for running experiments.
|
||||
You find out how to conduct experiments using `gitlab-experiment` in the [README](https://gitlab.com/gitlab-org/gitlab-experiment/-/blob/master/README.md).
|
||||
|
||||
## How to create an A/B test using `experimentation.rb`
|
||||
### Experiments using the `Experimentation Module`
|
||||
|
||||
### Implement the experiment
|
||||
|
||||
1. Add the experiment to the `Gitlab::Experimentation::EXPERIMENTS` hash in [`experimentation.rb`](https://gitlab.com/gitlab-org/gitlab/blob/master/lib%2Fgitlab%2Fexperimentation.rb):
|
||||
1. Add the experiment to the `Gitlab::Experimentation::EXPERIMENTS` hash in the [`Experimentation Module`](https://gitlab.com/gitlab-org/gitlab/blob/master/lib%2Fgitlab%2Fexperimentation.rb):
|
||||
|
||||
```ruby
|
||||
EXPERIMENTS = {
|
||||
|
@ -151,13 +169,13 @@ in GitLab that can be used for running experiments.
|
|||
end
|
||||
```
|
||||
|
||||
### Implement the tracking events
|
||||
#### Implement the tracking events
|
||||
|
||||
To determine whether the experiment is a success or not, we must implement tracking events
|
||||
to acquire data for analyzing. We can send events to Snowplow via either the backend or frontend.
|
||||
Read the [product intelligence guide](https://about.gitlab.com/handbook/product/product-intelligence-guide/) for more details.
|
||||
|
||||
#### Track backend events
|
||||
##### Track backend events
|
||||
|
||||
The framework provides the following helper method that is available in controllers:
|
||||
|
||||
|
@ -190,7 +208,7 @@ context 'when the experiment is active and the user is in the experimental group
|
|||
end
|
||||
```
|
||||
|
||||
#### Track frontend events
|
||||
##### Track frontend events
|
||||
|
||||
The framework provides the following helper method that is available in controllers:
|
||||
|
||||
|
@ -273,7 +291,7 @@ describe('event tracking', () => {
|
|||
});
|
||||
```
|
||||
|
||||
### Record experiment user
|
||||
#### Record experiment user
|
||||
|
||||
In addition to the anonymous tracking of events, we can also record which users have participated in which experiments and whether they were given the control experience or the experimental experience.
|
||||
|
||||
|
@ -289,7 +307,7 @@ Subsequent calls to this method for the same experiment and the same user have n
|
|||
|
||||
Note that this data is completely separate from the [events tracking data](#implement-the-tracking-events). They are not linked together in any way.
|
||||
|
||||
#### Add context
|
||||
##### Add context
|
||||
|
||||
You can add arbitrary context data in a hash which gets stored as part of the experiment user record. New calls to the `record_experiment_user` with newer contexts get merged deeply into the existing context.
|
||||
|
||||
|
@ -306,7 +324,7 @@ record_experiment_user(:signup_flow, foo: 40, bar: { b: 2 }, thor: 3)
|
|||
# context becomes { "foo" => 40, "bar" => { "a" => 22, "b" => 2 }, "thor" => 3}
|
||||
```
|
||||
|
||||
### Record experiment conversion event
|
||||
#### Record experiment conversion event
|
||||
|
||||
Along with the tracking of backend and frontend events and the [recording of experiment participants](#record-experiment-user), we can also record when a user performs the desired conversion event action. For example:
|
||||
|
||||
|
@ -323,7 +341,7 @@ end
|
|||
|
||||
Note that the use of this method requires that we have first [recorded the user as being part of the experiment](#record-experiment-user).
|
||||
|
||||
### Enable the experiment
|
||||
#### Enable the experiment
|
||||
|
||||
After all merge requests have been merged, use [`chatops`](../../ci/chatops/index.md) in the
|
||||
[appropriate channel](../feature_flags/controls.md#communicate-the-change) to start the experiment for 10% of the users.
|
||||
|
@ -340,7 +358,7 @@ For visibility, please also share any commands run against production in the `#s
|
|||
/chatops run feature delete signup_flow_experiment_percentage
|
||||
```
|
||||
|
||||
### Manually force the current user to be in the experiment group
|
||||
#### Manually force the current user to be in the experiment group
|
||||
|
||||
You may force the application to put your current user in the experiment group. To do so
|
||||
add a query string parameter to the path where the experiment runs. If you do so,
|
||||
|
@ -353,7 +371,7 @@ to the URL:
|
|||
https://gitlab.com/<EXPERIMENT_ENTRY_URL>?force_experiment=<EXPERIMENT_KEY>
|
||||
```
|
||||
|
||||
### A cookie-based approach to force an experiment
|
||||
#### A cookie-based approach to force an experiment
|
||||
|
||||
It's possible to force the current user to be in the experiment group for `<EXPERIMENT_KEY>`
|
||||
during the browser session by using your browser's developer tools:
|
||||
|
@ -374,9 +392,9 @@ To clear the experiments, unset the `force_experiment` cookie:
|
|||
document.cookie = "force_experiment=; path=/";
|
||||
```
|
||||
|
||||
### Testing and test helpers
|
||||
#### Testing and test helpers
|
||||
|
||||
#### RSpec
|
||||
##### RSpec
|
||||
|
||||
Use the following in RSpec to mock the experiment:
|
||||
|
||||
|
@ -404,7 +422,7 @@ context 'when the experiment is active' do
|
|||
end
|
||||
```
|
||||
|
||||
#### Jest
|
||||
##### Jest
|
||||
|
||||
Use the following in Jest to mock the experiment:
|
||||
|
||||
|
|
|
@ -161,7 +161,7 @@ unnecessary when using `gl-icon`.
|
|||
// good - decorative images hidden from screen readers
|
||||
<img src="decorative.jpg" alt="">
|
||||
<svg role="img" alt="">
|
||||
<gl-icon name="epic"/>
|
||||
<gl-icon name="epic"/>
|
||||
```
|
||||
|
||||
## When should ARIA be used
|
||||
|
@ -187,7 +187,7 @@ Use of ARIA would then only occur in [GitLab UI](https://gitlab.com/gitlab-org/g
|
|||
We have two options for Web accessibility testing:
|
||||
|
||||
- [axe](https://www.deque.com/axe/) for [Firefox](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/)
|
||||
- [axe](https://www.deque.com/axe/) for [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd)
|
||||
- [axe](https://www.deque.com/axe/) for [Chrome](https://chrome.google.com/webstore/detail/axe-devtools-web-accessib/lhdoppojpmngadmnindnejefpokejbdd)
|
||||
|
||||
### Other links
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ projects:
|
|||
- Avoid global variables, even in packages. By doing so you introduce side
|
||||
effects if the package is included multiple times.
|
||||
- Use `goimports` before committing.
|
||||
[`goimports`](https://godoc.org/golang.org/x/tools/cmd/goimports)
|
||||
[`goimports`](https://pkg.go.dev/golang.org/x/tools/cmd/goimports)
|
||||
is a tool that automatically formats Go source code using
|
||||
[`Gofmt`](https://golang.org/cmd/gofmt/), in addition to formatting import lines,
|
||||
adding missing ones and removing unreferenced ones.
|
||||
|
|
|
@ -22,9 +22,17 @@ You may create a new account or use any of their supported sign in services.
|
|||
|
||||
GitLab is being translated into many languages.
|
||||
|
||||
1. Select the language you would like to contribute translations to by clicking the flag
|
||||
1. Find the language that you want to contribute to, in our
|
||||
[GitLab Crowdin project](https://crowdin.com/project/gitlab-ee).
|
||||
- If the language that you're looking for is available, proceed
|
||||
to the next step.
|
||||
- If the language you are looking for is not available,
|
||||
[open an issue](https://gitlab.com/gitlab-org/gitlab/-/issues?scope=all&utf8=✓&state=all&label_name[]=Category%3AInternationalization). Notify our Crowdin
|
||||
administrators by including `@gitlab-org/manage/import` in your issue.
|
||||
in the issue.
|
||||
- After the issue/Merge Request is complete, restart this procedure.
|
||||
1. Next, you can view list of files and folders.
|
||||
Click `gitlab.pot` to open the translation editor.
|
||||
Select `gitlab.pot` to open the translation editor.
|
||||
|
||||
### Translation Editor
|
||||
|
||||
|
|
|
@ -151,7 +151,7 @@ To run the Monitor tests locally, against the GDK, please follow the preparation
|
|||
1. The test setup deploys the app in a Kubernetes cluster, using the Auto DevOps deployment strategy.
|
||||
To enable Auto DevOps in GDK, follow the [associated setup](https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/master/doc/howto/auto_devops/index.md#setup) instructions. If you have problems, review the [troubleshooting guide](https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/master/doc/howto/auto_devops/tips_and_troubleshooting.md) or reach out to the `#gdk` channel in the internal GitLab Slack.
|
||||
1. Do [secure your GitLab instance](https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/master/doc/howto/auto_devops/index.md#secure-your-gitlab-instance) since it is now publicly accessible on `https://[YOUR-PORT].qa-tunnel.gitlab.info`.
|
||||
1. Install the Kubernetes command line tool known as `kubectl`. Use the [official installation instructions](https://kubernetes.io/docs/tasks/tools/install-kubectl/).
|
||||
1. Install the Kubernetes command line tool known as `kubectl`. Use the [official installation instructions](https://kubernetes.io/docs/tasks/tools/).
|
||||
|
||||
You might see NGINX issues when you run `gdk start` or `gdk restart`. In that case, run `sft login` to revalidate your credentials and regain access the QA Tunnel.
|
||||
|
||||
|
|
|
@ -212,7 +212,7 @@ When it comes to querying DOM elements in your tests, it is best to uniquely and
|
|||
the element.
|
||||
|
||||
Preferentially, this is done by targeting what the user actually sees using [DOM Testing Library](https://testing-library.com/docs/dom-testing-library/intro/).
|
||||
When selecting by text it is best to use [`getByRole` or `findByRole`](https://testing-library.com/docs/queries/byrole)
|
||||
When selecting by text it is best to use [`getByRole` or `findByRole`](https://testing-library.com/docs/queries/byrole/)
|
||||
as these enforce accessibility best practices as well. The examples below demonstrate the order of preference.
|
||||
|
||||
When writing Vue component unit tests, it can be wise to query children by component, so that the unit test can focus on comprehensive value coverage
|
||||
|
|
|
@ -112,7 +112,7 @@ Review Apps are automatically stopped 2 days after the last deployment thanks to
|
|||
the [Environment auto-stop](../../ci/environments/index.md#stop-an-environment-after-a-certain-time-period) feature.
|
||||
|
||||
If you need your Review App to stay up for a longer time, you can
|
||||
[pin its environment](../../ci/environments/index.md#auto-stop-example) or retry the
|
||||
[pin its environment](../../ci/environments/index.md#override-a-deployments-scheduled-stop-time) or retry the
|
||||
`review-deploy` job to update the "latest deployed at" time.
|
||||
|
||||
The `review-cleanup` job that automatically runs in scheduled
|
||||
|
|
|
@ -351,7 +351,7 @@ Remember to sign in with the username and password you specified when you
|
|||
[created your Azure VM](#basics).
|
||||
|
||||
If you need to reset your VM password, read
|
||||
[how to reset SSH credentials for a user on an Azure VM](https://docs.microsoft.com/en-us/azure/virtual-machines/troubleshooting/troubleshoot-ssh-connection).
|
||||
[how to reset SSH credentials for a user on an Azure VM](https://docs.microsoft.com/en-us/troubleshoot/azure/virtual-machines/troubleshoot-ssh-connection).
|
||||
|
||||
#### SSH from the command-line
|
||||
|
||||
|
@ -433,7 +433,7 @@ Check out our other [Technical Articles](../../topics/index.md) or browse the [G
|
|||
- [Azure - Marketplace](https://azuremarketplace.microsoft.com/en-us/marketplace/)
|
||||
- [Azure Portal](https://portal.azure.com)
|
||||
- [Azure - Pricing Calculator](https://azure.microsoft.com/en-us/pricing/calculator/)
|
||||
- [Azure - Troubleshoot SSH Connections to an Azure Linux VM](https://docs.microsoft.com/en-us/azure/virtual-machines/troubleshooting/troubleshoot-ssh-connection)
|
||||
- [Azure - Troubleshoot SSH Connections to an Azure Linux VM](https://docs.microsoft.com/en-us/troubleshoot/azure/virtual-machines/troubleshoot-ssh-connection)
|
||||
- [Azure - Properly Shutdown an Azure VM](https://build5nines.com/properly-shutdown-azure-vm-to-save-money/)
|
||||
- [SSH](https://en.wikipedia.org/wiki/Secure_Shell), [PuTTY](https://www.putty.org) and [Using SSH in PuTTY](https://mediatemple.net/community/products/dv/204404604/using-ssh-in-putty-)
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ already, go ahead and install the following components as they are essential to
|
|||
test OpenShift easily:
|
||||
|
||||
- [VirtualBox](https://www.virtualbox.org/wiki/Downloads)
|
||||
- [Vagrant](https://www.vagrantup.com/downloads.html)
|
||||
- [Vagrant](https://www.vagrantup.com/downloads)
|
||||
- [OpenShift Client](https://docs.okd.io/3.11/cli_reference/get_started_cli.html) (`oc` for short)
|
||||
|
||||
It is also important to mention that for the purposes of this tutorial, the
|
||||
|
|
|
@ -79,8 +79,8 @@ is 200. For GitLab SaaS, the maximum number is determined by [tier](https://abou
|
|||
You can apply a feature flag strategy across multiple environments, without defining
|
||||
the strategy multiple times.
|
||||
|
||||
GitLab Feature Flags use [Unleash](https://docs.getunleash.ai/) as the feature flag
|
||||
engine. In Unleash, there are [strategies](https://docs.getunleash.ai/docs/activation_strategy)
|
||||
GitLab Feature Flags use [Unleash](https://docs.getunleash.io/) as the feature flag
|
||||
engine. In Unleash, there are [strategies](https://docs.getunleash.io/docs/activation_strategy)
|
||||
for granular feature flag controls. GitLab Feature Flags can have multiple strategies,
|
||||
and the supported strategies are:
|
||||
|
||||
|
@ -95,7 +95,7 @@ and clicking **{pencil}** (edit).
|
|||
|
||||
### All users
|
||||
|
||||
Enables the feature for all users. It uses the [`default`](https://docs.getunleash.ai/docs/activation_strategy#default)
|
||||
Enables the feature for all users. It uses the [`default`](https://docs.getunleash.io/docs/activation_strategy#default)
|
||||
Unleash activation strategy.
|
||||
|
||||
### Percent Rollout
|
||||
|
|
|
@ -24,6 +24,7 @@ type: index
|
|||
- [Security of running jobs](https://docs.gitlab.com/runner/security/)
|
||||
- [Proxying images](asset_proxy.md)
|
||||
- [CI/CD variables](cicd_variables.md)
|
||||
- [Token overview](token_overview.md)
|
||||
|
||||
## Securing your GitLab installation
|
||||
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
---
|
||||
stage: Manage
|
||||
group: Access
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
|
||||
type: reference
|
||||
---
|
||||
|
||||
# GitLab Token overview
|
||||
|
||||
This document lists tokens used in GitLab, their purpose and, where applicable, security guidance.
|
||||
|
||||
## Personal access tokens
|
||||
|
||||
You can create [Personal access tokens](../user/profile/personal_access_tokens.md) to authenticate with:
|
||||
|
||||
- The GitLab API.
|
||||
- GitLab repositories.
|
||||
- The GitLab registry.
|
||||
|
||||
You can limit the scope and expiration date of your personal access tokens. By default,
|
||||
they inherit permissions from the user who created them.
|
||||
|
||||
## OAuth2 tokens
|
||||
|
||||
GitLab can serve as an [OAuth2 provider](../api/oauth2.md) to allow other services to access the GitLab API on a user’s behalf.
|
||||
|
||||
You can limit the scope and lifetime of your OAuth2 tokens.
|
||||
|
||||
## Impersonation tokens
|
||||
|
||||
An [Impersonation token](../api/README.md#impersonation-tokens) is a special type of personal access
|
||||
token. It can be created only by an administrator for a specific user. Impersonation tokens can
|
||||
help you build applications or scripts that authenticate with the GitLab API, repositories, and the GitLab registry as a specific user.
|
||||
|
||||
You can limit the scope and set an expiration date for an impersonation token.
|
||||
|
||||
## Project access tokens
|
||||
|
||||
[Project access tokens](../user/project/settings/project_access_tokens.md#project-access-tokens)
|
||||
are scoped to a project. As with [Personal access tokens](#personal-access-tokens), you can use them to authenticate with:
|
||||
|
||||
- The GitLab API.
|
||||
- GitLab repositories.
|
||||
- The GitLab registry.
|
||||
|
||||
You can limit the scope and expiration date of project access tokens. When you
|
||||
create a project access token, GitLab creates a [project bot user](../user/project/settings/project_access_tokens.md#project-bot-users). Project
|
||||
bot users are service accounts and do not count as licensed seats.
|
||||
|
||||
## Deploy tokens
|
||||
|
||||
[Deploy tokens](../user/project/deploy_tokens/index.md) allow you to download (`git clone`) or push and pull packages and container registry images of a project without having a user and a password. Deploy tokens cannot be used with the GitLab API.
|
||||
|
||||
Deploy tokens can be managed by project maintainers and owners.
|
||||
|
||||
## Deploy keys
|
||||
|
||||
[Deploy keys](../user/project/deploy_keys/index.md) allow read-only or read-write access to your repositories by importing an SSH public key into your GitLab instance. Deploy keys cannot be used with the GitLab API or the registry.
|
||||
|
||||
This is useful, for example, for cloning repositories to your Continuous Integration (CI) server. By using deploy keys, you don’t have to set up a fake user account.
|
||||
|
||||
Project maintainers and owners can add or enable a deploy key for a project repository
|
||||
|
||||
## Runner registration tokens
|
||||
|
||||
Runner registration tokens are used to [register](https://docs.gitlab.com/runner/register/) a [runner](https://docs.gitlab.com/runner/) with GitLab. Group or project owners or instance admins can obtain them through the GitLab user interface. The registration token is limited to runner registration and has no further scope.
|
||||
|
||||
You can use the runner registration token to add runners that execute jobs in a project or group. The runner has access to the project’s code, so be careful when assigning project and group-level permissions.
|
||||
|
||||
## Runner authentication tokens (also called runner tokens)
|
||||
|
||||
After registration, the runner receives an authentication token, which it uses to authenticate with GitLab when picking up jobs from the job queue. The authentication token is stored locally in the runner's [`config.toml`](https://docs.gitlab.com/runner/configuration/advanced-configuration.html) file.
|
||||
|
||||
After authentication with GitLab, the runner receives a [job token](../user/project/new_ci_build_permissions_model.md#job-token), which it uses to execute the job.
|
||||
|
||||
In case of Docker Machine/Kubernetes/VirtualBox/Parallels/SSH executors, the execution environment has no access to the runner authentication token, because it stays on the runner machine. They have access to the job token only, which is needed to execute the job.
|
||||
|
||||
Malicious access to a runner's file system may expose the `config.toml` file and thus the authentication token, allowing an attacker to [clone the runner](https://docs.gitlab.com/runner/security/#cloning-a-runner).
|
||||
|
||||
## CI/CD job tokens
|
||||
|
||||
The [CI/CD](../api/README.md#gitlab-ci-job-token) job token
|
||||
is a short lived token only valid for the duration of a job. It gives a CI/CD job
|
||||
access to a limited amount of [API endpoints](../api/README.md#gitlab-ci-job-token).
|
||||
API authentication uses the job token, by using the authorization of the user
|
||||
triggering the job.
|
||||
|
||||
The job token is secured by its short life-time and limited scope. It could possibly be leaked if multiple jobs run on the same machine ([like with the shell runner](https://docs.gitlab.com/runner/security/#usage-of-shell-executor)). On Docker Machine runners, configuring [`MaxBuilds=1`](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runnersmachine-section) is recommended to make sure runner machines only ever run one build and are destroyed afterwards. This may impact performance, as provisioning machines takes some time.
|
||||
|
||||
## Available scopes
|
||||
|
||||
This table shows available scopes per token. Scopes can be limited further on token creation.
|
||||
|
||||
| | API access | Registry access | Repository access |
|
||||
|-----------------------------|------------|-----------------|-------------------|
|
||||
| Personal access token | ✅ | ✅ | ✅ |
|
||||
| OAuth2 token | ✅ | 🚫 | ✅ |
|
||||
| Impersonation token | ✅ | ✅ | ✅ |
|
||||
| Project access token | ✅(1) | ✅(1) | ✅(1) |
|
||||
| Deploy token | 🚫 | ✅ | ✅ |
|
||||
| Deploy key | 🚫 | 🚫 | ✅ |
|
||||
| Runner registration token | 🚫 | 🚫 | ✴️(2) |
|
||||
| Runner authentication token | 🚫 | 🚫 | ✴️(2) |
|
||||
| Job token | ✴️(3) | 🚫 | ✅ |
|
||||
|
||||
1. Limited to the one project.
|
||||
1. Runner registration and authentication token don't provide direct access to repositories, but can be used to register and authenticate a new runner that may execute jobs which do have access to the repository
|
||||
1. Limited to certain [endpoints](../api/README.md#gitlab-ci-job-token).
|
|
@ -321,7 +321,7 @@ simplify configuration and prevent any unforeseen issues.
|
|||
The GitLab integration with Helm does not support installing applications when
|
||||
behind a proxy. Users who want to do so must inject their proxy settings
|
||||
into the installation pods at runtime, such as by using a
|
||||
[`PodPreset`](https://kubernetes.io/docs/concepts/workloads/pods/podpreset/):
|
||||
[`PodPreset`](https://v1-19.docs.kubernetes.io/docs/concepts/workloads/pods/podpreset/):
|
||||
|
||||
```yaml
|
||||
apiVersion: settings.k8s.io/v1alpha1
|
||||
|
|
|
@ -635,7 +635,7 @@ ciliumNetworkPolicy:
|
|||
#### Enabling Alerts
|
||||
|
||||
You can also enable alerts. Network policies with alerts are considered only if
|
||||
[GitLab Kubernetes Agent](https://docs.gitlab.com/13.6/ee/user/clusters/agent/)
|
||||
[GitLab Kubernetes Agent](../../user/clusters/agent/index.md)
|
||||
has been integrated.
|
||||
|
||||
You can enable alerts as follows:
|
||||
|
|
|
@ -27,7 +27,7 @@ involves:
|
|||
## Prerequisites
|
||||
|
||||
1. Install
|
||||
[`kubectl`](https://kubernetes.io/docs/tasks/tools/install-kubectl/).
|
||||
[`kubectl`](https://kubernetes.io/docs/tasks/tools/).
|
||||
1. Ensure that you can access your Kubernetes cluster using `kubectl`.
|
||||
This varies based on Kubernetes providers.
|
||||
1. Prepare for downtime. The steps below include taking the application offline
|
||||
|
|
|
@ -510,7 +510,7 @@ ensure that it can reach your private repository. Here is an example configurati
|
|||
### Referencing local dependencies using a path in JavaScript projects
|
||||
|
||||
The [Retire.js](https://gitlab.com/gitlab-org/security-products/analyzers/retire.js) analyzer
|
||||
doesn't support dependency references made with [local paths](https://docs.npmjs.com/cli/v6/configuring-npm/package-json#local-paths)
|
||||
doesn't support dependency references made with [local paths](https://docs.npmjs.com/cli/v6/configuring-npm/package-json/#local-paths)
|
||||
in the `package.json` of JavaScript projects. The dependency scan outputs the following error for
|
||||
such references:
|
||||
|
||||
|
|
|
@ -93,11 +93,9 @@ The available `agentk` and `kas` versions can be found in
|
|||
|
||||
### Install the Kubernetes Agent Server
|
||||
|
||||
The GitLab Kubernetes Agent Server (KAS) can be deployed using [Omnibus
|
||||
GitLab](https://docs.gitlab.com/omnibus/) or the [GitLab
|
||||
chart](https://gitlab.com/gitlab-org/charts/gitlab). If you don't already have
|
||||
GitLab installed, please refer to our [installation
|
||||
documentation](https://docs.gitlab.com/ee/install/README.html).
|
||||
The GitLab Kubernetes Agent Server (KAS) can be deployed using [Omnibus GitLab](https://docs.gitlab.com/omnibus/) or the
|
||||
[GitLab chart](https://gitlab.com/gitlab-org/charts/gitlab). If you don't already have
|
||||
GitLab installed, please refer to our [installation documentation](../../../install/index.md).
|
||||
|
||||
NOTE:
|
||||
GitLab plans to include the KAS on [GitLab.com](https://gitlab.com/groups/gitlab-org/-/epics/3834).
|
||||
|
@ -469,7 +467,7 @@ The following example projects can help you get started with the Kubernetes Agen
|
|||
### Deploying GitLab Runner with the Agent
|
||||
|
||||
You can use the Kubernetes Agent to
|
||||
[deploy GitLab Runner in a Kubernetes cluster](http://docs.gitlab.com/runner/install/kubernetes-agent.html).
|
||||
[deploy GitLab Runner in a Kubernetes cluster](https://docs.gitlab.com/runner/install/kubernetes-agent.html).
|
||||
|
||||
## Kubernetes Network Security Alerts
|
||||
|
||||
|
|
|
@ -86,10 +86,9 @@ is saved as a [CI job artifact](../../ci/pipelines/job_artifacts.md).
|
|||
|
||||
#### Usage in GitLab versions earlier than 13.5
|
||||
|
||||
For GitLab versions 13.5 and below, the Ingress, Fluentd, Prometheus,
|
||||
and Sentry apps are fetched from the central Helm
|
||||
[stable repository](https://kubernetes-charts.storage.googleapis.com/). This repository
|
||||
[was deleted](https://github.com/helm/charts#deprecation-timeline)
|
||||
For GitLab versions 13.5 and earlier, the Ingress, Fluentd, Prometheus, and Sentry
|
||||
apps were fetched from the central Helm stable repository (`https://kubernetes-charts.storage.googleapis.com/`).
|
||||
This repository [was deleted](https://github.com/helm/charts#deprecation-timeline)
|
||||
on November 13, 2020. This causes the installation CI/CD pipeline to
|
||||
fail. Upgrade to GitLab 13.6, or alternatively, you can
|
||||
use the following `.gitlab-ci.yml`, which has been tested on GitLab 13.5:
|
||||
|
|
|
@ -79,7 +79,7 @@ The reported licenses might be incomplete or inaccurate.
|
|||
| Elixir | [Mix](https://elixir-lang.org/getting-started/mix-otp/introduction-to-mix.html) |
|
||||
| C++/C | [Conan](https://conan.io/) |
|
||||
| Scala | [sbt](https://www.scala-sbt.org/) |
|
||||
| Rust | [Cargo](https://crates.io/) |
|
||||
| Rust | [Cargo](https://crates.io) |
|
||||
| PHP | [Composer](https://getcomposer.org/) |
|
||||
|
||||
## Requirements
|
||||
|
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 12 KiB |
|
@ -187,7 +187,7 @@ For more information, see our [discussion on providers](#providers).
|
|||
Your identity provider may have relevant documentation. It may be generic SAML documentation, or specifically targeted for GitLab. Examples:
|
||||
|
||||
- [ADFS (Active Directory Federation Services)](https://docs.microsoft.com/en-us/windows-server/identity/ad-fs/operations/create-a-relying-party-trust)
|
||||
- [Auth0](https://auth0.com/docs/protocols/saml-configuration-options/configure-auth0-as-saml-identity-provider)
|
||||
- [Auth0](https://auth0.com/docs/protocols/saml-protocol/configure-auth0-as-saml-identity-provider)
|
||||
- [Google Workspace](https://support.google.com/a/answer/6087519?hl=en)
|
||||
- [JumpCloud](https://support.jumpcloud.com/support/s/article/single-sign-on-sso-with-gitlab-2019-08-21-10-36-47)
|
||||
- [PingOne by Ping Identity](https://docs.pingidentity.com/bundle/pingone/page/xsh1564020480660-1.html)
|
||||
|
|
|
@ -161,7 +161,7 @@ have FortiToken configured in FortiToken Cloud.
|
|||
|
||||
You'll also need a `client_id` and `client_secret` to configure FortiToken Cloud.
|
||||
To get these, see the `REST API Guide` at
|
||||
[`Fortinet Document Library`](https://docs.fortinet.com/document/fortitoken-cloud/20.4.d/rest-api).
|
||||
[`Fortinet Document Library`](https://docs.fortinet.com/document/fortitoken-cloud/latest/rest-api).
|
||||
|
||||
First configure FortiToken Cloud in GitLab. On your GitLab server:
|
||||
|
||||
|
|
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 100 KiB After Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 77 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 26 KiB |