Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
31f59b55c6
commit
a6b21afb09
|
|
@ -72,8 +72,6 @@ Performance/RegexpMatch:
|
|||
- 'qa/qa/service/cluster_provider/k3d.rb'
|
||||
- 'qa/qa/specs/spec_helper.rb'
|
||||
- 'qa/qa/tools/ci/ff_changes.rb'
|
||||
- 'rubocop/cop/project_path_helper.rb'
|
||||
- 'rubocop/cop/qa/selector_usage.rb'
|
||||
- 'scripts/changed-feature-flags'
|
||||
- 'scripts/failed_tests.rb'
|
||||
- 'scripts/lib/glfm/parse_examples.rb'
|
||||
|
|
@ -83,14 +81,3 @@ Performance/RegexpMatch:
|
|||
- 'scripts/qa/testcases-check'
|
||||
- 'scripts/trigger-build.rb'
|
||||
- 'sidekiq_cluster/cli.rb'
|
||||
- 'spec/lib/gitlab/cluster/mixins/puma_cluster_spec.rb'
|
||||
- 'spec/mailers/emails/in_product_marketing_spec.rb'
|
||||
- 'spec/spec_helper.rb'
|
||||
- 'spec/support/capybara.rb'
|
||||
- 'spec/support/helpers/test_env.rb'
|
||||
- 'spec/support/shared_contexts/features/integrations/integrations_shared_context.rb'
|
||||
- 'spec/support/shared_examples/features/discussion_comments_shared_example.rb'
|
||||
- 'spec/tooling/quality/test_level_spec.rb'
|
||||
- 'tooling/danger/analytics_instrumentation.rb'
|
||||
- 'tooling/danger/database_dictionary.rb'
|
||||
- 'tooling/danger/specs/feature_category_suggestion.rb'
|
||||
|
|
|
|||
|
|
@ -18,10 +18,10 @@ const axiosGet = (url, query, options, callback) => {
|
|||
...options,
|
||||
},
|
||||
})
|
||||
.then(({ data }) => {
|
||||
.then(({ data, headers }) => {
|
||||
callback(data);
|
||||
|
||||
return data;
|
||||
return { data, headers };
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ export default {
|
|||
});
|
||||
},
|
||||
[types.RECEIVE_SEARCHED_ITEMS_SUCCESS](state, results) {
|
||||
const rawItems = results.data ? results.data : results; // Api.groups returns array, Api.projects returns object
|
||||
const rawItems = results.data;
|
||||
Object.assign(state, {
|
||||
items: rawItems.map((rawItem) => ({
|
||||
id: rawItem.id,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { GlAvatarLabeled, GlCollapsibleListbox } from '@gitlab/ui';
|
|||
import { debounce } from 'lodash';
|
||||
import { s__ } from '~/locale';
|
||||
import { getGroups, getDescendentGroups } from '~/rest_api';
|
||||
import { normalizeHeaders, parseIntPagination } from '~/lib/utils/common_utils';
|
||||
import { SEARCH_DELAY, GROUP_FILTERS } from '../constants';
|
||||
|
||||
export default {
|
||||
|
|
@ -39,6 +40,8 @@ export default {
|
|||
isFetching: false,
|
||||
groups: [],
|
||||
searchTerm: '',
|
||||
pagination: {},
|
||||
infiniteScrollLoading: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -48,24 +51,29 @@ export default {
|
|||
isFetchResultEmpty() {
|
||||
return this.groups.length === 0;
|
||||
},
|
||||
infiniteScroll() {
|
||||
return Boolean(this.pagination.nextPage);
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.retrieveGroups();
|
||||
},
|
||||
methods: {
|
||||
retrieveGroups: debounce(function debouncedRetrieveGroups() {
|
||||
retrieveGroups: debounce(async function debouncedRetrieveGroups() {
|
||||
this.isFetching = true;
|
||||
return this.fetchGroups()
|
||||
.then((response) => {
|
||||
this.groups = this.processGroups(response);
|
||||
this.isFetching = false;
|
||||
})
|
||||
.catch(() => {
|
||||
this.isFetching = false;
|
||||
});
|
||||
|
||||
try {
|
||||
const response = await this.fetchGroups();
|
||||
this.pagination = this.processPagination(response);
|
||||
this.groups = this.processGroups(response);
|
||||
} catch {
|
||||
this.onApiError();
|
||||
} finally {
|
||||
this.isFetching = false;
|
||||
}
|
||||
}, SEARCH_DELAY),
|
||||
processGroups(response) {
|
||||
const rawGroups = response.map((group) => ({
|
||||
processGroups({ data }) {
|
||||
const rawGroups = data.map((group) => ({
|
||||
// `value` is needed for `GlCollapsibleListbox`
|
||||
value: group.id,
|
||||
id: group.id,
|
||||
|
|
@ -76,6 +84,9 @@ export default {
|
|||
|
||||
return this.filterOutInvalidGroups(rawGroups);
|
||||
},
|
||||
processPagination({ headers }) {
|
||||
return parseIntPagination(normalizeHeaders(headers));
|
||||
},
|
||||
filterOutInvalidGroups(groups) {
|
||||
return groups.filter((group) => this.invalidGroups.indexOf(group.id) === -1);
|
||||
},
|
||||
|
|
@ -86,23 +97,43 @@ export default {
|
|||
this.searchTerm = searchTerm;
|
||||
this.retrieveGroups();
|
||||
},
|
||||
fetchGroups() {
|
||||
fetchGroups(options = {}) {
|
||||
const combinedOptions = {
|
||||
...this.$options.defaultFetchOptions,
|
||||
...options,
|
||||
};
|
||||
|
||||
switch (this.groupsFilter) {
|
||||
case GROUP_FILTERS.DESCENDANT_GROUPS:
|
||||
return getDescendentGroups(
|
||||
this.parentGroupId,
|
||||
this.searchTerm,
|
||||
this.$options.defaultFetchOptions,
|
||||
);
|
||||
return getDescendentGroups(this.parentGroupId, this.searchTerm, combinedOptions);
|
||||
default:
|
||||
return getGroups(this.searchTerm, this.$options.defaultFetchOptions);
|
||||
return getGroups(this.searchTerm, combinedOptions);
|
||||
}
|
||||
},
|
||||
async onBottomReached() {
|
||||
this.infiniteScrollLoading = true;
|
||||
|
||||
try {
|
||||
const response = await this.fetchGroups({ page: this.pagination.page + 1 });
|
||||
this.pagination = this.processPagination(response);
|
||||
this.groups.push(...this.processGroups(response));
|
||||
} catch {
|
||||
this.onApiError();
|
||||
} finally {
|
||||
this.infiniteScrollLoading = false;
|
||||
}
|
||||
},
|
||||
onApiError() {
|
||||
this.$emit('error', this.$options.i18n.errorMessage);
|
||||
},
|
||||
},
|
||||
i18n: {
|
||||
dropdownText: s__('GroupSelect|Select a group'),
|
||||
searchPlaceholder: s__('GroupSelect|Search groups'),
|
||||
emptySearchResult: s__('GroupSelect|No matching results'),
|
||||
errorMessage: s__(
|
||||
'GroupSelect|An error occurred fetching the groups. Please refresh the page to try again.',
|
||||
),
|
||||
},
|
||||
defaultFetchOptions: {
|
||||
exclude_internal: true,
|
||||
|
|
@ -125,6 +156,10 @@ export default {
|
|||
is-check-centered
|
||||
:searching="isFetching"
|
||||
:no-results-text="$options.i18n.emptySearchResult"
|
||||
:infinite-scroll="infiniteScroll"
|
||||
:infinite-scroll-loading="infiniteScrollLoading"
|
||||
:total-items="pagination.total"
|
||||
@bottom-reached="onBottomReached"
|
||||
@select="onSelect"
|
||||
@search="onSearch"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
<script>
|
||||
import * as Sentry from '@sentry/browser';
|
||||
import { GlAlert } from '@gitlab/ui';
|
||||
import { uniqueId } from 'lodash';
|
||||
import Api from '~/api';
|
||||
import { BV_SHOW_MODAL, BV_HIDE_MODAL } from '~/lib/utils/constants';
|
||||
|
|
@ -19,6 +21,7 @@ export default {
|
|||
GroupSelect,
|
||||
InviteModalBase,
|
||||
InviteGroupNotification,
|
||||
GlAlert,
|
||||
},
|
||||
props: {
|
||||
id: {
|
||||
|
|
@ -83,6 +86,7 @@ export default {
|
|||
isLoading: false,
|
||||
modalId: uniqueId('invite-groups-modal-'),
|
||||
groupToBeSharedWith: {},
|
||||
groupSelectError: '',
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -165,6 +169,10 @@ export default {
|
|||
clearValidation() {
|
||||
this.invalidFeedbackMessage = '';
|
||||
},
|
||||
onGroupSelectError(error) {
|
||||
this.groupSelectError = error;
|
||||
Sentry.captureException(error);
|
||||
},
|
||||
},
|
||||
labels: GROUP_MODAL_LABELS,
|
||||
};
|
||||
|
|
@ -197,6 +205,9 @@ export default {
|
|||
:notification-link="$options.labels[inviteTo].notificationLink"
|
||||
class="gl-mb-5"
|
||||
/>
|
||||
<gl-alert v-if="groupSelectError" class="gl-mb-5" variant="danger" :dismissible="false">{{
|
||||
groupSelectError
|
||||
}}</gl-alert>
|
||||
</template>
|
||||
|
||||
<template #select>
|
||||
|
|
@ -206,6 +217,7 @@ export default {
|
|||
:parent-group-id="groupSelectParentId"
|
||||
:invalid-groups="invalidGroups"
|
||||
@input="clearValidation"
|
||||
@error="onGroupSelectError"
|
||||
/>
|
||||
</template>
|
||||
</invite-modal-base>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
<script>
|
||||
import { GlAlert } from '@gitlab/ui';
|
||||
import ConvertDescriptionModal from 'ee_component/issues/show/components/convert_description_modal.vue';
|
||||
import { getDraft, updateDraft, getLockVersion, clearDraft } from '~/lib/utils/autosave';
|
||||
import { convertToGraphQLId } from '~/graphql_shared/utils';
|
||||
import { TYPENAME_ISSUE, TYPENAME_USER } from '~/graphql_shared/constants';
|
||||
|
|
@ -16,7 +15,6 @@ import LockedWarning from './locked_warning.vue';
|
|||
|
||||
export default {
|
||||
components: {
|
||||
ConvertDescriptionModal,
|
||||
DescriptionField,
|
||||
DescriptionTemplateField,
|
||||
EditActions,
|
||||
|
|
@ -175,9 +173,6 @@ export default {
|
|||
updateDraft(this.descriptionAutosaveKey, description, this.formState.lock_version);
|
||||
}
|
||||
},
|
||||
setDescription(desc) {
|
||||
this.formData.description = desc;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -219,14 +214,6 @@ export default {
|
|||
:project-namespace="projectNamespace"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<convert-description-modal
|
||||
v-if="issueId && glFeatures.generateDescriptionAi"
|
||||
class="gl-pl-5 gl-md-pl-0"
|
||||
:resource-id="resourceId"
|
||||
:user-id="userId"
|
||||
@contentGenerated="setDescription"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<description-field
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { initForm } from 'ee_else_ce/issues';
|
||||
import { mountMarkdownEditor } from '~/vue_shared/components/markdown/mount_markdown_editor';
|
||||
import { mountMarkdownEditor } from 'ee_else_ce/vue_shared/components/markdown/mount_markdown_editor';
|
||||
import IssuableTemplateSelectors from '~/issuable/issuable_template_selectors';
|
||||
|
||||
initForm();
|
||||
|
|
|
|||
|
|
@ -49,6 +49,9 @@ export default {
|
|||
iconName() {
|
||||
return this.isExpanded ? 'chevron-down' : 'chevron-right';
|
||||
},
|
||||
popoverId() {
|
||||
return `popover-${this.pipelineIid}`;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
failedJobsCount(val) {
|
||||
|
|
@ -77,8 +80,8 @@ export default {
|
|||
<gl-button variant="link" @click="toggleWidget">
|
||||
<gl-icon :name="iconName" />
|
||||
{{ failedJobsCountText }}
|
||||
<gl-icon id="target" name="information-o" />
|
||||
<gl-popover target="target" placement="top">
|
||||
<gl-icon :id="popoverId" name="information-o" />
|
||||
<gl-popover :target="popoverId" placement="top">
|
||||
<template #title> {{ $options.i18n.additionalInfoTitle }} </template>
|
||||
<slot>
|
||||
<gl-sprintf :message="$options.i18n.additionalInfoPopover">
|
||||
|
|
|
|||
|
|
@ -1,10 +1,5 @@
|
|||
<script>
|
||||
import {
|
||||
GlDropdown,
|
||||
GlDropdownItem,
|
||||
GlDropdownSectionHeader,
|
||||
GlTooltipDirective,
|
||||
} from '@gitlab/ui';
|
||||
import { GlDisclosureDropdown, GlTooltipDirective } from '@gitlab/ui';
|
||||
import { __ } from '~/locale';
|
||||
|
||||
export const i18n = {
|
||||
|
|
@ -18,9 +13,7 @@ export default {
|
|||
GlTooltip: GlTooltipDirective,
|
||||
},
|
||||
components: {
|
||||
GlDropdown,
|
||||
GlDropdownItem,
|
||||
GlDropdownSectionHeader,
|
||||
GlDisclosureDropdown,
|
||||
},
|
||||
inject: {
|
||||
artifactsEndpoint: {
|
||||
|
|
@ -42,6 +35,21 @@ export default {
|
|||
},
|
||||
},
|
||||
computed: {
|
||||
items() {
|
||||
return [
|
||||
{
|
||||
name: this.$options.i18n.artifactSectionHeader,
|
||||
items: this.artifacts.map(({ name, path }) => ({
|
||||
text: name,
|
||||
href: path,
|
||||
extraAttrs: {
|
||||
download: '',
|
||||
rel: 'nofollow',
|
||||
},
|
||||
})),
|
||||
},
|
||||
];
|
||||
},
|
||||
shouldShowDropdown() {
|
||||
return this.artifacts?.length;
|
||||
},
|
||||
|
|
@ -49,31 +57,16 @@ export default {
|
|||
};
|
||||
</script>
|
||||
<template>
|
||||
<gl-dropdown
|
||||
<gl-disclosure-dropdown
|
||||
v-if="shouldShowDropdown"
|
||||
v-gl-tooltip
|
||||
class="build-artifacts js-pipeline-dropdown-download"
|
||||
:title="$options.i18n.artifacts"
|
||||
:text="$options.i18n.artifacts"
|
||||
:toggle-text="$options.i18n.artifacts"
|
||||
:aria-label="$options.i18n.artifacts"
|
||||
icon="download"
|
||||
right
|
||||
lazy
|
||||
placement="right"
|
||||
text-sr-only
|
||||
>
|
||||
<gl-dropdown-section-header>{{
|
||||
$options.i18n.artifactSectionHeader
|
||||
}}</gl-dropdown-section-header>
|
||||
|
||||
<gl-dropdown-item
|
||||
v-for="(artifact, i) in artifacts"
|
||||
:key="i"
|
||||
:href="artifact.path"
|
||||
rel="nofollow"
|
||||
download
|
||||
class="gl-word-break-word"
|
||||
>
|
||||
{{ artifact.name }}
|
||||
</gl-dropdown-item>
|
||||
</gl-dropdown>
|
||||
:items="items"
|
||||
/>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ export default {
|
|||
:label-for="$options.labelId"
|
||||
label-cols="3"
|
||||
label-cols-lg="2"
|
||||
label-class="gl-pb-0! gl-overflow-wrap-break"
|
||||
label-class="gl-pb-0! gl-overflow-wrap-break work-item-field-label"
|
||||
class="gl-align-items-center"
|
||||
>
|
||||
<gl-form-select
|
||||
|
|
@ -63,7 +63,7 @@ export default {
|
|||
:options="$options.states"
|
||||
:disabled="disabled"
|
||||
data-testid="work-item-state-select"
|
||||
class="gl-w-auto hide-select-decoration gl-pl-4 gl-my-1"
|
||||
class="gl-w-auto hide-select-decoration gl-pl-4 gl-my-1 work-item-field-value"
|
||||
:class="{ 'gl-bg-transparent! gl-cursor-text!': disabled }"
|
||||
@change="setState"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ export default {
|
|||
:note-id="noteId"
|
||||
:is-system-note="true"
|
||||
>
|
||||
<span ref="gfm-content" v-safe-html="actionTextHtml"></span>
|
||||
<span ref="gfm-content" v-safe-html="actionTextHtml" class="gl-word-break-word"></span>
|
||||
<template v-if="canSeeDescriptionVersion" #extra-controls>
|
||||
·
|
||||
<gl-button
|
||||
|
|
|
|||
|
|
@ -303,7 +303,7 @@ export default {
|
|||
<div class="form-row gl-mb-5 work-item-assignees gl-relative gl-flex-nowrap">
|
||||
<span
|
||||
:id="assigneesTitleId"
|
||||
class="gl-font-weight-bold gl-mt-2 col-lg-2 col-3 gl-pt-2 min-w-fit-content gl-overflow-wrap-break"
|
||||
class="gl-font-weight-bold gl-mt-2 col-lg-2 col-3 gl-pt-2 min-w-fit-content gl-overflow-wrap-break work-item-field-label"
|
||||
data-testid="assignees-title"
|
||||
>{{ assigneeText }}</span
|
||||
>
|
||||
|
|
@ -313,11 +313,12 @@ export default {
|
|||
:selected-tokens="localAssignees"
|
||||
:container-class="containerClass"
|
||||
:class="{ 'gl-hover-border-gray-200': canUpdate }"
|
||||
menu-class="token-selector-menu-class"
|
||||
:dropdown-items="dropdownItems"
|
||||
:loading="isLoadingUsers && !isLoadingMore"
|
||||
:view-only="!canUpdate"
|
||||
:allow-clear-all="isEditing"
|
||||
class="assignees-selector gl-flex-grow-1 gl-border gl-border-white gl-rounded-base col-9 gl-align-self-start gl-px-0! gl-mx-2"
|
||||
class="assignees-selector gl-flex-grow-1 gl-border gl-border-white gl-rounded-base col-9 gl-align-self-start gl-px-0! gl-mx-2 work-item-field-value"
|
||||
data-testid="work-item-assignees-input"
|
||||
@input="handleAssigneesInput"
|
||||
@text-input="debouncedSearchKeyUpdate"
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<section>
|
||||
<div class="work-item-attributes-wrapper">
|
||||
<work-item-state
|
||||
:work-item="workItem"
|
||||
:work-item-parent-id="workItemParentId"
|
||||
|
|
@ -176,5 +176,5 @@ export default {
|
|||
:work-item-type="workItemType"
|
||||
@error="$emit('error', $event)"
|
||||
/>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="gl-mb-5 gl-border-t gl-pt-5">
|
||||
<div class="gl-mb-5">
|
||||
<div class="gl-display-inline-flex gl-align-items-center gl-mb-3">
|
||||
<label class="d-block col-form-label gl-mr-5">{{ __('Description') }}</label>
|
||||
<gl-button
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import {
|
|||
GlButton,
|
||||
GlTooltipDirective,
|
||||
GlEmptyState,
|
||||
GlIntersectionObserver,
|
||||
} from '@gitlab/ui';
|
||||
import noAccessSvg from '@gitlab/svgs/dist/illustrations/analytics/no-access.svg?raw';
|
||||
import { s__ } from '~/locale';
|
||||
|
|
@ -75,6 +76,7 @@ export default {
|
|||
WorkItemNotes,
|
||||
WorkItemDetailModal,
|
||||
AbuseCategorySelector,
|
||||
GlIntersectionObserver,
|
||||
},
|
||||
mixins: [glFeatureFlagMixin()],
|
||||
inject: ['fullPath', 'reportAbusePath'],
|
||||
|
|
@ -106,6 +108,7 @@ export default {
|
|||
isReportDrawerOpen: false,
|
||||
reportedUrl: '',
|
||||
reportedUserId: 0,
|
||||
isStickyHeaderShowing: false,
|
||||
};
|
||||
},
|
||||
apollo: {
|
||||
|
|
@ -253,6 +256,9 @@ export default {
|
|||
'gl-pt-5': !this.updateError && !this.isModal,
|
||||
};
|
||||
},
|
||||
showIntersectionObserver() {
|
||||
return !this.isModal && this.workItemsMvc2Enabled;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
if (this.modalWorkItemIid) {
|
||||
|
|
@ -358,6 +364,15 @@ export default {
|
|||
this.reportedUrl = reply.url || {};
|
||||
this.reportedUserId = reply.author ? getIdFromGraphQLId(reply.author.id) : 0;
|
||||
},
|
||||
hideStickyHeader() {
|
||||
this.isStickyHeaderShowing = false;
|
||||
},
|
||||
showStickyHeader() {
|
||||
// only if scrolled under the work item's title
|
||||
if (this.$refs?.title?.$el.offsetTop < window.pageYOffset) {
|
||||
this.isStickyHeaderShowing = true;
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
WORK_ITEM_TYPE_VALUE_OBJECTIVE,
|
||||
|
|
@ -462,67 +477,148 @@ export default {
|
|||
@click="$emit('close')"
|
||||
/>
|
||||
</div>
|
||||
<work-item-title
|
||||
v-if="workItem.title"
|
||||
:work-item-id="workItem.id"
|
||||
:work-item-title="workItem.title"
|
||||
:work-item-type="workItemType"
|
||||
:work-item-parent-id="workItemParentId"
|
||||
:can-update="canUpdate"
|
||||
@error="updateError = $event"
|
||||
/>
|
||||
<work-item-created-updated :work-item-iid="workItemIid" />
|
||||
<work-item-attributes-wrapper
|
||||
:work-item="workItem"
|
||||
:work-item-parent-id="workItemParentId"
|
||||
@error="updateError = $event"
|
||||
/>
|
||||
<work-item-description
|
||||
v-if="hasDescriptionWidget"
|
||||
:work-item-id="workItem.id"
|
||||
:work-item-iid="workItem.iid"
|
||||
class="gl-pt-5"
|
||||
@error="updateError = $event"
|
||||
/>
|
||||
<work-item-award-emoji
|
||||
v-if="workItemAwardEmoji"
|
||||
:work-item-id="workItem.id"
|
||||
:work-item-fullpath="workItem.project.fullPath"
|
||||
:award-emoji="workItemAwardEmoji.awardEmoji"
|
||||
:work-item-iid="workItemIid"
|
||||
@error="updateError = $event"
|
||||
/>
|
||||
<work-item-tree
|
||||
v-if="workItemType === $options.WORK_ITEM_TYPE_VALUE_OBJECTIVE"
|
||||
:work-item-type="workItemType"
|
||||
:parent-work-item-type="workItem.workItemType.name"
|
||||
:work-item-id="workItem.id"
|
||||
:work-item-iid="workItemIid"
|
||||
:children="children"
|
||||
:can-update="canUpdate"
|
||||
:confidential="workItem.confidential"
|
||||
@show-modal="openInModal"
|
||||
/>
|
||||
<work-item-notes
|
||||
v-if="workItemNotes"
|
||||
:work-item-id="workItem.id"
|
||||
:work-item-iid="workItem.iid"
|
||||
:work-item-type="workItemType"
|
||||
:is-modal="isModal"
|
||||
:assignees="workItemAssignees && workItemAssignees.assignees.nodes"
|
||||
:can-set-work-item-metadata="canAssignUnassignUser"
|
||||
:report-abuse-path="reportAbusePath"
|
||||
class="gl-pt-5"
|
||||
@error="updateError = $event"
|
||||
@has-notes="updateHasNotes"
|
||||
@openReportAbuse="openReportAbuseDrawer"
|
||||
/>
|
||||
<gl-empty-state
|
||||
v-if="error"
|
||||
:title="$options.i18n.fetchErrorTitle"
|
||||
:description="error"
|
||||
:svg-path="noAccessSvgPath"
|
||||
/>
|
||||
<div>
|
||||
<work-item-title
|
||||
v-if="workItem.title"
|
||||
ref="title"
|
||||
:work-item-id="workItem.id"
|
||||
:work-item-title="workItem.title"
|
||||
:work-item-type="workItemType"
|
||||
:work-item-parent-id="workItemParentId"
|
||||
:can-update="canUpdate"
|
||||
@error="updateError = $event"
|
||||
/>
|
||||
<work-item-created-updated :work-item-iid="workItemIid" />
|
||||
</div>
|
||||
<gl-intersection-observer
|
||||
v-if="showIntersectionObserver"
|
||||
@appear="hideStickyHeader"
|
||||
@disappear="showStickyHeader"
|
||||
>
|
||||
<transition name="issuable-header-slide">
|
||||
<div
|
||||
v-if="isStickyHeaderShowing"
|
||||
class="issue-sticky-header gl-fixed gl-bg-white gl-border-b gl-z-index-3 gl-py-2"
|
||||
data-testid="work-item-sticky-header"
|
||||
>
|
||||
<div
|
||||
class="gl-align-items-center gl-mx-auto gl-px-5 gl-display-flex gl-max-w-container-xl"
|
||||
>
|
||||
<span class="gl-text-truncate gl-font-weight-bold gl-pr-3 gl-mr-auto">
|
||||
{{ workItem.title }}
|
||||
</span>
|
||||
<gl-loading-icon v-if="updateInProgress" class="gl-mr-3" />
|
||||
<gl-badge
|
||||
v-if="workItem.confidential"
|
||||
v-gl-tooltip.bottom
|
||||
:title="confidentialTooltip"
|
||||
variant="warning"
|
||||
icon="eye-slash"
|
||||
class="gl-mr-3 gl-cursor-help"
|
||||
>{{ __('Confidential') }}</gl-badge
|
||||
>
|
||||
<work-item-todos
|
||||
v-if="showWorkItemCurrentUserTodos"
|
||||
:work-item-id="workItem.id"
|
||||
:work-item-iid="workItemIid"
|
||||
:work-item-fullpath="workItem.project.fullPath"
|
||||
:current-user-todos="currentUserTodos"
|
||||
@error="updateError = $event"
|
||||
/>
|
||||
<work-item-actions
|
||||
:work-item-id="workItem.id"
|
||||
:subscribed-to-notifications="workItemNotificationsSubscribed"
|
||||
:work-item-type="workItemType"
|
||||
:work-item-type-id="workItemTypeId"
|
||||
:can-delete="canDelete"
|
||||
:can-update="canUpdate"
|
||||
:is-confidential="workItem.confidential"
|
||||
:is-parent-confidential="parentWorkItemConfidentiality"
|
||||
:work-item-reference="workItem.reference"
|
||||
:work-item-create-note-email="workItem.createNoteEmail"
|
||||
:is-modal="isModal"
|
||||
@deleteWorkItem="
|
||||
$emit('deleteWorkItem', { workItemType, workItemId: workItem.id })
|
||||
"
|
||||
@toggleWorkItemConfidentiality="toggleConfidentiality"
|
||||
@error="updateError = $event"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</gl-intersection-observer>
|
||||
<div
|
||||
data-testid="work-item-overview"
|
||||
:class="{ 'work-item-overview': workItemsMvc2Enabled }"
|
||||
>
|
||||
<section>
|
||||
<work-item-attributes-wrapper
|
||||
:class="{ 'gl-md-display-none!': workItemsMvc2Enabled }"
|
||||
class="gl-border-b"
|
||||
:work-item="workItem"
|
||||
:work-item-parent-id="workItemParentId"
|
||||
@error="updateError = $event"
|
||||
/>
|
||||
<work-item-description
|
||||
v-if="hasDescriptionWidget"
|
||||
:work-item-id="workItem.id"
|
||||
:work-item-iid="workItem.iid"
|
||||
class="gl-pt-5"
|
||||
@error="updateError = $event"
|
||||
/>
|
||||
<work-item-award-emoji
|
||||
v-if="workItemAwardEmoji"
|
||||
:work-item-id="workItem.id"
|
||||
:work-item-fullpath="workItem.project.fullPath"
|
||||
:award-emoji="workItemAwardEmoji.awardEmoji"
|
||||
:work-item-iid="workItemIid"
|
||||
@error="updateError = $event"
|
||||
/>
|
||||
<work-item-tree
|
||||
v-if="workItemType === $options.WORK_ITEM_TYPE_VALUE_OBJECTIVE"
|
||||
:work-item-type="workItemType"
|
||||
:parent-work-item-type="workItem.workItemType.name"
|
||||
:work-item-id="workItem.id"
|
||||
:work-item-iid="workItemIid"
|
||||
:children="children"
|
||||
:can-update="canUpdate"
|
||||
:confidential="workItem.confidential"
|
||||
@show-modal="openInModal"
|
||||
/>
|
||||
<work-item-notes
|
||||
v-if="workItemNotes"
|
||||
:work-item-id="workItem.id"
|
||||
:work-item-iid="workItem.iid"
|
||||
:work-item-type="workItemType"
|
||||
:is-modal="isModal"
|
||||
:assignees="workItemAssignees && workItemAssignees.assignees.nodes"
|
||||
:can-set-work-item-metadata="canAssignUnassignUser"
|
||||
:report-abuse-path="reportAbusePath"
|
||||
class="gl-pt-5"
|
||||
@error="updateError = $event"
|
||||
@has-notes="updateHasNotes"
|
||||
@openReportAbuse="openReportAbuseDrawer"
|
||||
/>
|
||||
<gl-empty-state
|
||||
v-if="error"
|
||||
:title="$options.i18n.fetchErrorTitle"
|
||||
:description="error"
|
||||
:svg-path="noAccessSvgPath"
|
||||
/>
|
||||
</section>
|
||||
<aside
|
||||
v-if="workItemsMvc2Enabled"
|
||||
data-testid="work-item-overview-right-sidebar"
|
||||
class="work-item-overview-right-sidebar gl-display-none gl-md-display-block"
|
||||
:class="{ 'is-modal': isModal }"
|
||||
>
|
||||
<work-item-attributes-wrapper
|
||||
:work-item="workItem"
|
||||
:work-item-parent-id="workItemParentId"
|
||||
@error="updateError = $event"
|
||||
/>
|
||||
</aside>
|
||||
</div>
|
||||
</template>
|
||||
<work-item-detail-modal
|
||||
v-if="!isModal"
|
||||
|
|
|
|||
|
|
@ -88,7 +88,11 @@ export default {
|
|||
return !this.canUpdate && !this.dueDate && !this.startDate;
|
||||
},
|
||||
labelClass() {
|
||||
return this.isReadonlyWithNoDates ? 'gl-align-self-center gl-pb-0!' : 'gl-mt-3 gl-pb-0!';
|
||||
return {
|
||||
'work-item-field-label': true,
|
||||
'gl-align-self-center gl-pb-0!': this.isReadonlyWithNoDates,
|
||||
'gl-mt-3 gl-pb-0!': !this.isReadonlyWithNoDates,
|
||||
};
|
||||
},
|
||||
showDueDateButton() {
|
||||
return this.canUpdate && !this.showDueDateInput;
|
||||
|
|
|
|||
|
|
@ -259,7 +259,7 @@ export default {
|
|||
<div class="form-row gl-mb-5 work-item-labels gl-relative gl-flex-nowrap">
|
||||
<span
|
||||
:id="labelsTitleId"
|
||||
class="gl-font-weight-bold gl-mt-2 col-lg-2 col-3 gl-pt-2 min-w-fit-content gl-overflow-wrap-break"
|
||||
class="gl-font-weight-bold gl-mt-2 col-lg-2 col-3 gl-pt-2 min-w-fit-content gl-overflow-wrap-break work-item-field-label"
|
||||
data-testid="labels-title"
|
||||
>{{ __('Labels') }}</span
|
||||
>
|
||||
|
|
@ -272,7 +272,8 @@ export default {
|
|||
:loading="isLoading"
|
||||
:view-only="!canUpdate"
|
||||
:allow-clear-all="isEditing"
|
||||
class="gl-flex-grow-1 gl-border gl-border-white gl-rounded-base col-9 gl-align-self-start gl-px-0! gl-mx-2!"
|
||||
class="gl-flex-grow-1 gl-border gl-border-white gl-rounded-base col-9 gl-align-self-start gl-px-0! gl-mx-2! work-item-field-value"
|
||||
menu-class="token-selector-menu-class"
|
||||
data-testid="work-item-labels-input"
|
||||
:class="{ 'gl-hover-border-gray-200': canUpdate }"
|
||||
@input="focusTokenSelector"
|
||||
|
|
|
|||
|
|
@ -208,13 +208,13 @@ export default {
|
|||
class="work-item-dropdown gl-flex-nowrap"
|
||||
:label="$options.i18n.MILESTONE"
|
||||
label-for="milestone-value"
|
||||
label-class="gl-pb-0! gl-mt-3 gl-overflow-wrap-break"
|
||||
label-class="gl-pb-0! gl-mt-3 gl-overflow-wrap-break work-item-field-label"
|
||||
label-cols="3"
|
||||
label-cols-lg="2"
|
||||
>
|
||||
<span
|
||||
v-if="!canUpdate"
|
||||
class="gl-text-secondary gl-ml-4 gl-mt-3 gl-display-inline-block gl-line-height-normal"
|
||||
class="gl-text-secondary gl-ml-4 gl-mt-3 gl-display-inline-block gl-line-height-normal work-item-field-value"
|
||||
data-testid="disabled-text"
|
||||
>
|
||||
{{ dropdownText }}
|
||||
|
|
@ -223,7 +223,7 @@ export default {
|
|||
v-else
|
||||
id="milestone-value"
|
||||
data-testid="work-item-milestone-dropdown"
|
||||
class="gl-pl-0 gl-max-w-full"
|
||||
class="gl-pl-0 gl-max-w-full work-item-field-value"
|
||||
:toggle-class="dropdownClasses"
|
||||
:text="dropdownText"
|
||||
:loading="updateInProgress"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
@import 'mixins_and_variables_and_functions';
|
||||
|
||||
$work-item-overview-right-sidebar-width: 340px;
|
||||
$work-item-sticky-header-height: 52px;
|
||||
|
||||
.gl-token-selector-token-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
@ -104,3 +107,54 @@
|
|||
@include gl-font-weight-normal;
|
||||
}
|
||||
}
|
||||
|
||||
.work-item-overview {
|
||||
@include media-breakpoint-up(md) {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr $work-item-overview-right-sidebar-width;
|
||||
gap: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.work-item-overview-right-sidebar {
|
||||
@include media-breakpoint-up(md) {
|
||||
&.is-modal {
|
||||
.work-item-attributes-wrapper {
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.work-item-attributes-wrapper {
|
||||
.work-item-overview & {
|
||||
@include media-breakpoint-up(md) {
|
||||
top: calc(#{$calc-application-header-height} + #{$work-item-sticky-header-height});
|
||||
height: calc(#{$calc-application-viewport-height} - #{$work-item-sticky-header-height});
|
||||
margin-bottom: calc(#{$content-wrapper-padding} * -1);
|
||||
position: sticky;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.work-item-field-label {
|
||||
.work-item-overview & {
|
||||
max-width: 30%;
|
||||
flex: none;
|
||||
}
|
||||
}
|
||||
|
||||
.work-item-field-value {
|
||||
.work-item-overview & {
|
||||
max-width: 65%;
|
||||
}
|
||||
}
|
||||
|
||||
.token-selector-menu-class {
|
||||
.work-item-overview & {
|
||||
width: 100%;
|
||||
min-width: 100%;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
= s_('Jobs|Use jobs to automate your tasks')
|
||||
%p
|
||||
= s_('Jobs|Jobs are the building blocks of a GitLab CI/CD pipeline. Each job has a specific task, like testing code. To set up jobs in a CI/CD pipeline, add a CI/CD configuration file to your project.')
|
||||
= link_to s_('Jobs|Create CI/CD configuration file'), project_ci_pipeline_editor_path(project), class: 'btn gl-button btn-confirm js-empty-state-button'
|
||||
= link_button_to s_('Jobs|Create CI/CD configuration file'), project_ci_pipeline_editor_path(project), class: 'js-empty-state-button', variant: :confirm
|
||||
- else
|
||||
.nothing-here-block= s_('Jobs|No jobs to show')
|
||||
- else
|
||||
|
|
|
|||
|
|
@ -40,4 +40,4 @@
|
|||
= f.gitlab_ui_checkbox_component :active, _('Active'), checkbox_options: { value: @schedule.active, required: false }
|
||||
.footer-block
|
||||
= f.submit _('Save pipeline schedule'), pajamas_button: true
|
||||
= link_to _('Cancel'), pipeline_schedules_path(@project), class: 'btn gl-button btn-default btn-cancel'
|
||||
= link_button_to _('Cancel'), pipeline_schedules_path(@project)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
name: key_set_optimizer_ignored_columns
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/125462
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/417515
|
||||
name: fix_new_blobs_memoization
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/125241
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/417632
|
||||
milestone: '16.2'
|
||||
type: development
|
||||
group: group::project management
|
||||
group: group::source code
|
||||
default_enabled: false
|
||||
|
|
@ -58,7 +58,7 @@ NOT_AVAILABLE_TEMPLATES = {
|
|||
analytics_instrumentation: group_not_available_template('#g_analyze_analytics_instrumentation', '@gitlab-org/analytics-section/analytics-instrumentation/engineers'),
|
||||
import_integrate_be: group_not_available_template('#g_manage_import_and_integrate', '@gitlab-org/manage/import-and-integrate'),
|
||||
import_integrate_fe: group_not_available_template('#g_manage_import_and_integrate', '@gitlab-org/manage/import-and-integrate'),
|
||||
remote_development: group_not_available_template('#f_remote_development', '@gitlab-org/remote-development')
|
||||
remote_development_be: group_not_available_template('#f_remote_development', '@gitlab-org/maintainers/remote-development/backend')
|
||||
}.freeze
|
||||
|
||||
def note_for_spin_role(spin, role, category)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,83 @@
|
|||
---
|
||||
stage: Fulfillment
|
||||
group: Provision
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Activate GitLab Enterprise Edition (EE) **(PREMIUM SELF)**
|
||||
|
||||
When you install a new GitLab instance without a license, only Free features
|
||||
are enabled. To enable more features in GitLab Enterprise Edition (EE), activate
|
||||
your instance with an activation code.
|
||||
|
||||
## Activate GitLab EE
|
||||
|
||||
In GitLab Enterprise Edition 14.1 and later, you need an activation code to activate
|
||||
your instance.
|
||||
|
||||
Prerequisite:
|
||||
|
||||
- You must [purchase a subscription](https://about.gitlab.com/pricing/).
|
||||
- You must be running GitLab Enterprise Edition (EE).
|
||||
- You must have GitLab 14.1 or later.
|
||||
- Your instance must be connected to the internet.
|
||||
|
||||
To activate your instance with an activation code:
|
||||
|
||||
1. Copy the activation code, a 24-character alphanumeric string, from either:
|
||||
- Your subscription confirmation email.
|
||||
- The [Customers Portal](https://customers.gitlab.com/customers/sign_in), on the **Manage Purchases** page.
|
||||
1. Sign in to your GitLab self-managed instance.
|
||||
1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
|
||||
1. Select **Admin Area**.
|
||||
1. Select **Subscription**.
|
||||
1. Paste the activation code in **Activation code**.
|
||||
1. Read and accept the terms of service.
|
||||
1. Select **Activate**.
|
||||
|
||||
The subscription is activated.
|
||||
|
||||
If you have an offline environment,
|
||||
[activate GitLab EE with a license file or key](../user/admin_area/license_file.md) instead.
|
||||
|
||||
If you have questions or need assistance activating your instance,
|
||||
[contact GitLab Support](https://about.gitlab.com/support/#contact-support).
|
||||
|
||||
When [the license expires](../administration/license_file.md#what-happens-when-your-license-expires),
|
||||
some functionality is locked.
|
||||
|
||||
## Verify your GitLab edition
|
||||
|
||||
To verify the edition, sign in to GitLab and select
|
||||
**Help** (**{question-o}**) > **Help**. The GitLab edition and version are listed
|
||||
at the top of the page.
|
||||
|
||||
If you are running GitLab Community Edition, you can upgrade your installation to GitLab
|
||||
EE. For more details, see [Upgrading between editions](../update/index.md#upgrading-between-editions).
|
||||
If you have questions or need assistance upgrading from GitLab Community Edition (CE) to EE,
|
||||
[contact GitLab Support](https://about.gitlab.com/support/#contact-support).
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Cannot activate instance due to connectivity error
|
||||
|
||||
This error occurs when you use an activation code to activate your instance, but your instance is unable to connect to the GitLab servers.
|
||||
|
||||
You may have connectivity issues due to the following reasons:
|
||||
|
||||
- **You have an offline environment**:
|
||||
- Configure your setup to allow connection to GitLab servers. If connection to GitLab servers is not possible, contact your Sales Representative to request a license key. You can also contact [GitLab support](https://about.gitlab.com/support/#contact-support) if you need help finding your Sales Representative.
|
||||
- **Customers Portal is not operational**:
|
||||
- To check for performance or service disruptions, check the Customers Portal [status](https://status.gitlab.com/).
|
||||
- **Firewall settings**:
|
||||
- Check if your GitLab instance has an encrypted connection to `customers.gitlab.com` (with IP addresses 172.64.146.11 and 104.18.41.245) on port 443:
|
||||
|
||||
```shell
|
||||
curl --verbose "https://customers.gitlab.com/"
|
||||
```
|
||||
|
||||
- If the curl command returns a failure, either:
|
||||
- [Configure a proxy](https://docs.gitlab.com/omnibus/settings/environment-variables.html) in `gitlab.rb` to point to your server.
|
||||
- Contact your network administrator to make changes to the proxy.
|
||||
- If an SSL inspection appliance is used, you must add the appliance's root CA certificate to `/etc/gitlab/trusted-certs` on the server, then run `gitlab-ctl reconfigure`.
|
||||
|
||||
|
|
@ -113,7 +113,7 @@ Configure DNS for an alternate SSH hostname such as `altssh.gitlab.example.com`.
|
|||
|
||||
## Readiness check
|
||||
|
||||
It is strongly recommend that multi-node deployments configure load balancers to use the [readiness check](../user/admin_area/monitoring/health_check.md#readiness) to ensure a node is ready to accept traffic, before routing traffic to it. This is especially important when utilizing Puma, as there is a brief period during a restart where Puma doesn't accept requests.
|
||||
It is strongly recommend that multi-node deployments configure load balancers to use the [readiness check](../administration/monitoring/health_check.md#readiness) to ensure a node is ready to accept traffic, before routing traffic to it. This is especially important when utilizing Puma, as there is a brief period during a restart where Puma doesn't accept requests.
|
||||
|
||||
WARNING:
|
||||
Using the `all=1` parameter with the readiness check in GitLab versions 15.4 to 15.8 may cause [increased Praefect memory usage](https://gitlab.com/gitlab-org/gitaly/-/issues/4751) and lead to memory errors.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,146 @@
|
|||
---
|
||||
stage: Monitor
|
||||
group: Respond
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Health Check **(FREE SELF)**
|
||||
|
||||
GitLab provides liveness and readiness probes to indicate service health and
|
||||
reachability to required services. These probes report on the status of the
|
||||
database connection, Redis connection, and access to the file system. These
|
||||
endpoints [can be provided to schedulers like Kubernetes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) to hold
|
||||
traffic until the system is ready or restart the container as needed.
|
||||
|
||||
## IP allowlist
|
||||
|
||||
To access monitoring resources, the requesting client IP needs to be included in the allowlist.
|
||||
For details, see [how to add IPs to the allowlist for the monitoring endpoints](../../administration/monitoring/ip_allowlist.md).
|
||||
|
||||
## Using the endpoints locally
|
||||
|
||||
With default allowlist settings, the probes can be accessed from localhost using the following URLs:
|
||||
|
||||
```plaintext
|
||||
GET http://localhost/-/health
|
||||
```
|
||||
|
||||
```plaintext
|
||||
GET http://localhost/-/readiness
|
||||
```
|
||||
|
||||
```plaintext
|
||||
GET http://localhost/-/liveness
|
||||
```
|
||||
|
||||
## Health
|
||||
|
||||
Checks whether the application server is running.
|
||||
It does not verify the database or other services
|
||||
are running. This endpoint circumvents Rails Controllers
|
||||
and is implemented as additional middleware `BasicHealthCheck`
|
||||
very early into the request processing lifecycle.
|
||||
|
||||
```plaintext
|
||||
GET /-/health
|
||||
```
|
||||
|
||||
Example request:
|
||||
|
||||
```shell
|
||||
curl "https://gitlab.example.com/-/health"
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```plaintext
|
||||
GitLab OK
|
||||
```
|
||||
|
||||
## Readiness
|
||||
|
||||
The readiness probe checks whether the GitLab instance is ready
|
||||
to accept traffic via Rails Controllers. The check by default
|
||||
does validate only instance-checks.
|
||||
|
||||
If the `all=1` parameter is specified, the check also validates
|
||||
the dependent services (Database, Redis, Gitaly etc.)
|
||||
and gives a status for each.
|
||||
|
||||
```plaintext
|
||||
GET /-/readiness
|
||||
GET /-/readiness?all=1
|
||||
```
|
||||
|
||||
Example request:
|
||||
|
||||
```shell
|
||||
curl "https://gitlab.example.com/-/readiness"
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
{
|
||||
"master_check":[{
|
||||
"status":"failed",
|
||||
"message": "unexpected Master check result: false"
|
||||
}],
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
On failure, the endpoint returns a `503` HTTP status code.
|
||||
|
||||
This check is being exempt from Rack Attack.
|
||||
|
||||
## Liveness
|
||||
|
||||
WARNING:
|
||||
In GitLab [12.4](https://about.gitlab.com/upcoming-releases/)
|
||||
the response body of the Liveness check was changed
|
||||
to match the example below.
|
||||
|
||||
Checks whether the application server is running.
|
||||
This probe is used to know if Rails Controllers
|
||||
are not deadlocked due to a multi-threading.
|
||||
|
||||
```plaintext
|
||||
GET /-/liveness
|
||||
```
|
||||
|
||||
Example request:
|
||||
|
||||
```shell
|
||||
curl "https://gitlab.example.com/-/liveness"
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
On success, the endpoint returns a `200` HTTP status code, and a response like below.
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "ok"
|
||||
}
|
||||
```
|
||||
|
||||
On failure, the endpoint returns a `503` HTTP status code.
|
||||
|
||||
This check is being exempt from Rack Attack.
|
||||
|
||||
## Sidekiq
|
||||
|
||||
Learn how to configure the [Sidekiq health checks](../../administration/sidekiq/sidekiq_health_check.md).
|
||||
|
||||
<!-- ## Troubleshooting
|
||||
|
||||
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
|
||||
one might have when setting this up, or when something is changed, or on upgrading, it's
|
||||
important to describe those, too. Think of things that may go wrong and include them here.
|
||||
This is important to minimize requests for support, and to avoid doc comments with
|
||||
questions that you know someone might ask.
|
||||
|
||||
Each scenario can be a third-level heading, for example `### Getting error message X`.
|
||||
If you have none to add when creating a doc, leave this section in place
|
||||
but commented out to help encourage others to add to it in the future. -->
|
||||
|
|
@ -69,7 +69,7 @@ GitLab Shell path: /opt/gitlab/embedded/service/gitlab-shell
|
|||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20501) in GitLab 12.6.
|
||||
> - Moved to GitLab Premium in 13.9.
|
||||
|
||||
This command shows information about your [GitLab license](../../user/admin_area/license.md) and
|
||||
This command shows information about your [GitLab license](../../administration/license.md) and
|
||||
how many seats are used. It is only available on GitLab Enterprise
|
||||
installations: a license cannot be installed into GitLab Community Edition.
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
---
|
||||
stage: Anti-Abuse
|
||||
group: Anti-Abuse
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Git abuse rate limit (administration) **(ULTIMATE SELF)**
|
||||
|
||||
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/8066) in GitLab 15.2 [with a flag](../../administration/feature_flags.md) named `git_abuse_rate_limit_feature_flag`. Disabled by default.
|
||||
> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/394996) in GitLab 15.11. Feature flag `git_abuse_rate_limit_feature_flag` removed.
|
||||
|
||||
This is the administration documentation. For information about Git abuse rate limiting at the group level, see the [group-level documentation](../../user/group/reporting/git_abuse_rate_limit.md).
|
||||
|
||||
Git abuse rate limiting is a feature to automatically [ban users](../../user/admin_area/moderate_users.md#ban-and-unban-users) who download, clone, or fork more than a specified number of repositories in any project in the instance in a given time frame. Banned users cannot sign in to the instance and cannot access any non-public group via HTTP or SSH. The rate limit also applies to users who authenticate with a [personal](../../user/profile/personal_access_tokens.md) or [group access token](../../user/group/settings/group_access_tokens.md).
|
||||
|
||||
Git abuse rate limiting does not apply to instance administrators, [deploy tokens](../../user/project/deploy_tokens/index.md), or [deploy keys](../../user/project/deploy_keys/index.md).
|
||||
|
||||
How GitLab determines a user's rate limit is under development.
|
||||
GitLab team members can view more information in this confidential epic:
|
||||
`https://gitlab.com/groups/gitlab-org/modelops/anti-abuse/-/epics/14`.
|
||||
|
||||
## Configure Git abuse rate limiting
|
||||
|
||||
1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
|
||||
1. Select **Admin Area**.
|
||||
1. Select **Settings > Reporting**.
|
||||
1. Expand **Git abuse rate limit**.
|
||||
1. Update the Git abuse rate limit settings:
|
||||
1. Enter a number in the **Number of repositories** field, greater than or equal to `0` and less than or equal to `10,000`. This number specifies the maximum amount of unique repositories a user can download in the specified time period before they're banned. When set to `0`, Git abuse rate limiting is disabled.
|
||||
1. Enter a number in the **Reporting time period (seconds)** field, greater than or equal to `0` and less than or equal to `86,400` (10 days). This number specifies the time in seconds a user can download the maximum amount of repositories before they're banned. When set to `0`, Git abuse rate limiting is disabled.
|
||||
1. Optional. Exclude up to `100` users by adding them to the **Excluded users** field. Excluded users are not automatically banned.
|
||||
1. Add up to `100` users to the **Send notifications to** field. You must select at least one user. All application administrators are selected by default.
|
||||
1. Optional. Turn on the **Automatically ban users from this namespace when they exceed the specified limits** toggle to enable automatic banning.
|
||||
1. Select **Save changes**.
|
||||
|
||||
## Automatic ban notifications
|
||||
|
||||
If automatic banning is disabled, a user is not banned automatically when they exceed the limit. However, notifications are still sent to the users listed under **Send notifications to**. You can use this setup to determine the correct values of the rate limit settings before enabling automatic banning.
|
||||
|
||||
If automatic banning is enabled, an email notification is sent when a user is about to be banned, and the user is automatically banned from the GitLab instance.
|
||||
|
||||
## Unban a user
|
||||
|
||||
1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
|
||||
1. Select **Admin Area**.
|
||||
1. Select **Overview > Users**.
|
||||
1. Select the **Banned** tab and search for the account you want to unban.
|
||||
1. From the **User administration** dropdown list select **Unban user**.
|
||||
1. On the confirmation dialog, select **Unban user**.
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
---
|
||||
type: reference
|
||||
stage: Data Stores
|
||||
group: Tenant Scale
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Rate limit on Projects API **(FREE SELF)**
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/112283) in GitLab 15.10 with a [flag](../feature_flags.md) named `rate_limit_for_unauthenticated_projects_api_access`. Disabled by default.
|
||||
> - [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/391922) on May 08, 2023.
|
||||
> - [Enabled on self-managed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/119603) in GitLab 16.0 by default.
|
||||
> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/120445) in GitLab 16.0. Feature flag `rate_limit_for_unauthenticated_projects_api_access` removed.
|
||||
|
||||
You can configure the rate limit per IP address for unauthenticated requests to the [list all projects API](../../api/projects.md#list-all-projects).
|
||||
|
||||
To change the rate limit:
|
||||
|
||||
1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
|
||||
1. Select **Admin Area**.
|
||||
1. Select **Settings > Network**.
|
||||
1. Expand **Projects API rate limit**.
|
||||
1. In the **Maximum requests per 10 minutes per IP address** text box, enter the new value.
|
||||
1. Select **Save changes**.
|
||||
|
||||
The rate limit:
|
||||
|
||||
- Applies per IP address.
|
||||
- Doesn't apply to authenticated requests.
|
||||
- Can be set to 0 to disable rate limiting.
|
||||
|
||||
The default value of the rate limit is `400`.
|
||||
|
||||
Requests over the rate limit are logged into the `auth.log` file.
|
||||
|
||||
For example, if you set a limit of 400, unauthenticated requests to the `GET /projects` API endpoint that
|
||||
exceed a rate of 400 within 10 minutes are blocked. Access to the endpoint is restored after ten minutes have elapsed.
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
---
|
||||
type: reference
|
||||
stage: Manage
|
||||
group: Authentication and Authorization
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Rate limits on Users API **(FREE SELF)**
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78364) in GitLab 14.8.
|
||||
|
||||
You can configure the per user rate limit for requests to [Users API](../../api/users.md).
|
||||
|
||||
To change the rate limit:
|
||||
|
||||
1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
|
||||
1. Select **Admin Area**.
|
||||
1. Select **Settings > Network**.
|
||||
1. Expand **Users API rate limit**.
|
||||
1. In the **Maximum requests per 10 minutes** text box, enter the new value.
|
||||
1. Optional. In the **Users to exclude from the rate limit** box, list users allowed to exceed the limit.
|
||||
1. Select **Save changes**.
|
||||
|
||||
This limit is:
|
||||
|
||||
- Applied independently per user.
|
||||
- Not applied per IP address.
|
||||
|
||||
The default value is `300`.
|
||||
|
||||
Requests over the rate limit are logged into the `auth.log` file.
|
||||
|
||||
For example, if you set a limit of 300, requests to the `GET /users/:id` API endpoint
|
||||
exceeding a rate of 300 per 10 minutes are blocked. Access to the endpoint is allowed after ten minutes have elapsed.
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
---
|
||||
stage: Create
|
||||
group: Source Code
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
type: reference
|
||||
---
|
||||
|
||||
# Rate limits on Git SSH operations **(FREE SELF)**
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78373) in GitLab 14.7 [with a flag](../feature_flags.md) named `rate_limit_gitlab_shell`. Available by default without a feature flag from 15.8.
|
||||
|
||||
GitLab applies rate limits to Git operations that use SSH by user account and project. When the rate limit is exceeded, GitLab rejects
|
||||
further connection requests from that user for the project.
|
||||
|
||||
The rate limit applies at the Git command ([plumbing](https://git-scm.com/book/en/v2/Git-Internals-Plumbing-and-Porcelain)) level.
|
||||
Each command has a rate limit of 600 per minute. For example:
|
||||
|
||||
- `git push` has a rate limit of 600 per minute.
|
||||
- `git pull` has its own rate limit of 600 per minute.
|
||||
|
||||
Because the same commands are shared by `git-upload-pack`, `git pull`, and `git clone`, they share a rate limit.
|
||||
|
||||
Users on self-managed GitLab can disable this rate limit.
|
||||
|
||||
## Configure GitLab Shell operation limit
|
||||
|
||||
`Git operations using SSH` is enabled by default. Defaults to 600 per user per minute.
|
||||
|
||||
1. On the left sidebar, select **Your work > Admin Area**.
|
||||
1. On the left sidebar, select **Settings > Network**.
|
||||
1. Expand **Git SSH operations rate limit**.
|
||||
1. Enter a value for **Maximum number of Git operations per minute**.
|
||||
1. Select **Save changes**.
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
---
|
||||
stage: none
|
||||
group: unassigned
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
type: reference
|
||||
---
|
||||
|
||||
# Rate limits on raw endpoints **(FREE SELF)**
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/30635) in GitLab 12.2.
|
||||
|
||||
This setting defaults to `300` requests per minute, and allows you to rate limit the requests to raw endpoints:
|
||||
|
||||
1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
|
||||
1. Select **Admin Area**.
|
||||
1. Select **Settings > Network**.
|
||||
1. Expand **Performance optimization**.
|
||||
|
||||
For example, requests over `300` per minute to `https://gitlab.com/gitlab-org/gitlab-foss/raw/master/app/controllers/application_controller.rb` are blocked. Access to the raw file is released after 1 minute.
|
||||
|
||||

|
||||
|
||||
This limit is:
|
||||
|
||||
- Applied independently per project, per file path.
|
||||
- Not applied per IP address.
|
||||
- Active by default. To disable, set the option to `0`.
|
||||
|
||||
Requests over the rate limit are logged into `auth.log`.
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
---
|
||||
type: reference, howto
|
||||
stage: Manage
|
||||
group: Authentication and Authorization
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Configure SCIM for self-managed GitLab instances **(PREMIUM SELF)**
|
||||
|
||||
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/8902) in GitLab 15.8.
|
||||
|
||||
You can use the open standard System for Cross-domain Identity Management (SCIM) to automatically:
|
||||
|
||||
- Create users.
|
||||
- Block users.
|
||||
|
||||
The [internal GitLab SCIM API](../../development/internal_api/index.md#instance-scim-api) implements part of [the RFC7644 protocol](https://www.rfc-editor.org/rfc/rfc7644).
|
||||
|
||||
If you are a GitLab.com user, see [configuring SCIM for GitLab.com groups](../../user/group/saml_sso/scim_setup.md).
|
||||
|
||||
## Configure GitLab
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- Configure [SAML single sign-on](../../integration/saml.md).
|
||||
|
||||
To configure GitLab SCIM:
|
||||
|
||||
1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
|
||||
1. Select **Admin Area**.
|
||||
1. Select **Settings > General**.
|
||||
1. Expand the **SCIM Token** section and select **Generate a SCIM token**.
|
||||
1. For configuration of your identity provider, save the:
|
||||
- Token from the **Your SCIM token** field.
|
||||
- URL from the **SCIM API endpoint URL** field.
|
||||
|
||||
## Remove access
|
||||
|
||||
Removing or deactivating a user on the identity provider blocks the user on
|
||||
the GitLab instance, while the SCIM identity remains linked to the GitLab user.
|
||||
|
||||
To update the user SCIM identity, use the
|
||||
[internal GitLab SCIM API](../../development/internal_api/index.md#update-a-single-scim-provisioned-user-1).
|
||||
|
|
@ -38,7 +38,7 @@ Have a look at some of our most popular topics:
|
|||
| [Two-factor authentication](user/profile/account/two_factor_authentication.md) | Improve the security of your GitLab account. |
|
||||
| [GitLab groups](user/group/index.md) | Manage projects together. |
|
||||
| [Keyword reference for the `.gitlab-ci.yml` file](ci/yaml/index.md) | Available configuration options for `.gitlab-ci.yml` files. |
|
||||
| [Activate GitLab EE with a license](user/admin_area/license.md) | Activate GitLab Enterprise Edition functionality with a license. |
|
||||
| [Activate GitLab EE with a license](administration/license.md) | Activate GitLab Enterprise Edition functionality with a license. |
|
||||
| [Back up and restore GitLab](administration/backup_restore/index.md) | Backing up and restoring GitLab self-managed instances. |
|
||||
| [GitLab release and maintenance policy](policy/maintenance.md) | Policies for version naming and cadence, and also upgrade recommendations. |
|
||||
| [Elasticsearch integration](integration/advanced_search/elasticsearch.md) | Integrate Elasticsearch with GitLab to enable advanced search. |
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ installation.
|
|||
|
||||
## License
|
||||
|
||||
- [Add a license](../user/admin_area/license.md) or [start a free trial](https://about.gitlab.com/free-trial/):
|
||||
- [Add a license](../administration/license.md) or [start a free trial](https://about.gitlab.com/free-trial/):
|
||||
Activate all GitLab Enterprise Edition functionality with a license.
|
||||
- [Pricing](https://about.gitlab.com/pricing/): Pricing for the different tiers.
|
||||
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ To enable advanced search:
|
|||
|
||||
NOTE:
|
||||
To see the **Advanced Search** section, you need an active GitLab Premium
|
||||
[license](../../user/admin_area/license.md).
|
||||
[license](../../administration/license.md).
|
||||
|
||||
1. Configure the [advanced search settings](#advanced-search-configuration) for
|
||||
your Elasticsearch cluster. Do not enable **Search with Elasticsearch enabled**
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ New paid features will not be released in Bronze and Starter tiers after GitLab
|
|||
The following features remain available to Bronze and Starter customers, even though
|
||||
the tiers are no longer mentioned in GitLab documentation:
|
||||
|
||||
- [Activate GitLab EE with a license](../user/admin_area/license.md)
|
||||
- [Activate GitLab EE with a license](../administration/license.md)
|
||||
- [Add a help message to the sign-in page](../administration/settings/help_page.md#add-a-help-message-to-the-sign-in-page)
|
||||
- [Burndown and burnup charts](../user/project/milestones/burndown_and_burnup_charts.md) in the [Milestone View](../user/project/milestones/index.md#burndown-charts),
|
||||
- [Code owners](../user/project/codeowners/index.md)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ To subscribe to GitLab for a GitLab self-managed installation:
|
|||
|
||||
1. Go to the [Customers Portal](https://customers.gitlab.com/) and purchase a GitLab self-managed plan.
|
||||
1. After purchase, an activation code is sent to the email address associated with the Customers Portal account.
|
||||
You must [add this code to your GitLab instance](../../user/admin_area/license.md).
|
||||
You must [add this code to your GitLab instance](../../administration/license.md).
|
||||
|
||||
NOTE:
|
||||
If you're purchasing a subscription for an existing **Free** GitLab self-managed
|
||||
|
|
@ -132,7 +132,7 @@ To enable subscription data synchronization you must have:
|
|||
|
||||
- GitLab Enterprise Edition (EE), version 14.1 or later.
|
||||
- Connection to the internet, and must not have an offline environment.
|
||||
- [Activated](../../user/admin_area/license.md) your instance with an activation code.
|
||||
- [Activated](../../administration/license.md) your instance with an activation code.
|
||||
|
||||
When your instance is activated, and data is synchronized, the following processes are automated:
|
||||
|
||||
|
|
@ -367,7 +367,7 @@ You can hover your mouse on the **Renew** button to see the date when it will be
|
|||
1. Enter the number of [users over subscription](#users-over-subscription) in the second box for the user overage incurred in your previous subscription term.
|
||||
1. Review your renewal details and complete the payment process.
|
||||
1. An activation code for the renewal term is available on the [Manage Purchases](https://customers.gitlab.com/subscriptions) page on the relevant subscription card. Select **Copy activation code** to get a copy.
|
||||
1. [Add the activation code](../../user/admin_area/license.md) to your instance.
|
||||
1. [Add the activation code](../../administration/license.md) to your instance.
|
||||
|
||||
An invoice is generated for the renewal and available for viewing or download on the [View invoices](https://customers.gitlab.com/receipts) page. If you have difficulty during the renewal process, contact our [support team](https://support.gitlab.com/hc/en-us/requests/new?ticket_form_id=360000071293) for assistance.
|
||||
|
||||
|
|
|
|||
|
|
@ -299,6 +299,7 @@ and [Helm Chart deployments](https://docs.gitlab.com/charts/). They come with ap
|
|||
- Geo: Since the migration of project designs to SSF, [missing design repositories are being incorrectly flagged as failing verification](https://gitlab.com/gitlab-org/gitlab/-/issues/414279). This is not a result of an actual replication/verification failure but an invalid internal state for these missing repositories inside Geo and results in errors in the logs and the verification progress reporting a failed state for these design repositories. You could be impacted by this issue even if you have not imported projects.
|
||||
- Impacted versions: GitLab versions 16.1.x.
|
||||
- Versions containing fix: GitLab 16.2.0 and later.
|
||||
- For self-compiled installations: You must remove any settings related to Puma worker killer from the `puma.rb` configuration file, since those have been [removed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/118645). For more information, see the [`puma.rb.example`](https://gitlab.com/gitlab-org/gitlab/-/blob/16-0-stable-ee/config/puma.rb.example) file.
|
||||
|
||||
### 16.0.0
|
||||
|
||||
|
|
@ -323,6 +324,9 @@ and [Helm Chart deployments](https://docs.gitlab.com/charts/). They come with ap
|
|||
- Geo: Some project imports do not initialize wiki repositories on project creation. Since the migration of project wikis to SSF, [missing wiki repositories are being incorrectly flagged as failing verification](https://gitlab.com/gitlab-org/gitlab/-/issues/409704). This is not a result of an actual replication/verification failure but an invalid internal state for these missing repositories inside Geo and results in errors in the logs and the verification progress reporting a failed state for these wiki repositories. If you have not imported projects you are not impacted by this issue.
|
||||
- Impacted versions: GitLab versions 15.11.x, 16.0.x, and 16.1.0 - 16.1.2.
|
||||
- Versions containing fix: GitLab 16.1.3 and later.
|
||||
- Geo: A [bug](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/7841) in the built-in `pg-upgrade` tool prevents upgrading the bundled PostgreSQL database to version 13. This leaves the secondary site in a broken state, and prevents upgrading the Geo installation to GitLab 16.x ([PostgreSQL 12 support has removed in 16.0](deprecations.md#postgresql-12-deprecated) and later releases). This occurs on secondary sites using the bundled PostgreSQL software, running both the secondary main Rails database and tracking database on the same node. There is a manual [workaround](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/7841#workaround) for those impacted until a fix is backported to 15.11.
|
||||
- Impacted versions: GitLab versions 15.2 - 15.11
|
||||
- Version 16.0 and later are not impacted. Note, 15.11 is a mandatory upgrade stop on the way to 16.0.
|
||||
|
||||
### 15.11.0
|
||||
|
||||
|
|
@ -332,6 +336,9 @@ and [Helm Chart deployments](https://docs.gitlab.com/charts/). They come with ap
|
|||
- Geo: Some project imports do not initialize wiki repositories on project creation. Since the migration of project wikis to SSF, [missing wiki repositories are being incorrectly flagged as failing verification](https://gitlab.com/gitlab-org/gitlab/-/issues/409704). This is not a result of an actual replication/verification failure but an invalid internal state for these missing repositories inside Geo and results in errors in the logs and the verification progress reporting a failed state for these wiki repositories. If you have not imported projects you are not impacted by this issue.
|
||||
- Impacted versions: GitLab versions 15.11.x, 16.0.x, and 16.1.0 - 16.1.2.
|
||||
- Versions containing fix: GitLab 16.1.3 and later.
|
||||
- Geo: A [bug](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/7841) in the built-in `pg-upgrade` tool prevents upgrading the bundled PostgreSQL database to version 13. This leaves the secondary site in a broken state, and prevents upgrading the Geo installation to GitLab 16.x ([PostgreSQL 12 support has removed in 16.0](deprecations.md#postgresql-12-deprecated) and later releases). This occurs on secondary sites using the bundled PostgreSQL software, running both the secondary main Rails database and tracking database on the same node. There is a manual [workaround](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/7841#workaround) for those impacted until a fix is backported to 15.11.
|
||||
- Impacted versions: GitLab versions 15.2 - 15.11
|
||||
- Version 16.0 and later are not impacted. Note, 15.11 is a mandatory upgrade stop on the way to 16.0.
|
||||
|
||||
### 15.10.5
|
||||
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ The steps can be summed up to:
|
|||
If you want to use `dpkg`/`rpm` instead of `apt-get`/`yum`, go through the first
|
||||
step to find the current GitLab version, then follow
|
||||
[Upgrade using a manually-downloaded package](index.md#upgrade-using-a-manually-downloaded-package),
|
||||
and then [add your license](../../user/admin_area/license.md).
|
||||
and then [add your license](../../administration/license.md).
|
||||
|
||||
1. Install the `gitlab-ee` package. The install automatically
|
||||
uninstalls the `gitlab-ce` package on your GitLab server. `reconfigure`
|
||||
|
|
@ -99,7 +99,7 @@ The steps can be summed up to:
|
|||
sudo gitlab-ctl reconfigure
|
||||
```
|
||||
|
||||
1. Now activate GitLab Enterprise Edition by [adding your license](../../user/admin_area/license.md).
|
||||
1. Now activate GitLab Enterprise Edition by [adding your license](../../administration/license.md).
|
||||
|
||||
1. After you confirm that GitLab is working as expected, you may remove the old
|
||||
Community Edition repository:
|
||||
|
|
|
|||
|
|
@ -1,83 +1,11 @@
|
|||
---
|
||||
stage: Fulfillment
|
||||
group: Provision
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
redirect_to: '../../administration/license.md'
|
||||
remove_date: '2023-10-11'
|
||||
---
|
||||
|
||||
# Activate GitLab Enterprise Edition (EE) **(PREMIUM SELF)**
|
||||
This document was moved to [another location](../../administration/license.md).
|
||||
|
||||
When you install a new GitLab instance without a license, only Free features
|
||||
are enabled. To enable more features in GitLab Enterprise Edition (EE), activate
|
||||
your instance with an activation code.
|
||||
|
||||
## Activate GitLab EE
|
||||
|
||||
In GitLab Enterprise Edition 14.1 and later, you need an activation code to activate
|
||||
your instance.
|
||||
|
||||
Prerequisite:
|
||||
|
||||
- You must [purchase a subscription](https://about.gitlab.com/pricing/).
|
||||
- You must be running GitLab Enterprise Edition (EE).
|
||||
- You must have GitLab 14.1 or later.
|
||||
- Your instance must be connected to the internet.
|
||||
|
||||
To activate your instance with an activation code:
|
||||
|
||||
1. Copy the activation code, a 24-character alphanumeric string, from either:
|
||||
- Your subscription confirmation email.
|
||||
- The [Customers Portal](https://customers.gitlab.com/customers/sign_in), on the **Manage Purchases** page.
|
||||
1. Sign in to your GitLab self-managed instance.
|
||||
1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
|
||||
1. Select **Admin Area**.
|
||||
1. Select **Subscription**.
|
||||
1. Paste the activation code in **Activation code**.
|
||||
1. Read and accept the terms of service.
|
||||
1. Select **Activate**.
|
||||
|
||||
The subscription is activated.
|
||||
|
||||
If you have an offline environment,
|
||||
[activate GitLab EE with a license file or key](../../administration/license_file.md) instead.
|
||||
|
||||
If you have questions or need assistance activating your instance,
|
||||
[contact GitLab Support](https://about.gitlab.com/support/#contact-support).
|
||||
|
||||
When [the license expires](../../administration/license_file.md#what-happens-when-your-license-expires),
|
||||
some functionality is locked.
|
||||
|
||||
## Verify your GitLab edition
|
||||
|
||||
To verify the edition, sign in to GitLab and select
|
||||
**Help** (**{question-o}**) > **Help**. The GitLab edition and version are listed
|
||||
at the top of the page.
|
||||
|
||||
If you are running GitLab Community Edition, you can upgrade your installation to GitLab
|
||||
EE. For more details, see [Upgrading between editions](../../update/index.md#upgrading-between-editions).
|
||||
If you have questions or need assistance upgrading from GitLab Community Edition (CE) to EE,
|
||||
[contact GitLab Support](https://about.gitlab.com/support/#contact-support).
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Cannot activate instance due to connectivity error
|
||||
|
||||
This error occurs when you use an activation code to activate your instance, but your instance is unable to connect to the GitLab servers.
|
||||
|
||||
You may have connectivity issues due to the following reasons:
|
||||
|
||||
- **You have an offline environment**:
|
||||
- Configure your setup to allow connection to GitLab servers. If connection to GitLab servers is not possible, contact your Sales Representative to request a license key. You can also contact [GitLab support](https://about.gitlab.com/support/#contact-support) if you need help finding your Sales Representative.
|
||||
- **Customers Portal is not operational**:
|
||||
- To check for performance or service disruptions, check the Customers Portal [status](https://status.gitlab.com/).
|
||||
- **Firewall settings**:
|
||||
- Check if your GitLab instance has an encrypted connection to `customers.gitlab.com` (with IP addresses 172.64.146.11 and 104.18.41.245) on port 443:
|
||||
|
||||
```shell
|
||||
curl --verbose "https://customers.gitlab.com/"
|
||||
```
|
||||
|
||||
- If the curl command returns a failure, either:
|
||||
- [Configure a proxy](https://docs.gitlab.com/omnibus/settings/environment-variables.html) in `gitlab.rb` to point to your server.
|
||||
- Contact your network administrator to make changes to the proxy.
|
||||
- If an SSL inspection appliance is used, you must add the appliance's root CA certificate to `/etc/gitlab/trusted-certs` on the server, then run `gitlab-ctl reconfigure`.
|
||||
|
||||
<!-- This redirect file can be deleted after <2023-10-11>. -->
|
||||
<!-- Redirects that point to other docs in the same project expire in three months. -->
|
||||
<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
|
||||
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
|
||||
|
|
|
|||
|
|
@ -1,146 +1,11 @@
|
|||
---
|
||||
stage: Monitor
|
||||
group: Respond
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
redirect_to: '../../../administration/monitoring/health_check.md'
|
||||
remove_date: '2023-10-12'
|
||||
---
|
||||
|
||||
# Health Check **(FREE SELF)**
|
||||
This document was moved to [another location](../../../administration/monitoring/health_check.md).
|
||||
|
||||
GitLab provides liveness and readiness probes to indicate service health and
|
||||
reachability to required services. These probes report on the status of the
|
||||
database connection, Redis connection, and access to the file system. These
|
||||
endpoints [can be provided to schedulers like Kubernetes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) to hold
|
||||
traffic until the system is ready or restart the container as needed.
|
||||
|
||||
## IP allowlist
|
||||
|
||||
To access monitoring resources, the requesting client IP needs to be included in the allowlist.
|
||||
For details, see [how to add IPs to the allowlist for the monitoring endpoints](../../../administration/monitoring/ip_allowlist.md).
|
||||
|
||||
## Using the endpoints locally
|
||||
|
||||
With default allowlist settings, the probes can be accessed from localhost using the following URLs:
|
||||
|
||||
```plaintext
|
||||
GET http://localhost/-/health
|
||||
```
|
||||
|
||||
```plaintext
|
||||
GET http://localhost/-/readiness
|
||||
```
|
||||
|
||||
```plaintext
|
||||
GET http://localhost/-/liveness
|
||||
```
|
||||
|
||||
## Health
|
||||
|
||||
Checks whether the application server is running.
|
||||
It does not verify the database or other services
|
||||
are running. This endpoint circumvents Rails Controllers
|
||||
and is implemented as additional middleware `BasicHealthCheck`
|
||||
very early into the request processing lifecycle.
|
||||
|
||||
```plaintext
|
||||
GET /-/health
|
||||
```
|
||||
|
||||
Example request:
|
||||
|
||||
```shell
|
||||
curl "https://gitlab.example.com/-/health"
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```plaintext
|
||||
GitLab OK
|
||||
```
|
||||
|
||||
## Readiness
|
||||
|
||||
The readiness probe checks whether the GitLab instance is ready
|
||||
to accept traffic via Rails Controllers. The check by default
|
||||
does validate only instance-checks.
|
||||
|
||||
If the `all=1` parameter is specified, the check also validates
|
||||
the dependent services (Database, Redis, Gitaly etc.)
|
||||
and gives a status for each.
|
||||
|
||||
```plaintext
|
||||
GET /-/readiness
|
||||
GET /-/readiness?all=1
|
||||
```
|
||||
|
||||
Example request:
|
||||
|
||||
```shell
|
||||
curl "https://gitlab.example.com/-/readiness"
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
{
|
||||
"master_check":[{
|
||||
"status":"failed",
|
||||
"message": "unexpected Master check result: false"
|
||||
}],
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
On failure, the endpoint returns a `503` HTTP status code.
|
||||
|
||||
This check is being exempt from Rack Attack.
|
||||
|
||||
## Liveness
|
||||
|
||||
WARNING:
|
||||
In GitLab [12.4](https://about.gitlab.com/upcoming-releases/)
|
||||
the response body of the Liveness check was changed
|
||||
to match the example below.
|
||||
|
||||
Checks whether the application server is running.
|
||||
This probe is used to know if Rails Controllers
|
||||
are not deadlocked due to a multi-threading.
|
||||
|
||||
```plaintext
|
||||
GET /-/liveness
|
||||
```
|
||||
|
||||
Example request:
|
||||
|
||||
```shell
|
||||
curl "https://gitlab.example.com/-/liveness"
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
On success, the endpoint returns a `200` HTTP status code, and a response like below.
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "ok"
|
||||
}
|
||||
```
|
||||
|
||||
On failure, the endpoint returns a `503` HTTP status code.
|
||||
|
||||
This check is being exempt from Rack Attack.
|
||||
|
||||
## Sidekiq
|
||||
|
||||
Learn how to configure the [Sidekiq health checks](../../../administration/sidekiq/sidekiq_health_check.md).
|
||||
|
||||
<!-- ## Troubleshooting
|
||||
|
||||
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
|
||||
one might have when setting this up, or when something is changed, or on upgrading, it's
|
||||
important to describe those, too. Think of things that may go wrong and include them here.
|
||||
This is important to minimize requests for support, and to avoid doc comments with
|
||||
questions that you know someone might ask.
|
||||
|
||||
Each scenario can be a third-level heading, for example `### Getting error message X`.
|
||||
If you have none to add when creating a doc, leave this section in place
|
||||
but commented out to help encourage others to add to it in the future. -->
|
||||
<!-- This redirect file can be deleted after <2023-10-12>. -->
|
||||
<!-- Redirects that point to other docs in the same project expire in three months. -->
|
||||
<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
|
||||
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
|
||||
|
|
|
|||
|
|
@ -1,49 +1,11 @@
|
|||
---
|
||||
stage: Anti-Abuse
|
||||
group: Anti-Abuse
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
redirect_to: '../../../administration//reporting/git_abuse_rate_limit.md'
|
||||
remove_date: '2023-10-12'
|
||||
---
|
||||
|
||||
# Git abuse rate limit (administration) **(ULTIMATE SELF)**
|
||||
This document was moved to [another location](../../../administration//reporting/git_abuse_rate_limit.md).
|
||||
|
||||
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/8066) in GitLab 15.2 [with a flag](../../../administration/feature_flags.md) named `git_abuse_rate_limit_feature_flag`. Disabled by default.
|
||||
> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/394996) in GitLab 15.11. Feature flag `git_abuse_rate_limit_feature_flag` removed.
|
||||
|
||||
This is the administration documentation. For information about Git abuse rate limiting at the group level, see the [group-level documentation](../../group/reporting/git_abuse_rate_limit.md).
|
||||
|
||||
Git abuse rate limiting is a feature to automatically [ban users](../moderate_users.md#ban-and-unban-users) who download, clone, or fork more than a specified number of repositories in any project in the instance in a given time frame. Banned users cannot sign in to the instance and cannot access any non-public group via HTTP or SSH. The rate limit also applies to users who authenticate with a [personal](../../../user/profile/personal_access_tokens.md) or [group access token](../../../user/group/settings/group_access_tokens.md).
|
||||
|
||||
Git abuse rate limiting does not apply to instance administrators, [deploy tokens](../../../user/project/deploy_tokens/index.md), or [deploy keys](../../../user/project/deploy_keys/index.md).
|
||||
|
||||
How GitLab determines a user's rate limit is under development.
|
||||
GitLab team members can view more information in this confidential epic:
|
||||
`https://gitlab.com/groups/gitlab-org/modelops/anti-abuse/-/epics/14`.
|
||||
|
||||
## Configure Git abuse rate limiting
|
||||
|
||||
1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
|
||||
1. Select **Admin Area**.
|
||||
1. Select **Settings > Reporting**.
|
||||
1. Expand **Git abuse rate limit**.
|
||||
1. Update the Git abuse rate limit settings:
|
||||
1. Enter a number in the **Number of repositories** field, greater than or equal to `0` and less than or equal to `10,000`. This number specifies the maximum amount of unique repositories a user can download in the specified time period before they're banned. When set to `0`, Git abuse rate limiting is disabled.
|
||||
1. Enter a number in the **Reporting time period (seconds)** field, greater than or equal to `0` and less than or equal to `86,400` (10 days). This number specifies the time in seconds a user can download the maximum amount of repositories before they're banned. When set to `0`, Git abuse rate limiting is disabled.
|
||||
1. Optional. Exclude up to `100` users by adding them to the **Excluded users** field. Excluded users are not automatically banned.
|
||||
1. Add up to `100` users to the **Send notifications to** field. You must select at least one user. All application administrators are selected by default.
|
||||
1. Optional. Turn on the **Automatically ban users from this namespace when they exceed the specified limits** toggle to enable automatic banning.
|
||||
1. Select **Save changes**.
|
||||
|
||||
## Automatic ban notifications
|
||||
|
||||
If automatic banning is disabled, a user is not banned automatically when they exceed the limit. However, notifications are still sent to the users listed under **Send notifications to**. You can use this setup to determine the correct values of the rate limit settings before enabling automatic banning.
|
||||
|
||||
If automatic banning is enabled, an email notification is sent when a user is about to be banned, and the user is automatically banned from the GitLab instance.
|
||||
|
||||
## Unban a user
|
||||
|
||||
1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
|
||||
1. Select **Admin Area**.
|
||||
1. Select **Overview > Users**.
|
||||
1. Select the **Banned** tab and search for the account you want to unban.
|
||||
1. From the **User administration** dropdown list select **Unban user**.
|
||||
1. On the confirmation dialog, select **Unban user**.
|
||||
<!-- This redirect file can be deleted after <2023-10-12>. -->
|
||||
<!-- Redirects that point to other docs in the same project expire in three months. -->
|
||||
<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
|
||||
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
|
||||
|
|
|
|||
|
|
@ -1,37 +1,11 @@
|
|||
---
|
||||
type: reference
|
||||
stage: Data Stores
|
||||
group: Tenant Scale
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
redirect_to: '../../../administration/settings/rate_limit_on_projects_api.md'
|
||||
remove_date: '2023-10-12'
|
||||
---
|
||||
|
||||
# Rate limit on Projects API **(FREE SELF)**
|
||||
This document was moved to [another location](../../../administration/settings/rate_limit_on_projects_api.md).
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/112283) in GitLab 15.10 with a [flag](../../../administration/feature_flags.md) named `rate_limit_for_unauthenticated_projects_api_access`. Disabled by default.
|
||||
> - [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/391922) on May 08, 2023.
|
||||
> - [Enabled on self-managed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/119603) in GitLab 16.0 by default.
|
||||
> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/120445) in GitLab 16.0. Feature flag `rate_limit_for_unauthenticated_projects_api_access` removed.
|
||||
|
||||
You can configure the rate limit per IP address for unauthenticated requests to the [list all projects API](../../../api/projects.md#list-all-projects).
|
||||
|
||||
To change the rate limit:
|
||||
|
||||
1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
|
||||
1. Select **Admin Area**.
|
||||
1. Select **Settings > Network**.
|
||||
1. Expand **Projects API rate limit**.
|
||||
1. In the **Maximum requests per 10 minutes per IP address** text box, enter the new value.
|
||||
1. Select **Save changes**.
|
||||
|
||||
The rate limit:
|
||||
|
||||
- Applies per IP address.
|
||||
- Doesn't apply to authenticated requests.
|
||||
- Can be set to 0 to disable rate limiting.
|
||||
|
||||
The default value of the rate limit is `400`.
|
||||
|
||||
Requests over the rate limit are logged into the `auth.log` file.
|
||||
|
||||
For example, if you set a limit of 400, unauthenticated requests to the `GET /projects` API endpoint that
|
||||
exceed a rate of 400 within 10 minutes are blocked. Access to the endpoint is restored after ten minutes have elapsed.
|
||||
<!-- This redirect file can be deleted after <2023-10-12>. -->
|
||||
<!-- Redirects that point to other docs in the same project expire in three months. -->
|
||||
<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
|
||||
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
|
||||
|
|
|
|||
|
|
@ -1,34 +1,11 @@
|
|||
---
|
||||
type: reference
|
||||
stage: Manage
|
||||
group: Authentication and Authorization
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
redirect_to: '../../../administration/settings/rate_limit_on_users_api.md'
|
||||
remove_date: '2023-10-12'
|
||||
---
|
||||
|
||||
# Rate limits on Users API **(FREE SELF)**
|
||||
This document was moved to [another location](../../../administration/settings/rate_limit_on_users_api.md).
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78364) in GitLab 14.8.
|
||||
|
||||
You can configure the per user rate limit for requests to [Users API](../../../api/users.md).
|
||||
|
||||
To change the rate limit:
|
||||
|
||||
1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
|
||||
1. Select **Admin Area**.
|
||||
1. Select **Settings > Network**.
|
||||
1. Expand **Users API rate limit**.
|
||||
1. In the **Maximum requests per 10 minutes** text box, enter the new value.
|
||||
1. Optional. In the **Users to exclude from the rate limit** box, list users allowed to exceed the limit.
|
||||
1. Select **Save changes**.
|
||||
|
||||
This limit is:
|
||||
|
||||
- Applied independently per user.
|
||||
- Not applied per IP address.
|
||||
|
||||
The default value is `300`.
|
||||
|
||||
Requests over the rate limit are logged into the `auth.log` file.
|
||||
|
||||
For example, if you set a limit of 300, requests to the `GET /users/:id` API endpoint
|
||||
exceeding a rate of 300 per 10 minutes are blocked. Access to the endpoint is allowed after ten minutes have elapsed.
|
||||
<!-- This redirect file can be deleted after <2023-10-12>. -->
|
||||
<!-- Redirects that point to other docs in the same project expire in three months. -->
|
||||
<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
|
||||
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
|
||||
|
|
|
|||
|
|
@ -1,33 +1,11 @@
|
|||
---
|
||||
stage: Create
|
||||
group: Source Code
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
type: reference
|
||||
redirect_to: '../../../administration/settings/rate_limits_on_git_ssh_operations.md'
|
||||
remove_date: '2023-10-12'
|
||||
---
|
||||
|
||||
# Rate limits on Git SSH operations **(FREE SELF)**
|
||||
This document was moved to [another location](../../../administration/settings/rate_limits_on_git_ssh_operations.md).
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78373) in GitLab 14.7 [with a flag](../../../administration/feature_flags.md) named `rate_limit_gitlab_shell`. Available by default without a feature flag from 15.8.
|
||||
|
||||
GitLab applies rate limits to Git operations that use SSH by user account and project. When the rate limit is exceeded, GitLab rejects
|
||||
further connection requests from that user for the project.
|
||||
|
||||
The rate limit applies at the Git command ([plumbing](https://git-scm.com/book/en/v2/Git-Internals-Plumbing-and-Porcelain)) level.
|
||||
Each command has a rate limit of 600 per minute. For example:
|
||||
|
||||
- `git push` has a rate limit of 600 per minute.
|
||||
- `git pull` has its own rate limit of 600 per minute.
|
||||
|
||||
Because the same commands are shared by `git-upload-pack`, `git pull`, and `git clone`, they share a rate limit.
|
||||
|
||||
Users on self-managed GitLab can disable this rate limit.
|
||||
|
||||
## Configure GitLab Shell operation limit
|
||||
|
||||
`Git operations using SSH` is enabled by default. Defaults to 600 per user per minute.
|
||||
|
||||
1. On the left sidebar, select **Your work > Admin Area**.
|
||||
1. On the left sidebar, select **Settings > Network**.
|
||||
1. Expand **Git SSH operations rate limit**.
|
||||
1. Enter a value for **Maximum number of Git operations per minute**.
|
||||
1. Select **Save changes**.
|
||||
<!-- This redirect file can be deleted after <2023-10-12>. -->
|
||||
<!-- Redirects that point to other docs in the same project expire in three months. -->
|
||||
<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
|
||||
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
|
||||
|
|
|
|||
|
|
@ -1,29 +1,11 @@
|
|||
---
|
||||
stage: none
|
||||
group: unassigned
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
type: reference
|
||||
redirect_to: '../../../administration/settings/rate_limits_on_raw_endpoints.md'
|
||||
remove_date: '2023-10-12'
|
||||
---
|
||||
|
||||
# Rate limits on raw endpoints **(FREE SELF)**
|
||||
This document was moved to [another location](../../../administration/settings/rate_limits_on_raw_endpoints.md).
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/30635) in GitLab 12.2.
|
||||
|
||||
This setting defaults to `300` requests per minute, and allows you to rate limit the requests to raw endpoints:
|
||||
|
||||
1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
|
||||
1. Select **Admin Area**.
|
||||
1. Select **Settings > Network**.
|
||||
1. Expand **Performance optimization**.
|
||||
|
||||
For example, requests over `300` per minute to `https://gitlab.com/gitlab-org/gitlab-foss/raw/master/app/controllers/application_controller.rb` are blocked. Access to the raw file is released after 1 minute.
|
||||
|
||||

|
||||
|
||||
This limit is:
|
||||
|
||||
- Applied independently per project, per file path.
|
||||
- Not applied per IP address.
|
||||
- Active by default. To disable, set the option to `0`.
|
||||
|
||||
Requests over the rate limit are logged into `auth.log`.
|
||||
<!-- This redirect file can be deleted after <2023-10-12>. -->
|
||||
<!-- Redirects that point to other docs in the same project expire in three months. -->
|
||||
<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
|
||||
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
|
||||
|
|
|
|||
|
|
@ -1,43 +1,11 @@
|
|||
---
|
||||
type: reference, howto
|
||||
stage: Manage
|
||||
group: Authentication and Authorization
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
redirect_to: '../../../administration/settings/scim_setup.md'
|
||||
remove_date: '2023-10-12'
|
||||
---
|
||||
|
||||
# Configure SCIM for self-managed GitLab instances **(PREMIUM SELF)**
|
||||
This document was moved to [another location](../../../administration/settings/scim_setup.md).
|
||||
|
||||
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/8902) in GitLab 15.8.
|
||||
|
||||
You can use the open standard System for Cross-domain Identity Management (SCIM) to automatically:
|
||||
|
||||
- Create users.
|
||||
- Block users.
|
||||
|
||||
The [internal GitLab SCIM API](../../../development/internal_api/index.md#instance-scim-api) implements part of [the RFC7644 protocol](https://www.rfc-editor.org/rfc/rfc7644).
|
||||
|
||||
If you are a GitLab.com user, see [configuring SCIM for GitLab.com groups](../../../user/group/saml_sso/scim_setup.md).
|
||||
|
||||
## Configure GitLab
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- Configure [SAML single sign-on](../../../integration/saml.md).
|
||||
|
||||
To configure GitLab SCIM:
|
||||
|
||||
1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
|
||||
1. Select **Admin Area**.
|
||||
1. Select **Settings > General**.
|
||||
1. Expand the **SCIM Token** section and select **Generate a SCIM token**.
|
||||
1. For configuration of your identity provider, save the:
|
||||
- Token from the **Your SCIM token** field.
|
||||
- URL from the **SCIM API endpoint URL** field.
|
||||
|
||||
## Remove access
|
||||
|
||||
Removing or deactivating a user on the identity provider blocks the user on
|
||||
the GitLab instance, while the SCIM identity remains linked to the GitLab user.
|
||||
|
||||
To update the user SCIM identity, use the
|
||||
[internal GitLab SCIM API](../../../development/internal_api/index.md#update-a-single-scim-provisioned-user-1).
|
||||
<!-- This redirect file can be deleted after <2023-10-12>. -->
|
||||
<!-- Redirects that point to other docs in the same project expire in three months. -->
|
||||
<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
|
||||
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ In your Okta SCIM application, check that the SCIM **Base URL** is correct and p
|
|||
SCIM API endpoint URL. Check the following documentation to find information on this URL for:
|
||||
|
||||
- [GitLab.com groups](scim_setup.md#configure-gitlab).
|
||||
- [Self-managed GitLab instances](../../admin_area/settings/scim_setup.md#configure-gitlab).
|
||||
- [Self-managed GitLab instances](../../../administration/settings/scim_setup.md#configure-gitlab).
|
||||
|
||||
For self-managed GitLab instances, ensure that GitLab is publicly available so Okta can connect to it. If needed,
|
||||
you can [allow access to Okta IP addresses](https://help.okta.com/en-us/Content/Topics/Security/ip-address-allow-listing.htm)
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ Prerequisites:
|
|||
|
||||
- You need to [authenticate with the API](../../../api/rest/index.md#authentication). If authenticating with a personal access token, it must be configured with the `read_api` scope.
|
||||
|
||||
Authentication tokens (Job Token or Personal Access Token) can be provided for `terraform` in your `~/.terraformrc` file:
|
||||
Authentication tokens (Job Token or Personal Access Token) can be provided for `terraform` in your `~/.terraformrc` or `%APPDATA%/terraform.rc` file:
|
||||
|
||||
```terraform
|
||||
credentials "gitlab.com" {
|
||||
|
|
|
|||
|
|
@ -406,12 +406,20 @@ module Gitlab
|
|||
return [] if newrevs.empty?
|
||||
|
||||
newrevs = newrevs.uniq.sort
|
||||
if Feature.enabled?(:fix_new_blobs_memoization, container)
|
||||
@new_blobs ||= {}
|
||||
@new_blobs[newrevs] ||= blobs(
|
||||
['--not', '--all', '--not'] + newrevs,
|
||||
with_paths: true,
|
||||
dynamic_timeout: dynamic_timeout
|
||||
).to_a
|
||||
else
|
||||
@new_blobs ||= Hash.new do |h, revs|
|
||||
h[revs] = blobs(['--not', '--all', '--not'] + newrevs, with_paths: true, dynamic_timeout: dynamic_timeout)
|
||||
end
|
||||
|
||||
@new_blobs ||= Hash.new do |h, revs|
|
||||
h[revs] = blobs(['--not', '--all', '--not'] + newrevs, with_paths: true, dynamic_timeout: dynamic_timeout)
|
||||
@new_blobs[newrevs]
|
||||
end
|
||||
|
||||
@new_blobs[newrevs]
|
||||
end
|
||||
|
||||
# List blobs reachable via a set of revisions. Supports the
|
||||
|
|
|
|||
|
|
@ -67,11 +67,7 @@ module Gitlab
|
|||
.select(finder_strategy.final_projections)
|
||||
.where("count <> 0") # filter out the initializer row
|
||||
|
||||
if Feature.enabled?(:key_set_optimizer_ignored_columns)
|
||||
model.select(Arel.star).from(q.arel.as(table_name))
|
||||
else
|
||||
model.from(q.arel.as(table_name))
|
||||
end
|
||||
model.select(Arel.star).from(q.arel.as(table_name))
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def final_projections
|
||||
if @model.default_select_columns.is_a?(Array) && Feature.enabled?(:key_set_optimizer_ignored_columns)
|
||||
if @model.default_select_columns.is_a?(Array)
|
||||
@model.default_select_columns.map { |column| "(#{RECORDS_COLUMN}).#{column.name}" }
|
||||
else
|
||||
["(#{RECORDS_COLUMN}).*"]
|
||||
|
|
|
|||
|
|
@ -247,11 +247,7 @@ module Gitlab
|
|||
scope.dup.where(where_value).reorder(self) # rubocop: disable CodeReuse/ActiveRecord
|
||||
end
|
||||
|
||||
if Feature.enabled?(:key_set_optimizer_ignored_columns)
|
||||
scope.model.select(scope.select_values).from_union(scopes, remove_duplicates: false, remove_order: false)
|
||||
else
|
||||
scope.model.from_union(scopes, remove_duplicates: false, remove_order: false)
|
||||
end
|
||||
scope.model.select(scope.select_values).from_union(scopes, remove_duplicates: false, remove_order: false)
|
||||
end
|
||||
|
||||
def to_sql_literal(column_definitions)
|
||||
|
|
|
|||
|
|
@ -1920,6 +1920,12 @@ msgstr ""
|
|||
msgid "AI|Code Explanation"
|
||||
msgstr ""
|
||||
|
||||
msgid "AI|Creates issue description based on a short prompt"
|
||||
msgstr ""
|
||||
|
||||
msgid "AI|Description is required"
|
||||
msgstr ""
|
||||
|
||||
msgid "AI|Enabling these features is your acceptance of the %{link_start}GitLab Testing Agreement%{link_end}."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -1938,6 +1944,9 @@ msgstr ""
|
|||
msgid "AI|For example: Organizations should be able to forecast into the future by using value stream analytics charts. This feature would help them understand how their metrics are trending."
|
||||
msgstr ""
|
||||
|
||||
msgid "AI|Generate issue description"
|
||||
msgstr ""
|
||||
|
||||
msgid "AI|Helpful"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -21856,6 +21865,9 @@ msgstr ""
|
|||
msgid "GroupSaml|Your SCIM token"
|
||||
msgstr ""
|
||||
|
||||
msgid "GroupSelect|An error occurred fetching the groups. Please refresh the page to try again."
|
||||
msgstr ""
|
||||
|
||||
msgid "GroupSelect|No matching results"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -23041,6 +23053,9 @@ msgstr ""
|
|||
msgid "IdentityVerification|You've reached the maximum amount of resends. Wait %{interval} and try again."
|
||||
msgstr ""
|
||||
|
||||
msgid "IdentityVerification|You've reached the maximum amount of tries. Wait %{interval} and try again."
|
||||
msgstr ""
|
||||
|
||||
msgid "IdentityVerification|You've reached the maximum amount of tries. Wait %{interval} or send a new code and try again."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -46574,9 +46589,6 @@ msgstr ""
|
|||
msgid "There was a problem updating the keep latest artifacts setting."
|
||||
msgstr ""
|
||||
|
||||
msgid "There was a problem with the credit card details you entered. Use a different credit card and try again."
|
||||
msgstr ""
|
||||
|
||||
msgid "There was an error creating the dashboard, branch name is invalid."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@
|
|||
"@gitlab/cluster-client": "^1.2.0",
|
||||
"@gitlab/favicon-overlay": "2.0.0",
|
||||
"@gitlab/fonts": "^1.3.0",
|
||||
"@gitlab/svgs": "3.54.0",
|
||||
"@gitlab/svgs": "3.55.0",
|
||||
"@gitlab/ui": "64.19.0",
|
||||
"@gitlab/visual-review-tools": "1.7.3",
|
||||
"@gitlab/web-ide": "0.0.1-dev-20230620122149",
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ module RuboCop
|
|||
METHOD_NAME_PATTERN = /\A([a-z_]+_)?namespace_project(?:_[a-z_]+)?_(?:url|path)\z/.freeze
|
||||
|
||||
def on_send(node)
|
||||
return unless method_name(node).to_s =~ METHOD_NAME_PATTERN
|
||||
return unless METHOD_NAME_PATTERN.match?(method_name(node).to_s)
|
||||
|
||||
namespace_expr, project_expr = arguments(node)
|
||||
return unless namespace_expr && project_expr
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ module RuboCop
|
|||
return if in_qa_file?(node)
|
||||
return unless in_spec?(node)
|
||||
|
||||
add_offense(node, message: MESSAGE % node.value) if SELECTORS =~ node.value
|
||||
add_offense(node, message: MESSAGE % node.value) if SELECTORS.match?(node.value)
|
||||
rescue StandardError
|
||||
# catch all errors and ignore them.
|
||||
# without this catch-all rescue, rubocop will fail
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ export const mockFrequentGroups = [
|
|||
},
|
||||
];
|
||||
|
||||
export const mockSearchedGroups = [mockRawGroup];
|
||||
export const mockSearchedGroups = { data: [mockRawGroup] };
|
||||
export const mockProcessedSearchedGroups = [mockGroup];
|
||||
|
||||
export const mockProject = {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,14 @@ jest.mock('~/api/groups_api');
|
|||
const group1 = { id: 1, full_name: 'Group One', avatar_url: 'test' };
|
||||
const group2 = { id: 2, full_name: 'Group Two', avatar_url: 'test' };
|
||||
const allGroups = [group1, group2];
|
||||
const headers = {
|
||||
'X-Next-Page': 2,
|
||||
'X-Page': 1,
|
||||
'X-Per-Page': 20,
|
||||
'X-Prev-Page': '',
|
||||
'X-Total': 40,
|
||||
'X-Total-Pages': 2,
|
||||
};
|
||||
|
||||
describe('GroupSelect', () => {
|
||||
let wrapper;
|
||||
|
|
@ -25,7 +33,7 @@ describe('GroupSelect', () => {
|
|||
};
|
||||
|
||||
beforeEach(() => {
|
||||
getGroups.mockResolvedValueOnce(allGroups);
|
||||
getGroups.mockResolvedValueOnce({ data: allGroups, headers });
|
||||
});
|
||||
|
||||
const findListbox = () => wrapper.findComponent(GlCollapsibleListbox);
|
||||
|
|
@ -121,4 +129,60 @@ describe('GroupSelect', () => {
|
|||
expect(findListboxToggle().text()).toBe(group1.full_name);
|
||||
});
|
||||
});
|
||||
|
||||
describe('infinite scroll', () => {
|
||||
it('sets infinite scroll related props', async () => {
|
||||
createComponent();
|
||||
await waitForPromises();
|
||||
|
||||
expect(findListbox().props()).toMatchObject({
|
||||
infiniteScroll: true,
|
||||
infiniteScrollLoading: false,
|
||||
totalItems: 40,
|
||||
});
|
||||
});
|
||||
|
||||
describe('when `bottom-reached` event is fired', () => {
|
||||
it('indicates new groups are loading and adds them to the listbox', async () => {
|
||||
createComponent();
|
||||
await waitForPromises();
|
||||
|
||||
const infiniteScrollGroup = {
|
||||
id: 3,
|
||||
full_name: 'Infinite scroll group',
|
||||
avatar_url: 'test',
|
||||
};
|
||||
|
||||
getGroups.mockResolvedValueOnce({ data: [infiniteScrollGroup], headers });
|
||||
|
||||
findListbox().vm.$emit('bottom-reached');
|
||||
await nextTick();
|
||||
|
||||
expect(findListbox().props('infiniteScrollLoading')).toBe(true);
|
||||
|
||||
await waitForPromises();
|
||||
|
||||
expect(findListbox().props('items')[2]).toMatchObject({
|
||||
value: infiniteScrollGroup.id,
|
||||
id: infiniteScrollGroup.id,
|
||||
name: infiniteScrollGroup.full_name,
|
||||
avatarUrl: infiniteScrollGroup.avatar_url,
|
||||
});
|
||||
});
|
||||
|
||||
describe('when API request fails', () => {
|
||||
it('emits `error` event', async () => {
|
||||
createComponent();
|
||||
await waitForPromises();
|
||||
|
||||
getGroups.mockRejectedValueOnce();
|
||||
|
||||
findListbox().vm.$emit('bottom-reached');
|
||||
await waitForPromises();
|
||||
|
||||
expect(wrapper.emitted('error')).toEqual([[GroupSelect.i18n.errorMessage]]);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { GlModal, GlSprintf } from '@gitlab/ui';
|
||||
import { GlModal, GlSprintf, GlAlert } from '@gitlab/ui';
|
||||
import { nextTick } from 'vue';
|
||||
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import Api from '~/api';
|
||||
|
|
@ -250,4 +250,15 @@ describe('InviteGroupsModal', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when group select emits an error event', () => {
|
||||
it('displays error alert', async () => {
|
||||
createComponent();
|
||||
|
||||
findGroupSelect().vm.$emit('error', GroupSelect.i18n.errorMessage);
|
||||
await nextTick();
|
||||
|
||||
expect(wrapper.findComponent(GlAlert).text()).toBe(GroupSelect.i18n.errorMessage);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
import { GlDropdown, GlDropdownItem, GlSprintf } from '@gitlab/ui';
|
||||
import {
|
||||
GlDisclosureDropdown,
|
||||
GlDisclosureDropdownItem,
|
||||
GlDisclosureDropdownGroup,
|
||||
GlSprintf,
|
||||
} from '@gitlab/ui';
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
import PipelineArtifacts from '~/pipelines/components/pipelines_list/pipelines_artifacts.vue';
|
||||
|
||||
|
|
@ -25,25 +30,27 @@ describe('Pipelines Artifacts dropdown', () => {
|
|||
},
|
||||
stubs: {
|
||||
GlSprintf,
|
||||
GlDisclosureDropdown,
|
||||
GlDisclosureDropdownItem,
|
||||
GlDisclosureDropdownGroup,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const findDropdown = () => wrapper.findComponent(GlDropdown);
|
||||
const findFirstGlDropdownItem = () => wrapper.findComponent(GlDropdownItem);
|
||||
const findAllGlDropdownItems = () =>
|
||||
wrapper.findComponent(GlDropdown).findAllComponents(GlDropdownItem);
|
||||
const findGlDropdown = () => wrapper.findComponent(GlDisclosureDropdown);
|
||||
const findFirstGlDropdownItem = () => wrapper.findComponent(GlDisclosureDropdownItem);
|
||||
|
||||
it('should render a dropdown with all the provided artifacts', () => {
|
||||
createComponent();
|
||||
|
||||
expect(findAllGlDropdownItems()).toHaveLength(artifacts.length);
|
||||
const [{ items }] = findGlDropdown().props('items');
|
||||
expect(items).toHaveLength(artifacts.length);
|
||||
});
|
||||
|
||||
it('should render a link with the provided path', () => {
|
||||
createComponent();
|
||||
|
||||
expect(findFirstGlDropdownItem().attributes('href')).toBe(artifacts[0].path);
|
||||
expect(findFirstGlDropdownItem().props('item').href).toBe(artifacts[0].path);
|
||||
expect(findFirstGlDropdownItem().text()).toBe(artifacts[0].name);
|
||||
});
|
||||
|
||||
|
|
@ -51,7 +58,7 @@ describe('Pipelines Artifacts dropdown', () => {
|
|||
it('should not render the dropdown', () => {
|
||||
createComponent({ mockArtifacts: [] });
|
||||
|
||||
expect(findDropdown().exists()).toBe(false);
|
||||
expect(findGlDropdown().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -5,10 +5,11 @@ import {
|
|||
GlSkeletonLoader,
|
||||
GlButton,
|
||||
GlEmptyState,
|
||||
GlIntersectionObserver,
|
||||
} from '@gitlab/ui';
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
import Vue, { nextTick } from 'vue';
|
||||
import VueApollo from 'vue-apollo';
|
||||
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import { isLoggedIn } from '~/lib/utils/common_utils';
|
||||
import createMockApollo from 'helpers/mock_apollo_helper';
|
||||
import waitForPromises from 'helpers/wait_for_promises';
|
||||
|
|
@ -67,15 +68,20 @@ describe('WorkItemDetail component', () => {
|
|||
const findCreatedUpdated = () => wrapper.findComponent(WorkItemCreatedUpdated);
|
||||
const findWorkItemDescription = () => wrapper.findComponent(WorkItemDescription);
|
||||
const findWorkItemAttributesWrapper = () => wrapper.findComponent(WorkItemAttributesWrapper);
|
||||
const findParent = () => wrapper.find('[data-testid="work-item-parent"]');
|
||||
const findParent = () => wrapper.findByTestId('work-item-parent');
|
||||
const findParentButton = () => findParent().findComponent(GlButton);
|
||||
const findCloseButton = () => wrapper.find('[data-testid="work-item-close"]');
|
||||
const findWorkItemType = () => wrapper.find('[data-testid="work-item-type"]');
|
||||
const findCloseButton = () => wrapper.findByTestId('work-item-close');
|
||||
const findWorkItemType = () => wrapper.findByTestId('work-item-type');
|
||||
const findHierarchyTree = () => wrapper.findComponent(WorkItemTree);
|
||||
const findNotesWidget = () => wrapper.findComponent(WorkItemNotes);
|
||||
const findModal = () => wrapper.findComponent(WorkItemDetailModal);
|
||||
const findAbuseCategorySelector = () => wrapper.findComponent(AbuseCategorySelector);
|
||||
const findWorkItemTodos = () => wrapper.findComponent(WorkItemTodos);
|
||||
const findIntersectionObserver = () => wrapper.findComponent(GlIntersectionObserver);
|
||||
const findStickyHeader = () => wrapper.findByTestId('work-item-sticky-header');
|
||||
const findWorkItemTwoColumnViewContainer = () => wrapper.findByTestId('work-item-overview');
|
||||
const findRightSidebar = () => wrapper.findByTestId('work-item-overview-right-sidebar');
|
||||
const triggerPageScroll = () => findIntersectionObserver().vm.$emit('disappear');
|
||||
|
||||
const createComponent = ({
|
||||
isModal = false,
|
||||
|
|
@ -92,7 +98,7 @@ describe('WorkItemDetail component', () => {
|
|||
confidentialityMock,
|
||||
];
|
||||
|
||||
wrapper = shallowMount(WorkItemDetail, {
|
||||
wrapper = shallowMountExtended(WorkItemDetail, {
|
||||
apolloProvider: createMockApollo(handlers),
|
||||
isLoggedIn: isLoggedIn(),
|
||||
propsData: {
|
||||
|
|
@ -646,4 +652,56 @@ describe('WorkItemDetail component', () => {
|
|||
expect(findAlert().text()).toBe(updateError);
|
||||
});
|
||||
});
|
||||
|
||||
describe('work item two column view', () => {
|
||||
describe('when `workItemsMvc2Enabled` is false', () => {
|
||||
beforeEach(async () => {
|
||||
createComponent({ workItemsMvc2Enabled: false });
|
||||
await waitForPromises();
|
||||
});
|
||||
|
||||
it('does not have the `work-item-overview` class', () => {
|
||||
expect(findWorkItemTwoColumnViewContainer().classes()).not.toContain('work-item-overview');
|
||||
});
|
||||
|
||||
it('does not have sticky header', () => {
|
||||
expect(findIntersectionObserver().exists()).toBe(false);
|
||||
expect(findStickyHeader().exists()).toBe(false);
|
||||
});
|
||||
|
||||
it('does not have right sidebar', () => {
|
||||
expect(findRightSidebar().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when `workItemsMvc2Enabled` is true', () => {
|
||||
beforeEach(async () => {
|
||||
createComponent({ workItemsMvc2Enabled: true });
|
||||
await waitForPromises();
|
||||
});
|
||||
|
||||
it('has the `work-item-overview` class', () => {
|
||||
expect(findWorkItemTwoColumnViewContainer().classes()).toContain('work-item-overview');
|
||||
});
|
||||
|
||||
it('does not show sticky header by default', () => {
|
||||
expect(findStickyHeader().exists()).toBe(false);
|
||||
});
|
||||
|
||||
it('has the sticky header when the page is scrolled', async () => {
|
||||
expect(findIntersectionObserver().exists()).toBe(true);
|
||||
|
||||
global.pageYOffset = 100;
|
||||
triggerPageScroll();
|
||||
|
||||
await nextTick();
|
||||
|
||||
expect(findStickyHeader().exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('has the right sidebar', () => {
|
||||
expect(findRightSidebar().exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ RSpec.describe Gitlab::Cluster::Mixins::PumaCluster do
|
|||
loop do
|
||||
line = process.readline
|
||||
puts "PUMA_DEBUG: #{line}" if ENV['PUMA_DEBUG']
|
||||
break if line =~ output
|
||||
break if line.match?(output)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1173,7 +1173,50 @@ RSpec.describe Gitlab::Git::Repository, feature_category: :source_code_managemen
|
|||
commit_result.newrev
|
||||
end
|
||||
|
||||
subject { repository.new_blobs(newrevs).to_a }
|
||||
subject { repository.new_blobs(newrevs) }
|
||||
|
||||
describe 'memoization' do
|
||||
context 'when the fix_new_blobs_memoization feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(fix_new_blobs_memoization: false)
|
||||
end
|
||||
|
||||
context 'when called with different revisions' do
|
||||
it 'calls blobs with the same arguments and memoizes the result' do # for documenting bug behaviour
|
||||
expect(repository).to receive(:blobs).twice.with(["--not", "--all", "--not", "revision1"], kind_of(Hash))
|
||||
.and_return(['first_result'], ['second_result'])
|
||||
expect(repository.new_blobs(['revision1'])).to eq(['first_result'])
|
||||
expect(repository.new_blobs(['revision2'])).to eq(['second_result'])
|
||||
expect(repository.new_blobs(['revision1'])).to eq(['first_result'])
|
||||
expect(repository.new_blobs(['revision2'])).to eq(['second_result'])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the fix_new_blobs_memoization feature flag is enabled' do
|
||||
before do
|
||||
allow(repository).to receive(:blobs).once.with(["--not", "--all", "--not", "revision1"], kind_of(Hash))
|
||||
.and_return(['first result'])
|
||||
repository.new_blobs(['revision1'])
|
||||
end
|
||||
|
||||
it 'calls blobs only once' do
|
||||
expect(repository.new_blobs(['revision1'])).to eq(['first result'])
|
||||
end
|
||||
|
||||
context 'when called with a different revision' do
|
||||
before do
|
||||
allow(repository).to receive(:blobs).once.with(["--not", "--all", "--not", "revision2"], kind_of(Hash))
|
||||
.and_return(['second result'])
|
||||
repository.new_blobs(['revision2'])
|
||||
end
|
||||
|
||||
it 'memoizes the different arguments' do
|
||||
expect(repository.new_blobs(['revision2'])).to eq(['second result'])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples '#new_blobs with revisions' do
|
||||
before do
|
||||
|
|
@ -1195,7 +1238,9 @@ RSpec.describe Gitlab::Git::Repository, feature_category: :source_code_managemen
|
|||
|
||||
it 'memoizes results' do
|
||||
expect(subject).to match_array(expected_blobs)
|
||||
expect(subject).to match_array(expected_blobs)
|
||||
|
||||
# call subject again
|
||||
expect(repository.new_blobs(newrevs)).to match_array(expected_blobs)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -156,14 +156,6 @@ RSpec.describe Gitlab::Pagination::Keyset::InOperatorOptimization::QueryBuilder
|
|||
let(:batch_size) { 1 }
|
||||
|
||||
it_behaves_like 'correct ordering examples'
|
||||
|
||||
context 'when key_set_optimizer_ignored_columns feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(key_set_optimizer_ignored_columns: false)
|
||||
end
|
||||
|
||||
it_behaves_like 'correct ordering examples'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when iterating records with LIMIT 3' do
|
||||
|
|
|
|||
|
|
@ -83,16 +83,6 @@ RSpec.describe Gitlab::Pagination::Keyset::InOperatorOptimization::Strategies::R
|
|||
model.default_select_columns.map { |column| "(#{described_class::RECORDS_COLUMN}).#{column.name}" }
|
||||
)
|
||||
end
|
||||
|
||||
context 'when the key_set_optimizer_ignored_columns feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(key_set_optimizer_ignored_columns: false)
|
||||
end
|
||||
|
||||
it 'does not specify the selected column names' do
|
||||
expect(strategy.final_projections).to contain_exactly("(#{described_class::RECORDS_COLUMN}).*")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -702,16 +702,6 @@ RSpec.describe Gitlab::Pagination::Keyset::Order do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when key_set_optimizer_ignored_columns feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(key_set_optimizer_ignored_columns: false)
|
||||
end
|
||||
|
||||
it 'returns items in the correct order' do
|
||||
expect(items).to eq(expected_results)
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns items in the correct order' do
|
||||
expect(items).to eq(expected_results)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ RSpec.describe Emails::InProductMarketing do
|
|||
is_expected.to have_body_text(message.subtitle)
|
||||
is_expected.to have_body_text(CGI.unescapeHTML(message.cta_link))
|
||||
|
||||
if track =~ /(create|verify)/
|
||||
if /create|verify/.match?(track)
|
||||
is_expected.to have_body_text(message.invite_text)
|
||||
is_expected.to have_body_text(CGI.unescapeHTML(message.invite_link))
|
||||
else
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ RSpec.configure do |config|
|
|||
|
||||
# Admin controller specs get auto admin mode enabled since they are
|
||||
# protected by the 'EnforcesAdminAuthentication' concern
|
||||
metadata[:enable_admin_mode] = true if location =~ %r{(ee)?/spec/controllers/admin/}
|
||||
metadata[:enable_admin_mode] = true if %r{(ee)?/spec/controllers/admin/}.match?(location)
|
||||
end
|
||||
|
||||
config.define_derived_metadata(file_path: %r{(ee)?/spec/.+_docs\.rb\z}) do |metadata|
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ require 'capybara/rails'
|
|||
require 'capybara/rspec'
|
||||
require 'capybara-screenshot/rspec'
|
||||
require 'selenium-webdriver'
|
||||
require 'gitlab/utils/all'
|
||||
|
||||
# Give CI some extra time
|
||||
timeout = ENV['CI'] || ENV['CI_SERVER'] ? 30 : 10
|
||||
|
|
@ -117,7 +118,7 @@ Capybara.register_driver :firefox do |app|
|
|||
options.add_argument("--window-size=#{CAPYBARA_WINDOW_SIZE.join(',')}")
|
||||
|
||||
# Run headless by default unless WEBDRIVER_HEADLESS specified
|
||||
options.add_argument("--headless") unless ENV['WEBDRIVER_HEADLESS'] =~ /^(false|no|0)$/i
|
||||
options.add_argument("--headless") unless Gitlab::Utils.to_boolean(ENV['WEBDRIVER_HEADLESS'], default: false)
|
||||
|
||||
Capybara::Selenium::Driver.new(
|
||||
app,
|
||||
|
|
|
|||
|
|
@ -523,7 +523,7 @@ module TestEnv
|
|||
|
||||
def component_matches_git_sha?(component_folder, expected_version)
|
||||
# Not a git SHA, so return early
|
||||
return false unless expected_version =~ ::Gitlab::Git::COMMIT_ID
|
||||
return false unless ::Gitlab::Git::COMMIT_ID.match?(expected_version)
|
||||
|
||||
return false unless Dir.exist?(component_folder)
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ RSpec.shared_context 'with integration' do
|
|||
hash.merge!(k => 'key:value')
|
||||
elsif integration == 'packagist' && k == :server
|
||||
hash.merge!(k => 'https://packagist.example.com')
|
||||
elsif k =~ /^(.*_url|url|webhook)/
|
||||
elsif /^(.*_url|url|webhook)/.match?(k)
|
||||
hash.merge!(k => "http://example.com")
|
||||
elsif integration_klass.method_defined?("#{k}?")
|
||||
hash.merge!(k => true)
|
||||
|
|
|
|||
|
|
@ -284,7 +284,7 @@ RSpec.shared_examples 'thread comments for issue, epic and merge request' do |re
|
|||
expect(new_comment).to have_css('.discussion-with-resolve-btn')
|
||||
end
|
||||
|
||||
if resource_name =~ /(issue|merge request)/
|
||||
if /(issue|merge request)/.match?(resource_name)
|
||||
it 'can be replied to' do
|
||||
submit_reply('some text')
|
||||
|
||||
|
|
@ -373,7 +373,7 @@ RSpec.shared_examples 'thread comments for issue, epic and merge request' do |re
|
|||
expect(page).not_to have_selector menu_selector
|
||||
end
|
||||
|
||||
if resource_name =~ /(issue|merge request)/
|
||||
if /(issue|merge request)/.match?(resource_name)
|
||||
it 'updates the close button text' do
|
||||
expect(find(close_selector)).to have_content "Comment & close #{resource_name}"
|
||||
end
|
||||
|
|
@ -402,7 +402,7 @@ RSpec.shared_examples 'thread comments for issue, epic and merge request' do |re
|
|||
end
|
||||
end
|
||||
|
||||
if resource_name =~ /(issue|merge request)/
|
||||
if /(issue|merge request)/.match?(resource_name)
|
||||
describe "on a closed #{resource_name}" do
|
||||
before do
|
||||
find("#{form_selector} .js-note-target-close").click
|
||||
|
|
|
|||
|
|
@ -65,6 +65,11 @@ RSpec.describe Tooling::Danger::ProjectHelper do
|
|||
'config/foo.js' | [:frontend]
|
||||
'config/deep/foo.js' | [:frontend]
|
||||
|
||||
'app/components/pajamas/empty_state_component.html.haml' | [:frontend, :backend]
|
||||
'ee/app/components/pajamas/empty_state_component.html.haml' | [:frontend, :backend]
|
||||
'app/components/diffs/overflow_warning_component.html.haml' | [:frontend, :backend]
|
||||
'app/components/layouts/horizontal_section_component.rb' | [:frontend, :backend]
|
||||
|
||||
'ee/app/assets/foo' | [:frontend]
|
||||
'ee/app/views/foo' | [:frontend, :backend]
|
||||
'ee/spec/frontend/bar' | [:frontend]
|
||||
|
|
@ -112,7 +117,7 @@ RSpec.describe Tooling::Danger::ProjectHelper do
|
|||
|
||||
'scripts/glfm/bar.rb' | [:backend]
|
||||
'scripts/glfm/bar.js' | [:frontend]
|
||||
'scripts/remote_development/run-smoke-test-suite.sh' | [:remote_development]
|
||||
'scripts/remote_development/run-smoke-test-suite.sh' | [:remote_development_be]
|
||||
'scripts/lib/glfm/bar.rb' | [:backend]
|
||||
'scripts/lib/glfm/bar.js' | [:frontend]
|
||||
'scripts/bar.rb' | [:backend, :tooling]
|
||||
|
|
|
|||
|
|
@ -238,7 +238,7 @@ RSpec.describe Quality::TestLevel, feature_category: :tooling do
|
|||
|
||||
it 'ensures all spec/ folders are covered by a test level' do
|
||||
Dir['{,ee/}spec/**/*/'].each do |path|
|
||||
next if path =~ %r{\A(ee/)?spec/(benchmarks|docs_screenshots|fixtures|frontend_integration|support)/}
|
||||
next if %r{\A(ee/)?spec/(benchmarks|docs_screenshots|fixtures|frontend_integration|support)/}.match?(path)
|
||||
|
||||
expect { subject.level_for(path) }.not_to raise_error
|
||||
end
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ module Tooling
|
|||
def metric_scope_affected
|
||||
select_models(helper.modified_files).each_with_object(Hash.new { |h, k| h[k] = [] }) do |file_name, matched_files|
|
||||
helper.changed_lines(file_name).each do |mod_line, _i|
|
||||
next unless mod_line =~ /^\+\s+scope :\w+/
|
||||
next unless /^\+\s+scope :\w+/.match?(mod_line)
|
||||
|
||||
affected_scope = mod_line.match(/:\w+/)
|
||||
next if affected_scope.nil?
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ module Tooling
|
|||
def database_dictionary_files(change_type:)
|
||||
files = helper.public_send("#{change_type}_files") # rubocop:disable GitlabSecurity/PublicSend
|
||||
|
||||
files.filter_map { |path| Found.new(path) if path =~ DICTIONARY_PATH_REGEXP }
|
||||
files.filter_map { |path| Found.new(path) if DICTIONARY_PATH_REGEXP.match?(path) }
|
||||
end
|
||||
|
||||
class Found
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ module Tooling
|
|||
%r{\A((ee|jh)/)?app/assets/} => :frontend,
|
||||
%r{\A((ee|jh)/)?app/views/.*\.svg} => :frontend,
|
||||
%r{\A((ee|jh)/)?app/views/} => [:frontend, :backend],
|
||||
%r{\A((ee|jh)/)?app/components/} => [:frontend, :backend],
|
||||
%r{\A((ee|jh)/)?public/} => :frontend,
|
||||
%r{\A((ee|jh)/)?spec/(javascripts|frontend|frontend_integration)/} => :frontend,
|
||||
%r{\A((ee|jh)/)?spec/contracts/consumer} => :frontend,
|
||||
|
|
@ -115,7 +116,7 @@ module Tooling
|
|||
|
||||
%r{\A((ee|jh)/)?scripts/(lib/)?glfm/.*\.rb} => [:backend],
|
||||
%r{\A((ee|jh)/)?scripts/(lib/)?glfm/.*\.js} => [:frontend],
|
||||
%r{\A((ee|jh)/)?scripts/remote_development/.*} => [:remote_development],
|
||||
%r{\A((ee|jh)/)?scripts/remote_development/.*} => [:remote_development_be],
|
||||
%r{\A((ee|jh)/)?scripts/.*\.rb} => [:backend, :tooling],
|
||||
%r{\A((ee|jh)/)?scripts/.*\.js} => [:frontend, :tooling],
|
||||
%r{\A((ee|jh)/)?scripts/} => :tooling,
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ module Tooling
|
|||
changed_lines = helper.changed_lines(filename)
|
||||
|
||||
changed_lines.each do |changed_line|
|
||||
next unless changed_line =~ RSPEC_TOP_LEVEL_DESCRIBE_REGEX
|
||||
next unless RSPEC_TOP_LEVEL_DESCRIBE_REGEX.match?(changed_line)
|
||||
|
||||
line_number = file_lines.find_index(changed_line.delete_prefix('+'))
|
||||
next unless line_number
|
||||
|
|
|
|||
|
|
@ -1127,10 +1127,10 @@
|
|||
stylelint-declaration-strict-value "1.8.0"
|
||||
stylelint-scss "4.2.0"
|
||||
|
||||
"@gitlab/svgs@3.54.0":
|
||||
version "3.54.0"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-3.54.0.tgz#6002ed7b3c2db832bef34629d6d5677ac36c45d6"
|
||||
integrity sha512-Fvo/0lF/Gx+na21Qg4qr02EsP1OEhVlkuh8ctmHMLu5cr5ho3b/MZYLHLjI8F5FDkTIpennyYuhxqiU8kTVM2Q==
|
||||
"@gitlab/svgs@3.55.0":
|
||||
version "3.55.0"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-3.55.0.tgz#c67c5dddf54c400485762aff6a693e1f5a643739"
|
||||
integrity sha512-1wuXRGhrWKfWXSM9ZI1aRHlZ0wv4X7tJjDil+AQVjPBANB6oBXAPAiga+qkzkBHss7TzyOjY7OytG/9L5weDLg==
|
||||
|
||||
"@gitlab/ui@64.19.0":
|
||||
version "64.19.0"
|
||||
|
|
|
|||
Loading…
Reference in New Issue