Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.rubocop_todo/performance/regexp_match.yml13
-rw-r--r--app/assets/javascripts/api/groups_api.js4
-rw-r--r--app/assets/javascripts/frequent_items/store/mutations.js2
-rw-r--r--app/assets/javascripts/invite_members/components/group_select.vue71
-rw-r--r--app/assets/javascripts/invite_members/components/invite_groups_modal.vue12
-rw-r--r--app/assets/javascripts/issues/show/components/form.vue13
-rw-r--r--app/assets/javascripts/pages/projects/issues/new/index.js2
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/failure_widget/pipeline_failed_jobs_widget.vue7
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/pipelines_artifacts.vue51
-rw-r--r--app/assets/javascripts/work_items/components/item_state.vue4
-rw-r--r--app/assets/javascripts/work_items/components/notes/system_note.vue2
-rw-r--r--app/assets/javascripts/work_items/components/work_item_assignees.vue5
-rw-r--r--app/assets/javascripts/work_items/components/work_item_attributes_wrapper.vue4
-rw-r--r--app/assets/javascripts/work_items/components/work_item_description_rendered.vue2
-rw-r--r--app/assets/javascripts/work_items/components/work_item_detail.vue218
-rw-r--r--app/assets/javascripts/work_items/components/work_item_due_date.vue6
-rw-r--r--app/assets/javascripts/work_items/components/work_item_labels.vue5
-rw-r--r--app/assets/javascripts/work_items/components/work_item_milestone.vue6
-rw-r--r--app/assets/stylesheets/page_bundles/work_items.scss54
-rw-r--r--app/views/projects/jobs/_table.html.haml2
-rw-r--r--app/views/projects/pipeline_schedules/_form.html.haml2
-rw-r--r--config/feature_flags/development/fix_new_blobs_memoization.yml (renamed from config/feature_flags/development/key_set_optimizer_ignored_columns.yml)8
-rw-r--r--danger/roulette/Dangerfile2
-rw-r--r--doc/administration/license.md83
-rw-r--r--doc/administration/load_balancer.md2
-rw-r--r--doc/administration/monitoring/health_check.md146
-rw-r--r--doc/administration/raketasks/maintenance.md2
-rw-r--r--doc/administration/reporting/git_abuse_rate_limit.md49
-rw-r--r--doc/administration/settings/rate_limit_on_projects_api.md37
-rw-r--r--doc/administration/settings/rate_limit_on_users_api.md34
-rw-r--r--doc/administration/settings/rate_limits_on_git_ssh_operations.md33
-rw-r--r--doc/administration/settings/rate_limits_on_raw_endpoints.md29
-rw-r--r--doc/administration/settings/scim_setup.md43
-rw-r--r--doc/index.md2
-rw-r--r--doc/install/next_steps.md2
-rw-r--r--doc/integration/advanced_search/elasticsearch.md2
-rw-r--r--doc/subscriptions/bronze_starter.md2
-rw-r--r--doc/subscriptions/self_managed/index.md6
-rw-r--r--doc/update/index.md7
-rw-r--r--doc/update/package/convert_to_ee.md4
-rw-r--r--doc/user/admin_area/license.md86
-rw-r--r--doc/user/admin_area/monitoring/health_check.md149
-rw-r--r--doc/user/admin_area/reporting/git_abuse_rate_limit.md52
-rw-r--r--doc/user/admin_area/settings/rate_limit_on_projects_api.md40
-rw-r--r--doc/user/admin_area/settings/rate_limit_on_users_api.md37
-rw-r--r--doc/user/admin_area/settings/rate_limits_on_git_ssh_operations.md36
-rw-r--r--doc/user/admin_area/settings/rate_limits_on_raw_endpoints.md32
-rw-r--r--doc/user/admin_area/settings/scim_setup.md46
-rw-r--r--doc/user/group/saml_sso/troubleshooting_scim.md2
-rw-r--r--doc/user/packages/terraform_module_registry/index.md2
-rw-r--r--generator_templates/active_record/migration/create_table_migration.rb.tt (renamed from generator_templates/active_record/migration/create_table_migration.rb)0
-rw-r--r--generator_templates/active_record/migration/migration.rb.tt (renamed from generator_templates/active_record/migration/migration.rb)0
-rw-r--r--generator_templates/post_deployment_migration/post_deployment_migration/migration.rb.tt (renamed from generator_templates/post_deployment_migration/post_deployment_migration/migration.rb)0
-rw-r--r--lib/gitlab/git/repository.rb16
-rw-r--r--lib/gitlab/pagination/keyset/in_operator_optimization/query_builder.rb6
-rw-r--r--lib/gitlab/pagination/keyset/in_operator_optimization/strategies/record_loader_strategy.rb2
-rw-r--r--lib/gitlab/pagination/keyset/order.rb6
-rw-r--r--locale/gitlab.pot18
-rw-r--r--package.json2
-rw-r--r--rubocop/cop/project_path_helper.rb2
-rw-r--r--rubocop/cop/qa/selector_usage.rb2
-rw-r--r--spec/frontend/frequent_items/mock_data.js2
-rw-r--r--spec/frontend/invite_members/components/group_select_spec.js66
-rw-r--r--spec/frontend/invite_members/components/invite_groups_modal_spec.js13
-rw-r--r--spec/frontend/pipelines/pipelines_artifacts_spec.js23
-rw-r--r--spec/frontend/work_items/components/work_item_detail_spec.js68
-rw-r--r--spec/lib/gitlab/cluster/mixins/puma_cluster_spec.rb2
-rw-r--r--spec/lib/gitlab/git/repository_spec.rb49
-rw-r--r--spec/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder_spec.rb8
-rw-r--r--spec/lib/gitlab/pagination/keyset/in_operator_optimization/strategies/record_loader_strategy_spec.rb10
-rw-r--r--spec/lib/gitlab/pagination/keyset/order_spec.rb10
-rw-r--r--spec/mailers/emails/in_product_marketing_spec.rb2
-rw-r--r--spec/spec_helper.rb2
-rw-r--r--spec/support/capybara.rb3
-rw-r--r--spec/support/helpers/test_env.rb2
-rw-r--r--spec/support/shared_contexts/features/integrations/integrations_shared_context.rb2
-rw-r--r--spec/support/shared_examples/features/discussion_comments_shared_example.rb6
-rw-r--r--spec/tooling/danger/project_helper_spec.rb7
-rw-r--r--spec/tooling/quality/test_level_spec.rb2
-rw-r--r--tooling/danger/analytics_instrumentation.rb2
-rw-r--r--tooling/danger/database_dictionary.rb2
-rw-r--r--tooling/danger/project_helper.rb3
-rw-r--r--tooling/danger/specs/feature_category_suggestion.rb2
-rw-r--r--yarn.lock8
84 files changed, 1126 insertions, 682 deletions
diff --git a/.rubocop_todo/performance/regexp_match.yml b/.rubocop_todo/performance/regexp_match.yml
index c1a8036f8d1..888552f876c 100644
--- a/.rubocop_todo/performance/regexp_match.yml
+++ b/.rubocop_todo/performance/regexp_match.yml
@@ -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'
diff --git a/app/assets/javascripts/api/groups_api.js b/app/assets/javascripts/api/groups_api.js
index 1b216e6f721..f9edebb9141 100644
--- a/app/assets/javascripts/api/groups_api.js
+++ b/app/assets/javascripts/api/groups_api.js
@@ -18,10 +18,10 @@ const axiosGet = (url, query, options, callback) => {
...options,
},
})
- .then(({ data }) => {
+ .then(({ data, headers }) => {
callback(data);
- return data;
+ return { data, headers };
});
};
diff --git a/app/assets/javascripts/frequent_items/store/mutations.js b/app/assets/javascripts/frequent_items/store/mutations.js
index 65f54e6ed05..9882bef444a 100644
--- a/app/assets/javascripts/frequent_items/store/mutations.js
+++ b/app/assets/javascripts/frequent_items/store/mutations.js
@@ -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,
diff --git a/app/assets/javascripts/invite_members/components/group_select.vue b/app/assets/javascripts/invite_members/components/group_select.vue
index a9f6ad15b23..1369deae3f9 100644
--- a/app/assets/javascripts/invite_members/components/group_select.vue
+++ b/app/assets/javascripts/invite_members/components/group_select.vue
@@ -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"
>
diff --git a/app/assets/javascripts/invite_members/components/invite_groups_modal.vue b/app/assets/javascripts/invite_members/components/invite_groups_modal.vue
index 51355baef99..91dbd86418c 100644
--- a/app/assets/javascripts/invite_members/components/invite_groups_modal.vue
+++ b/app/assets/javascripts/invite_members/components/invite_groups_modal.vue
@@ -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>
diff --git a/app/assets/javascripts/issues/show/components/form.vue b/app/assets/javascripts/issues/show/components/form.vue
index c9e21b296e4..831248d9603 100644
--- a/app/assets/javascripts/issues/show/components/form.vue
+++ b/app/assets/javascripts/issues/show/components/form.vue
@@ -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
diff --git a/app/assets/javascripts/pages/projects/issues/new/index.js b/app/assets/javascripts/pages/projects/issues/new/index.js
index c5b63b74c35..2911069a967 100644
--- a/app/assets/javascripts/pages/projects/issues/new/index.js
+++ b/app/assets/javascripts/pages/projects/issues/new/index.js
@@ -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();
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/failure_widget/pipeline_failed_jobs_widget.vue b/app/assets/javascripts/pipelines/components/pipelines_list/failure_widget/pipeline_failed_jobs_widget.vue
index 7d4d2e139f0..5e49c05f47d 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/failure_widget/pipeline_failed_jobs_widget.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/failure_widget/pipeline_failed_jobs_widget.vue
@@ -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">
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_artifacts.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_artifacts.vue
index 7d0cea67099..4452db64b0a 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_artifacts.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_artifacts.vue
@@ -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>
diff --git a/app/assets/javascripts/work_items/components/item_state.vue b/app/assets/javascripts/work_items/components/item_state.vue
index 8bb8b6101d4..9053d8972de 100644
--- a/app/assets/javascripts/work_items/components/item_state.vue
+++ b/app/assets/javascripts/work_items/components/item_state.vue
@@ -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"
/>
diff --git a/app/assets/javascripts/work_items/components/notes/system_note.vue b/app/assets/javascripts/work_items/components/notes/system_note.vue
index 1fa217f456e..7903adea9bd 100644
--- a/app/assets/javascripts/work_items/components/notes/system_note.vue
+++ b/app/assets/javascripts/work_items/components/notes/system_note.vue
@@ -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>
&middot;
<gl-button
diff --git a/app/assets/javascripts/work_items/components/work_item_assignees.vue b/app/assets/javascripts/work_items/components/work_item_assignees.vue
index d0d520ae5b1..ad9db1428ec 100644
--- a/app/assets/javascripts/work_items/components/work_item_assignees.vue
+++ b/app/assets/javascripts/work_items/components/work_item_assignees.vue
@@ -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"
diff --git a/app/assets/javascripts/work_items/components/work_item_attributes_wrapper.vue b/app/assets/javascripts/work_items/components/work_item_attributes_wrapper.vue
index 3e82d603c1d..c727075eaac 100644
--- a/app/assets/javascripts/work_items/components/work_item_attributes_wrapper.vue
+++ b/app/assets/javascripts/work_items/components/work_item_attributes_wrapper.vue
@@ -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>
diff --git a/app/assets/javascripts/work_items/components/work_item_description_rendered.vue b/app/assets/javascripts/work_items/components/work_item_description_rendered.vue
index 9a2cdc1c172..07e03eba1d1 100644
--- a/app/assets/javascripts/work_items/components/work_item_description_rendered.vue
+++ b/app/assets/javascripts/work_items/components/work_item_description_rendered.vue
@@ -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
diff --git a/app/assets/javascripts/work_items/components/work_item_detail.vue b/app/assets/javascripts/work_items/components/work_item_detail.vue
index e42e39a92ac..1402b313cee 100644
--- a/app/assets/javascripts/work_items/components/work_item_detail.vue
+++ b/app/assets/javascripts/work_items/components/work_item_detail.vue
@@ -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"
diff --git a/app/assets/javascripts/work_items/components/work_item_due_date.vue b/app/assets/javascripts/work_items/components/work_item_due_date.vue
index 3e546598dc2..b4b3049d669 100644
--- a/app/assets/javascripts/work_items/components/work_item_due_date.vue
+++ b/app/assets/javascripts/work_items/components/work_item_due_date.vue
@@ -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;
diff --git a/app/assets/javascripts/work_items/components/work_item_labels.vue b/app/assets/javascripts/work_items/components/work_item_labels.vue
index 662ba880753..8676456a6a4 100644
--- a/app/assets/javascripts/work_items/components/work_item_labels.vue
+++ b/app/assets/javascripts/work_items/components/work_item_labels.vue
@@ -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"
diff --git a/app/assets/javascripts/work_items/components/work_item_milestone.vue b/app/assets/javascripts/work_items/components/work_item_milestone.vue
index 693397686d0..6cc61ed4756 100644
--- a/app/assets/javascripts/work_items/components/work_item_milestone.vue
+++ b/app/assets/javascripts/work_items/components/work_item_milestone.vue
@@ -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"
diff --git a/app/assets/stylesheets/page_bundles/work_items.scss b/app/assets/stylesheets/page_bundles/work_items.scss
index ecbb872e1df..013aa064c4e 100644
--- a/app/assets/stylesheets/page_bundles/work_items.scss
+++ b/app/assets/stylesheets/page_bundles/work_items.scss
@@ -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%;
+ }
+}
diff --git a/app/views/projects/jobs/_table.html.haml b/app/views/projects/jobs/_table.html.haml
index 954c77a21f3..0bb512b4035 100644
--- a/app/views/projects/jobs/_table.html.haml
+++ b/app/views/projects/jobs/_table.html.haml
@@ -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
diff --git a/app/views/projects/pipeline_schedules/_form.html.haml b/app/views/projects/pipeline_schedules/_form.html.haml
index 235b89b8c5b..df85963218d 100644
--- a/app/views/projects/pipeline_schedules/_form.html.haml
+++ b/app/views/projects/pipeline_schedules/_form.html.haml
@@ -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)
diff --git a/config/feature_flags/development/key_set_optimizer_ignored_columns.yml b/config/feature_flags/development/fix_new_blobs_memoization.yml
index af47a43646e..128dad3a49c 100644
--- a/config/feature_flags/development/key_set_optimizer_ignored_columns.yml
+++ b/config/feature_flags/development/fix_new_blobs_memoization.yml
@@ -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
diff --git a/danger/roulette/Dangerfile b/danger/roulette/Dangerfile
index 945dc4eb507..39b79745ead 100644
--- a/danger/roulette/Dangerfile
+++ b/danger/roulette/Dangerfile
@@ -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)
diff --git a/doc/administration/license.md b/doc/administration/license.md
new file mode 100644
index 00000000000..504143e1744
--- /dev/null
+++ b/doc/administration/license.md
@@ -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`.
+ \ No newline at end of file
diff --git a/doc/administration/load_balancer.md b/doc/administration/load_balancer.md
index e43fe851aa2..a862fd46a3f 100644
--- a/doc/administration/load_balancer.md
+++ b/doc/administration/load_balancer.md
@@ -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.
diff --git a/doc/administration/monitoring/health_check.md b/doc/administration/monitoring/health_check.md
new file mode 100644
index 00000000000..4dbbdf6f3c9
--- /dev/null
+++ b/doc/administration/monitoring/health_check.md
@@ -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. -->
diff --git a/doc/administration/raketasks/maintenance.md b/doc/administration/raketasks/maintenance.md
index d3ea98c13a5..975d80c25ef 100644
--- a/doc/administration/raketasks/maintenance.md
+++ b/doc/administration/raketasks/maintenance.md
@@ -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.
diff --git a/doc/administration/reporting/git_abuse_rate_limit.md b/doc/administration/reporting/git_abuse_rate_limit.md
new file mode 100644
index 00000000000..7bb368efdd1
--- /dev/null
+++ b/doc/administration/reporting/git_abuse_rate_limit.md
@@ -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**.
diff --git a/doc/administration/settings/rate_limit_on_projects_api.md b/doc/administration/settings/rate_limit_on_projects_api.md
new file mode 100644
index 00000000000..2192e4355c0
--- /dev/null
+++ b/doc/administration/settings/rate_limit_on_projects_api.md
@@ -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.
diff --git a/doc/administration/settings/rate_limit_on_users_api.md b/doc/administration/settings/rate_limit_on_users_api.md
new file mode 100644
index 00000000000..9424e508d86
--- /dev/null
+++ b/doc/administration/settings/rate_limit_on_users_api.md
@@ -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.
diff --git a/doc/administration/settings/rate_limits_on_git_ssh_operations.md b/doc/administration/settings/rate_limits_on_git_ssh_operations.md
new file mode 100644
index 00000000000..64acb15b8ac
--- /dev/null
+++ b/doc/administration/settings/rate_limits_on_git_ssh_operations.md
@@ -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**.
diff --git a/doc/administration/settings/rate_limits_on_raw_endpoints.md b/doc/administration/settings/rate_limits_on_raw_endpoints.md
new file mode 100644
index 00000000000..fb1a6347890
--- /dev/null
+++ b/doc/administration/settings/rate_limits_on_raw_endpoints.md
@@ -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.
+
+![Rate limits on raw endpoints](../../user/admin_area/settings/img/rate_limits_on_raw_endpoints.png)
+
+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`.
diff --git a/doc/administration/settings/scim_setup.md b/doc/administration/settings/scim_setup.md
new file mode 100644
index 00000000000..6a02a5b832c
--- /dev/null
+++ b/doc/administration/settings/scim_setup.md
@@ -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).
diff --git a/doc/index.md b/doc/index.md
index 6b0422310da..2c90d2f0970 100644
--- a/doc/index.md
+++ b/doc/index.md
@@ -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. |
diff --git a/doc/install/next_steps.md b/doc/install/next_steps.md
index 2ddc70902b0..ecc456cd3ec 100644
--- a/doc/install/next_steps.md
+++ b/doc/install/next_steps.md
@@ -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.
diff --git a/doc/integration/advanced_search/elasticsearch.md b/doc/integration/advanced_search/elasticsearch.md
index c55ec8b6b83..cdda85bb259 100644
--- a/doc/integration/advanced_search/elasticsearch.md
+++ b/doc/integration/advanced_search/elasticsearch.md
@@ -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**
diff --git a/doc/subscriptions/bronze_starter.md b/doc/subscriptions/bronze_starter.md
index b0115cd7e7e..44e2d6675a7 100644
--- a/doc/subscriptions/bronze_starter.md
+++ b/doc/subscriptions/bronze_starter.md
@@ -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)
diff --git a/doc/subscriptions/self_managed/index.md b/doc/subscriptions/self_managed/index.md
index 60430f87125..86230646c50 100644
--- a/doc/subscriptions/self_managed/index.md
+++ b/doc/subscriptions/self_managed/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.
diff --git a/doc/update/index.md b/doc/update/index.md
index fb303d06eb5..ed3a3f0b338 100644
--- a/doc/update/index.md
+++ b/doc/update/index.md
@@ -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
diff --git a/doc/update/package/convert_to_ee.md b/doc/update/package/convert_to_ee.md
index 950c1b68935..31de896349c 100644
--- a/doc/update/package/convert_to_ee.md
+++ b/doc/update/package/convert_to_ee.md
@@ -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:
diff --git a/doc/user/admin_area/license.md b/doc/user/admin_area/license.md
index 4e003e1f2c8..636f5cb2831 100644
--- a/doc/user/admin_area/license.md
+++ b/doc/user/admin_area/license.md
@@ -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`.
- \ No newline at end of file
+<!-- 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 -->
diff --git a/doc/user/admin_area/monitoring/health_check.md b/doc/user/admin_area/monitoring/health_check.md
index f3b09c61532..bda326d4daf 100644
--- a/doc/user/admin_area/monitoring/health_check.md
+++ b/doc/user/admin_area/monitoring/health_check.md
@@ -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 -->
diff --git a/doc/user/admin_area/reporting/git_abuse_rate_limit.md b/doc/user/admin_area/reporting/git_abuse_rate_limit.md
index 38aaeb8eb55..75e42c09474 100644
--- a/doc/user/admin_area/reporting/git_abuse_rate_limit.md
+++ b/doc/user/admin_area/reporting/git_abuse_rate_limit.md
@@ -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 -->
diff --git a/doc/user/admin_area/settings/rate_limit_on_projects_api.md b/doc/user/admin_area/settings/rate_limit_on_projects_api.md
index 326dd3b4706..12577ba44b1 100644
--- a/doc/user/admin_area/settings/rate_limit_on_projects_api.md
+++ b/doc/user/admin_area/settings/rate_limit_on_projects_api.md
@@ -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 -->
diff --git a/doc/user/admin_area/settings/rate_limit_on_users_api.md b/doc/user/admin_area/settings/rate_limit_on_users_api.md
index 112518131bf..80acbf21023 100644
--- a/doc/user/admin_area/settings/rate_limit_on_users_api.md
+++ b/doc/user/admin_area/settings/rate_limit_on_users_api.md
@@ -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 -->
diff --git a/doc/user/admin_area/settings/rate_limits_on_git_ssh_operations.md b/doc/user/admin_area/settings/rate_limits_on_git_ssh_operations.md
index 7c6a5df6040..b60a78d1f49 100644
--- a/doc/user/admin_area/settings/rate_limits_on_git_ssh_operations.md
+++ b/doc/user/admin_area/settings/rate_limits_on_git_ssh_operations.md
@@ -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 -->
diff --git a/doc/user/admin_area/settings/rate_limits_on_raw_endpoints.md b/doc/user/admin_area/settings/rate_limits_on_raw_endpoints.md
index 78e65f7ba7b..5cfee536a58 100644
--- a/doc/user/admin_area/settings/rate_limits_on_raw_endpoints.md
+++ b/doc/user/admin_area/settings/rate_limits_on_raw_endpoints.md
@@ -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.
-
-![Rate limits on raw endpoints](img/rate_limits_on_raw_endpoints.png)
-
-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 -->
diff --git a/doc/user/admin_area/settings/scim_setup.md b/doc/user/admin_area/settings/scim_setup.md
index 0471dffe442..4ebd8a84f8a 100644
--- a/doc/user/admin_area/settings/scim_setup.md
+++ b/doc/user/admin_area/settings/scim_setup.md
@@ -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 -->
diff --git a/doc/user/group/saml_sso/troubleshooting_scim.md b/doc/user/group/saml_sso/troubleshooting_scim.md
index b592ca31490..e4531882fc1 100644
--- a/doc/user/group/saml_sso/troubleshooting_scim.md
+++ b/doc/user/group/saml_sso/troubleshooting_scim.md
@@ -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)
diff --git a/doc/user/packages/terraform_module_registry/index.md b/doc/user/packages/terraform_module_registry/index.md
index 2f37b75b637..3a3409daa6a 100644
--- a/doc/user/packages/terraform_module_registry/index.md
+++ b/doc/user/packages/terraform_module_registry/index.md
@@ -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" {
diff --git a/generator_templates/active_record/migration/create_table_migration.rb b/generator_templates/active_record/migration/create_table_migration.rb.tt
index 0b0cb05249c..0b0cb05249c 100644
--- a/generator_templates/active_record/migration/create_table_migration.rb
+++ b/generator_templates/active_record/migration/create_table_migration.rb.tt
diff --git a/generator_templates/active_record/migration/migration.rb b/generator_templates/active_record/migration/migration.rb.tt
index 50d2b018ae7..50d2b018ae7 100644
--- a/generator_templates/active_record/migration/migration.rb
+++ b/generator_templates/active_record/migration/migration.rb.tt
diff --git a/generator_templates/post_deployment_migration/post_deployment_migration/migration.rb b/generator_templates/post_deployment_migration/post_deployment_migration/migration.rb.tt
index dcc9d1e4563..dcc9d1e4563 100644
--- a/generator_templates/post_deployment_migration/post_deployment_migration/migration.rb
+++ b/generator_templates/post_deployment_migration/post_deployment_migration/migration.rb.tt
diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb
index cfca4661429..e830fab3623 100644
--- a/lib/gitlab/git/repository.rb
+++ b/lib/gitlab/git/repository.rb
@@ -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
diff --git a/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder.rb b/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder.rb
index 5f4304a7e1b..422839dcde1 100644
--- a/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder.rb
+++ b/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder.rb
@@ -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
diff --git a/lib/gitlab/pagination/keyset/in_operator_optimization/strategies/record_loader_strategy.rb b/lib/gitlab/pagination/keyset/in_operator_optimization/strategies/record_loader_strategy.rb
index d1675a8e916..786ae282c88 100644
--- a/lib/gitlab/pagination/keyset/in_operator_optimization/strategies/record_loader_strategy.rb
+++ b/lib/gitlab/pagination/keyset/in_operator_optimization/strategies/record_loader_strategy.rb
@@ -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}).*"]
diff --git a/lib/gitlab/pagination/keyset/order.rb b/lib/gitlab/pagination/keyset/order.rb
index 482b2977b4b..a7faef2fdad 100644
--- a/lib/gitlab/pagination/keyset/order.rb
+++ b/lib/gitlab/pagination/keyset/order.rb
@@ -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)
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index e43683b4b51..142a9ac129c 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -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 ""
diff --git a/package.json b/package.json
index e114b43ead6..860252ccce3 100644
--- a/package.json
+++ b/package.json
@@ -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",
diff --git a/rubocop/cop/project_path_helper.rb b/rubocop/cop/project_path_helper.rb
index 104a352949f..f053c9a01b7 100644
--- a/rubocop/cop/project_path_helper.rb
+++ b/rubocop/cop/project_path_helper.rb
@@ -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
diff --git a/rubocop/cop/qa/selector_usage.rb b/rubocop/cop/qa/selector_usage.rb
index d615bd2926c..c17f642bd06 100644
--- a/rubocop/cop/qa/selector_usage.rb
+++ b/rubocop/cop/qa/selector_usage.rb
@@ -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
diff --git a/spec/frontend/frequent_items/mock_data.js b/spec/frontend/frequent_items/mock_data.js
index 5e15b4b33e0..6563daee6c3 100644
--- a/spec/frontend/frequent_items/mock_data.js
+++ b/spec/frontend/frequent_items/mock_data.js
@@ -69,7 +69,7 @@ export const mockFrequentGroups = [
},
];
-export const mockSearchedGroups = [mockRawGroup];
+export const mockSearchedGroups = { data: [mockRawGroup] };
export const mockProcessedSearchedGroups = [mockGroup];
export const mockProject = {
diff --git a/spec/frontend/invite_members/components/group_select_spec.js b/spec/frontend/invite_members/components/group_select_spec.js
index 3186e5c6212..bd90832f497 100644
--- a/spec/frontend/invite_members/components/group_select_spec.js
+++ b/spec/frontend/invite_members/components/group_select_spec.js
@@ -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]]);
+ });
+ });
+ });
+ });
});
diff --git a/spec/frontend/invite_members/components/invite_groups_modal_spec.js b/spec/frontend/invite_members/components/invite_groups_modal_spec.js
index 2a3ecd44e7a..4136de75545 100644
--- a/spec/frontend/invite_members/components/invite_groups_modal_spec.js
+++ b/spec/frontend/invite_members/components/invite_groups_modal_spec.js
@@ -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);
+ });
+ });
});
diff --git a/spec/frontend/pipelines/pipelines_artifacts_spec.js b/spec/frontend/pipelines/pipelines_artifacts_spec.js
index 9fedbaf9b56..1abc2887682 100644
--- a/spec/frontend/pipelines/pipelines_artifacts_spec.js
+++ b/spec/frontend/pipelines/pipelines_artifacts_spec.js
@@ -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);
});
});
});
diff --git a/spec/frontend/work_items/components/work_item_detail_spec.js b/spec/frontend/work_items/components/work_item_detail_spec.js
index 14a6ada16bd..7ceae935d2d 100644
--- a/spec/frontend/work_items/components/work_item_detail_spec.js
+++ b/spec/frontend/work_items/components/work_item_detail_spec.js
@@ -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);
+ });
+ });
+ });
});
diff --git a/spec/lib/gitlab/cluster/mixins/puma_cluster_spec.rb b/spec/lib/gitlab/cluster/mixins/puma_cluster_spec.rb
index 05b67a8a93f..cc329c48c5f 100644
--- a/spec/lib/gitlab/cluster/mixins/puma_cluster_spec.rb
+++ b/spec/lib/gitlab/cluster/mixins/puma_cluster_spec.rb
@@ -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
diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb
index 226d91e4a35..feaef8015f2 100644
--- a/spec/lib/gitlab/git/repository_spec.rb
+++ b/spec/lib/gitlab/git/repository_spec.rb
@@ -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
diff --git a/spec/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder_spec.rb b/spec/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder_spec.rb
index 28f6919e6bc..1c67c9e0b95 100644
--- a/spec/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder_spec.rb
+++ b/spec/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder_spec.rb
@@ -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
diff --git a/spec/lib/gitlab/pagination/keyset/in_operator_optimization/strategies/record_loader_strategy_spec.rb b/spec/lib/gitlab/pagination/keyset/in_operator_optimization/strategies/record_loader_strategy_spec.rb
index c20f3c96734..3fe858f33da 100644
--- a/spec/lib/gitlab/pagination/keyset/in_operator_optimization/strategies/record_loader_strategy_spec.rb
+++ b/spec/lib/gitlab/pagination/keyset/in_operator_optimization/strategies/record_loader_strategy_spec.rb
@@ -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
diff --git a/spec/lib/gitlab/pagination/keyset/order_spec.rb b/spec/lib/gitlab/pagination/keyset/order_spec.rb
index a8bdafb1ce8..05bb0bb8b3a 100644
--- a/spec/lib/gitlab/pagination/keyset/order_spec.rb
+++ b/spec/lib/gitlab/pagination/keyset/order_spec.rb
@@ -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
diff --git a/spec/mailers/emails/in_product_marketing_spec.rb b/spec/mailers/emails/in_product_marketing_spec.rb
index 5419c9e6798..2d332dd99d6 100644
--- a/spec/mailers/emails/in_product_marketing_spec.rb
+++ b/spec/mailers/emails/in_product_marketing_spec.rb
@@ -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
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index eb7796cb55a..4d66784d943 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -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|
diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb
index a855e4468ca..392743fda4a 100644
--- a/spec/support/capybara.rb
+++ b/spec/support/capybara.rb
@@ -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,
diff --git a/spec/support/helpers/test_env.rb b/spec/support/helpers/test_env.rb
index da4954c1a5f..b95adb3fe4d 100644
--- a/spec/support/helpers/test_env.rb
+++ b/spec/support/helpers/test_env.rb
@@ -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)
diff --git a/spec/support/shared_contexts/features/integrations/integrations_shared_context.rb b/spec/support/shared_contexts/features/integrations/integrations_shared_context.rb
index 21d9dccbb8d..8c17136b1e2 100644
--- a/spec/support/shared_contexts/features/integrations/integrations_shared_context.rb
+++ b/spec/support/shared_contexts/features/integrations/integrations_shared_context.rb
@@ -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)
diff --git a/spec/support/shared_examples/features/discussion_comments_shared_example.rb b/spec/support/shared_examples/features/discussion_comments_shared_example.rb
index d6f1efc09fc..ac8055138d7 100644
--- a/spec/support/shared_examples/features/discussion_comments_shared_example.rb
+++ b/spec/support/shared_examples/features/discussion_comments_shared_example.rb
@@ -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
diff --git a/spec/tooling/danger/project_helper_spec.rb b/spec/tooling/danger/project_helper_spec.rb
index fb0603a207a..91ba8eebe51 100644
--- a/spec/tooling/danger/project_helper_spec.rb
+++ b/spec/tooling/danger/project_helper_spec.rb
@@ -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]
diff --git a/spec/tooling/quality/test_level_spec.rb b/spec/tooling/quality/test_level_spec.rb
index a7e4e42206a..6ccd2e46f7b 100644
--- a/spec/tooling/quality/test_level_spec.rb
+++ b/spec/tooling/quality/test_level_spec.rb
@@ -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
diff --git a/tooling/danger/analytics_instrumentation.rb b/tooling/danger/analytics_instrumentation.rb
index 767ae8dfb4c..69cc30f51fb 100644
--- a/tooling/danger/analytics_instrumentation.rb
+++ b/tooling/danger/analytics_instrumentation.rb
@@ -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?
diff --git a/tooling/danger/database_dictionary.rb b/tooling/danger/database_dictionary.rb
index 8776532ff84..2ea937efd73 100644
--- a/tooling/danger/database_dictionary.rb
+++ b/tooling/danger/database_dictionary.rb
@@ -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
diff --git a/tooling/danger/project_helper.rb b/tooling/danger/project_helper.rb
index 9ab6c5fa32e..b9da06dd3ba 100644
--- a/tooling/danger/project_helper.rb
+++ b/tooling/danger/project_helper.rb
@@ -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,
diff --git a/tooling/danger/specs/feature_category_suggestion.rb b/tooling/danger/specs/feature_category_suggestion.rb
index 5acf73c8956..00cb99f368b 100644
--- a/tooling/danger/specs/feature_category_suggestion.rb
+++ b/tooling/danger/specs/feature_category_suggestion.rb
@@ -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
diff --git a/yarn.lock b/yarn.lock
index 3e4dbc08868..330ecdfc6b2 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -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"