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--.gitlab-ci.yml1
-rw-r--r--.gitlab/ci/benchmark.gitlab-ci.yml17
-rw-r--r--.gitlab/ci/global.gitlab-ci.yml8
-rw-r--r--.gitlab/ci/rules.gitlab-ci.yml27
-rw-r--r--app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/artifacts_and_cache_item.vue2
-rw-r--r--app/assets/javascripts/error_tracking/components/timeline_chart.vue4
-rw-r--r--app/assets/javascripts/ide/components/ide_status_bar.vue1
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/components/app.vue68
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/components/feedback_banner.vue57
-rw-r--r--app/assets/javascripts/mr_more_dropdown.js4
-rw-r--r--app/assets/javascripts/pages/projects/merge_requests/page.js2
-rw-r--r--app/assets/javascripts/pages/projects/merge_requests/show/index.js4
-rw-r--r--app/assets/javascripts/super_sidebar/components/global_search/command_palette/command_palette_items.vue7
-rw-r--r--app/assets/javascripts/super_sidebar/components/global_search/command_palette/constants.js6
-rw-r--r--app/assets/javascripts/vue_shared/components/ci_icon.vue12
-rw-r--r--app/assets/stylesheets/page_bundles/jira_connect.scss8
-rw-r--r--app/graphql/types/ci/job_type.rb10
-rw-r--r--app/graphql/types/ci/stage_type.rb2
-rw-r--r--app/models/user.rb3
-rw-r--r--app/models/user_preference.rb2
-rw-r--r--app/views/admin/application_settings/_help_page.html.haml2
-rw-r--r--doc/administration/custom_project_templates.md73
-rw-r--r--doc/administration/docs_self_host.md2
-rw-r--r--doc/administration/email_from_gitlab.md61
-rw-r--r--doc/administration/geo/replication/troubleshooting.md4
-rw-r--r--doc/administration/geo_sites.md119
-rw-r--r--doc/administration/img/email1.png (renamed from doc/user/admin_area/img/email1.png)bin9590 -> 9590 bytes
-rw-r--r--doc/administration/img/email2.png (renamed from doc/user/admin_area/img/email2.png)bin14902 -> 14902 bytes
-rw-r--r--doc/administration/settings/help_page.md111
-rw-r--r--doc/administration/settings/incident_management_rate_limits.md39
-rw-r--r--doc/api/cluster_agents.md3
-rw-r--r--doc/ci/environments/deployment_approvals.md2
-rw-r--r--doc/ci/pipelines/index.md2
-rw-r--r--doc/development/product_qualified_lead_guide/index.md8
-rw-r--r--doc/subscriptions/bronze_starter.md2
-rw-r--r--doc/user/admin_area/custom_project_templates.md76
-rw-r--r--doc/user/admin_area/email_from_gitlab.md64
-rw-r--r--doc/user/admin_area/geo_sites.md122
-rw-r--r--doc/user/admin_area/settings/help_page.md114
-rw-r--r--doc/user/admin_area/settings/incident_management_rate_limits.md42
-rw-r--r--doc/user/clusters/agent/work_with_agent.md3
-rw-r--r--doc/user/group/custom_project_templates.md2
-rw-r--r--doc/user/profile/notifications.md4
-rw-r--r--doc/user/project/settings/import_export.md2
-rw-r--r--lib/api/users.rb2
-rw-r--r--locale/gitlab.pot11
-rw-r--r--spec/features/projects/blobs/blob_show_spec.rb2
-rw-r--r--spec/features/projects/pipelines/pipeline_spec.rb14
-rw-r--r--spec/frontend/ci/reports/components/summary_row_spec.js2
-rw-r--r--spec/frontend/ide/components/ide_status_bar_spec.js44
-rw-r--r--spec/frontend/ide/mock_data.js2
-rw-r--r--spec/frontend/jira_connect/subscriptions/components/app_spec.js8
-rw-r--r--spec/frontend/jira_connect/subscriptions/components/feedback_banner_spec.js45
-rw-r--r--spec/frontend/jobs/components/job/job_container_item_spec.js14
-rw-r--r--spec/frontend/vue_merge_request_widget/components/states/mr_widget_failed_to_merge_spec.js19
-rw-r--r--spec/frontend/vue_shared/components/ci_icon_spec.js55
-rw-r--r--spec/models/user_preference_spec.rb10
-rw-r--r--spec/models/user_spec.rb4
-rw-r--r--spec/requests/api/graphql/project/jobs_spec.rb31
-rw-r--r--spec/requests/api/graphql/project/pipeline_spec.rb36
60 files changed, 817 insertions, 584 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 4a017c93c91..8a09f2bcdfc 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -13,6 +13,7 @@ stages:
- pages
- notify
- release-environments
+ - benchmark
# always use `gitlab-org` runners, however
# in cases where jobs require Docker-in-Docker, the job
diff --git a/.gitlab/ci/benchmark.gitlab-ci.yml b/.gitlab/ci/benchmark.gitlab-ci.yml
new file mode 100644
index 00000000000..5949a9cd6a9
--- /dev/null
+++ b/.gitlab/ci/benchmark.gitlab-ci.yml
@@ -0,0 +1,17 @@
+benchmark-markdown:
+ extends:
+ - .single-db-ci-connection
+ - .rails-job-base
+ - .use-pg14
+ - .benchmark:rules:benchmark-markdown
+ stage: benchmark
+ needs:
+ - setup-test-env
+ script:
+ - section_start "gitaly-test-spawn" "Spawning Gitaly"; scripts/gitaly-test-spawn; section_end "gitaly-test-spawn"; # Do not use 'bundle exec' here
+ - bundle exec rake benchmark:banzai &> benchmark-markdown.txt
+ artifacts:
+ when: always
+ paths:
+ - benchmark-markdown.txt
+ allow_failure: true
diff --git a/.gitlab/ci/global.gitlab-ci.yml b/.gitlab/ci/global.gitlab-ci.yml
index 7e0a9c3a21b..cb35d5ff56d 100644
--- a/.gitlab/ci/global.gitlab-ci.yml
+++ b/.gitlab/ci/global.gitlab-ci.yml
@@ -431,7 +431,7 @@
.use-pg14-opensearch1-ee:
services:
- name: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:postgres-14-pgvector-0.4.1
- command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
+ command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off", "-c", "max_locks_per_transaction=128"]
alias: postgres
- name: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:redis-cluster-6.2.12
alias: rediscluster # configure connections in config/redis.yml
@@ -450,7 +450,7 @@
.use-pg14-opensearch2-ee:
services:
- name: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:postgres-14-pgvector-0.4.1
- command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
+ command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off", "-c", "max_locks_per_transaction=128"]
alias: postgres
- name: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:redis-cluster-6.2.12
alias: rediscluster # configure connections in config/redis.yml
@@ -469,7 +469,7 @@
.use-pg15-opensearch1-ee:
services:
- name: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:postgres-15-pgvector-0.4.1
- command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
+ command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off", "-c", "max_locks_per_transaction=128"]
alias: postgres
- name: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:redis-cluster-6.2.12
alias: rediscluster # configure connections in config/redis.yml
@@ -488,7 +488,7 @@
.use-pg15-opensearch2-ee:
services:
- name: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:postgres-15-pgvector-0.4.1
- command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
+ command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off", "-c", "max_locks_per_transaction=128"]
alias: postgres
- name: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:redis-cluster-6.2.12
alias: rediscluster # configure connections in config/redis.yml
diff --git a/.gitlab/ci/rules.gitlab-ci.yml b/.gitlab/ci/rules.gitlab-ci.yml
index 6c190281655..1003989a67a 100644
--- a/.gitlab/ci/rules.gitlab-ci.yml
+++ b/.gitlab/ci/rules.gitlab-ci.yml
@@ -465,7 +465,7 @@
- ".stylelintrc"
- "Dockerfile.assets"
- "vendor/assets/**/*"
- - ".{eslintignore,gitattributes,nvmrc,prettierrc,stylelintrc,yamllint}"
+ - ".{eslintrc.yml,eslintignore,gitattributes,nvmrc,prettierrc,stylelintrc,yamllint}"
- "*_VERSION"
- "{,jh/}Gemfile{,.lock}"
- "Rakefile"
@@ -492,7 +492,7 @@
- ".stylelintrc"
- "Dockerfile.assets"
- "vendor/assets/**/*"
- - ".{eslintignore,gitattributes,nvmrc,prettierrc,stylelintrc,yamllint}"
+ - ".{eslintrc.yml,eslintignore,gitattributes,nvmrc,prettierrc,stylelintrc,yamllint}"
- ".gitlab-ci.yml"
- "*_VERSION"
- "{,jh/}Gemfile{,.lock}"
@@ -1152,17 +1152,9 @@
changes: *workhorse-patterns
# Rules to support .qa:rules:package-and-test
- <<: *if-default-branch-schedule-nightly
- - <<: *if-merge-request
- changes: *dependency-patterns
- <<: *if-merge-request-labels-run-all-e2e
- <<: *if-dot-com-gitlab-org-and-security-merge-request-manual-ff-package-and-e2e
changes: *feature-flag-development-config-patterns
- - <<: *if-merge-request
- changes: *feature-flag-development-config-patterns
- - <<: *if-merge-request
- changes: *nodejs-patterns
- - <<: *if-merge-request
- changes: *ci-qa-patterns
- <<: *if-force-ci
.frontend:rules:compile-production-assets-as-if-foss:
@@ -2473,9 +2465,9 @@
- ".gitlab/ci/test-metadata.gitlab-ci.yml"
- "scripts/rspec_helpers.sh"
-#######################
+###################
# Preflight rules #
-#######################
+###################
.preflight:rules:rails-production-server-boot:
rules:
@@ -2605,3 +2597,14 @@
- <<: *if-merge-request-labels-pipeline-expedite
when: never
- !reference [".releases:rules:canonical-dot-com-gitlab-stable-branch-only-setup-test-env-patterns", rules]
+
+###################
+# Benchmark rules #
+###################
+.benchmark:rules:benchmark-markdown:
+ rules:
+ - <<: *if-default-refs
+ changes: *setup-test-env-patterns
+ when: manual
+ - <<: *if-merge-request-labels-run-all-rspec
+ when: manual
diff --git a/app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/artifacts_and_cache_item.vue b/app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/artifacts_and_cache_item.vue
index 794763e0cd8..76db9613dc1 100644
--- a/app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/artifacts_and_cache_item.vue
+++ b/app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/artifacts_and_cache_item.vue
@@ -26,7 +26,7 @@ export default {
return [
{
key: 'artifacts.paths',
- title: i18n.ARTIFACTS_AND_CACHE,
+ title: i18n.ARTIFACTS_PATHS,
paths: this.job.artifacts.paths,
generateInputDataTestId: (index) => `artifacts-paths-input-${index}`,
generateDeleteButtonDataTestId: (index) => `delete-artifacts-paths-button-${index}`,
diff --git a/app/assets/javascripts/error_tracking/components/timeline_chart.vue b/app/assets/javascripts/error_tracking/components/timeline_chart.vue
index 51e0c900e4b..907a6c8557f 100644
--- a/app/assets/javascripts/error_tracking/components/timeline_chart.vue
+++ b/app/assets/javascripts/error_tracking/components/timeline_chart.vue
@@ -1,6 +1,6 @@
<script>
import { GlChart } from '@gitlab/ui/dist/charts';
-import { dataVizBlue500 } from '@gitlab/ui/scss_to_js/scss_variables';
+import { DATA_VIZ_BLUE_500 } from '@gitlab/ui/dist/tokens/js/tokens';
import { hexToRgba } from '@gitlab/ui/dist/utils/utils';
import { isNumber } from 'lodash';
import { formatDate } from '~/lib/utils/datetime/date_format_utility';
@@ -109,7 +109,7 @@ export default {
{
data: yData,
type: 'bar',
- itemStyle: { color: hexToRgba(dataVizBlue500, 0.5) },
+ itemStyle: { color: hexToRgba(DATA_VIZ_BLUE_500, 0.5) },
},
],
tooltip: {
diff --git a/app/assets/javascripts/ide/components/ide_status_bar.vue b/app/assets/javascripts/ide/components/ide_status_bar.vue
index 8962bb76926..edc6cc3dcdc 100644
--- a/app/assets/javascripts/ide/components/ide_status_bar.vue
+++ b/app/assets/javascripts/ide/components/ide_status_bar.vue
@@ -105,6 +105,7 @@ export default {
:title="lastCommit.message"
:href="getCommitPath(lastCommit.short_id)"
class="commit-sha"
+ data-testid="commit-sha-content"
data-qa-selector="commit_sha_content"
>{{ lastCommit.short_id }}</a
>
diff --git a/app/assets/javascripts/jira_connect/subscriptions/components/app.vue b/app/assets/javascripts/jira_connect/subscriptions/components/app.vue
index 7e79572f76d..c5f6f736626 100644
--- a/app/assets/javascripts/jira_connect/subscriptions/components/app.vue
+++ b/app/assets/javascripts/jira_connect/subscriptions/components/app.vue
@@ -10,6 +10,7 @@ import SignInPage from '../pages/sign_in/sign_in_page.vue';
import SubscriptionsPage from '../pages/subscriptions_page.vue';
import UserLink from './user_link.vue';
import BrowserSupportAlert from './browser_support_alert.vue';
+import FeedbackBanner from './feedback_banner.vue';
export default {
name: 'JiraConnectApp',
@@ -18,6 +19,7 @@ export default {
GlLink,
GlSprintf,
BrowserSupportAlert,
+ FeedbackBanner,
SignInPage,
SubscriptionsPage,
UserLink,
@@ -103,39 +105,47 @@ export default {
<user-link v-if="userSignedIn" :user="currentUser" class="gl-fixed gl-right-4" />
</header>
- <main class="jira-connect-app gl-px-5 gl-pt-7 gl-mx-auto">
- <browser-support-alert v-if="!isBrowserSupported" class="gl-mb-7" />
- <div v-else data-testid="jira-connect-app">
- <gl-alert
- v-if="shouldShowAlert"
- :variant="alert.variant"
- :title="alert.title"
- class="gl-mb-5"
- data-testid="jira-connect-persisted-alert"
- @dismiss="setAlert"
- >
- <gl-sprintf v-if="alert.linkUrl" :message="alert.message">
- <template #link="{ content }">
- <gl-link :href="alert.linkUrl" target="_blank">{{ content }}</gl-link>
- </template>
- </gl-sprintf>
+ <main
+ class="jira-connect-app gl-px-5 gl-pt-7 gl-pb-7 gl-mx-auto gl-display-flex gl-flex-direction-column gl-gap-7"
+ >
+ <div class="gl-flex-grow-1">
+ <browser-support-alert v-if="!isBrowserSupported" class="gl-mb-7" />
+ <div v-else data-testid="jira-connect-app">
+ <gl-alert
+ v-if="shouldShowAlert"
+ :variant="alert.variant"
+ :title="alert.title"
+ class="gl-mb-5"
+ data-testid="jira-connect-persisted-alert"
+ @dismiss="setAlert"
+ >
+ <gl-sprintf v-if="alert.linkUrl" :message="alert.message">
+ <template #link="{ content }">
+ <gl-link :href="alert.linkUrl" target="_blank">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
- <template v-else>
- {{ alert.message }}
- </template>
- </gl-alert>
+ <template v-else>
+ {{ alert.message }}
+ </template>
+ </gl-alert>
- <div class="gl-layout-w-limited gl-mx-auto gl-px-5 gl-mb-7">
- <sign-in-page
- v-show="!userSignedIn"
- :has-subscriptions="hasSubscriptions"
- :public-key-storage-enabled="publicKeyStorageEnabled"
- @sign-in-oauth="onSignInOauth"
- @error="onSignInError"
- />
- <subscriptions-page v-if="userSignedIn" :has-subscriptions="hasSubscriptions" />
+ <div class="gl-layout-w-limited gl-mx-auto gl-px-5 gl-mb-7">
+ <sign-in-page
+ v-show="!userSignedIn"
+ :has-subscriptions="hasSubscriptions"
+ :public-key-storage-enabled="publicKeyStorageEnabled"
+ @sign-in-oauth="onSignInOauth"
+ @error="onSignInError"
+ />
+ <subscriptions-page v-if="userSignedIn" :has-subscriptions="hasSubscriptions" />
+ </div>
</div>
</div>
+
+ <div class="gl-flex-grow-2">
+ <feedback-banner class="gl-max-w-80 gl-mx-auto" />
+ </div>
</main>
</div>
</template>
diff --git a/app/assets/javascripts/jira_connect/subscriptions/components/feedback_banner.vue b/app/assets/javascripts/jira_connect/subscriptions/components/feedback_banner.vue
new file mode 100644
index 00000000000..5d6117b836d
--- /dev/null
+++ b/app/assets/javascripts/jira_connect/subscriptions/components/feedback_banner.vue
@@ -0,0 +1,57 @@
+<script>
+import { GlBanner } from '@gitlab/ui';
+import ChatBubbleSvg from '@gitlab/svgs/dist/illustrations/chat-bubble-sm.svg?url';
+import { s__, __ } from '~/locale';
+import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
+
+export default {
+ components: {
+ GlBanner,
+ LocalStorageSync,
+ },
+
+ data() {
+ return {
+ feedbackBannerDismissed: false,
+ };
+ },
+
+ methods: {
+ handleBannerClose() {
+ this.feedbackBannerDismissed = true;
+ },
+ },
+
+ i18n: {
+ title: s__('JiraConnect|Tell us what you think!'),
+ body: s__(
+ 'JiraConnect|We would love to learn more about your experience with the GitLab for Jira Cloud App.',
+ ),
+ dismissLabel: __('Dismiss'),
+ buttonText: __('Give feedback'),
+ },
+ feedbackBannerKey: 'jira_connect_feedback_banner',
+ feedbackIssueUrl: 'https://gitlab.com/gitlab-org/gitlab/-/issues/413652',
+ buttonAttributes: {
+ target: '_blank',
+ },
+ ChatBubbleSvg,
+};
+</script>
+
+<template>
+ <local-storage-sync v-model="feedbackBannerDismissed" :storage-key="$options.feedbackBannerKey">
+ <gl-banner
+ v-if="!feedbackBannerDismissed"
+ :title="$options.i18n.title"
+ :button-attributes="$options.buttonAttributes"
+ :button-text="$options.i18n.buttonText"
+ :button-link="$options.feedbackIssueUrl"
+ :dismiss-label="$options.i18n.dismissLabel"
+ :svg-path="$options.ChatBubbleSvg"
+ @close="handleBannerClose"
+ >
+ <p>{{ $options.i18n.body }}</p>
+ </gl-banner>
+ </local-storage-sync>
+</template>
diff --git a/app/assets/javascripts/mr_more_dropdown.js b/app/assets/javascripts/mr_more_dropdown.js
index ca50028a93a..4a9e10be5ad 100644
--- a/app/assets/javascripts/mr_more_dropdown.js
+++ b/app/assets/javascripts/mr_more_dropdown.js
@@ -1,4 +1,5 @@
import Vue from 'vue';
+import { initReportAbuse } from '~/projects/report_abuse';
import MrMoreDropdown from '~/vue_shared/components/mr_more_dropdown.vue';
export const initMrMoreDropdown = () => {
@@ -37,6 +38,9 @@ export const initMrMoreDropdown = () => {
reportAbusePath: el.dataset.reportAbusePath,
showSummaryNotesToggle: Boolean(document.querySelector('#js-summary-notes')),
},
+ beforeCreate() {
+ initReportAbuse();
+ },
render: (createElement) =>
createElement(MrMoreDropdown, {
props: {
diff --git a/app/assets/javascripts/pages/projects/merge_requests/page.js b/app/assets/javascripts/pages/projects/merge_requests/page.js
index 552e75da9b8..75e308e706f 100644
--- a/app/assets/javascripts/pages/projects/merge_requests/page.js
+++ b/app/assets/javascripts/pages/projects/merge_requests/page.js
@@ -9,6 +9,7 @@ import store from '~/mr_notes/stores';
import initSidebarBundle from '~/sidebar/sidebar_bundle';
import { apolloProvider } from '~/graphql_shared/issuable_client';
import { parseBoolean } from '~/lib/utils/common_utils';
+import { initMrMoreDropdown } from '~/mr_more_dropdown';
import initShow from './init_merge_request_show';
import getStateQuery from './queries/get_state.query.graphql';
@@ -17,6 +18,7 @@ Vue.use(VueApollo);
export function initMrPage() {
initMrNotes();
initShow();
+ initMrMoreDropdown();
startCodeReviewMessaging({ signalBus: diffsEventHub });
}
diff --git a/app/assets/javascripts/pages/projects/merge_requests/show/index.js b/app/assets/javascripts/pages/projects/merge_requests/show/index.js
index 1cc7e892ca0..9eaf490abb2 100644
--- a/app/assets/javascripts/pages/projects/merge_requests/show/index.js
+++ b/app/assets/javascripts/pages/projects/merge_requests/show/index.js
@@ -1,9 +1,5 @@
import mountNotesApp from 'ee_else_ce/mr_notes/mount_app';
-import { initReportAbuse } from '~/projects/report_abuse';
-import { initMrMoreDropdown } from '~/mr_more_dropdown';
import { initMrPage } from 'ee_else_ce/pages/projects/merge_requests/page';
initMrPage();
mountNotesApp();
-initReportAbuse();
-initMrMoreDropdown();
diff --git a/app/assets/javascripts/super_sidebar/components/global_search/command_palette/command_palette_items.vue b/app/assets/javascripts/super_sidebar/components/global_search/command_palette/command_palette_items.vue
index 1e31a1cbbee..a1d0e400b5f 100644
--- a/app/assets/javascripts/super_sidebar/components/global_search/command_palette/command_palette_items.vue
+++ b/app/assets/javascripts/super_sidebar/components/global_search/command_palette/command_palette_items.vue
@@ -59,6 +59,13 @@ export default {
case COMMAND_HANDLE:
this.getCommandsAndPages();
break;
+ /* TODO: Search for recent issues initiated by #(ISSUE_HANDLE) from the command palette scope
+ was removed as using the # in command palette conflicted
+ with the existing global search functionality to search for issue by its id.
+ The code that performs the Recent issues search was not removed from the code base
+ as it would be nice to bring it back when we decide how to combine both search by id and text.
+ In scope of https://gitlab.com/gitlab-org/gitlab/-/issues/417434
+ we either bring back the search by #issue_text or remove the related code completely */
case USER_HANDLE:
case PROJECT_HANDLE:
case ISSUE_HANDLE:
diff --git a/app/assets/javascripts/super_sidebar/components/global_search/command_palette/constants.js b/app/assets/javascripts/super_sidebar/components/global_search/command_palette/constants.js
index 83b262cf0d7..a43e621da44 100644
--- a/app/assets/javascripts/super_sidebar/components/global_search/command_palette/constants.js
+++ b/app/assets/javascripts/super_sidebar/components/global_search/command_palette/constants.js
@@ -2,14 +2,14 @@ import { s__, sprintf } from '~/locale';
export const COMMAND_HANDLE = '>';
export const USER_HANDLE = '@';
-export const PROJECT_HANDLE = '&';
+export const PROJECT_HANDLE = ':';
export const ISSUE_HANDLE = '#';
export const PATH_HANDLE = '/';
-export const COMMON_HANDLES = [COMMAND_HANDLE, USER_HANDLE, PROJECT_HANDLE, ISSUE_HANDLE];
+export const COMMON_HANDLES = [COMMAND_HANDLE, USER_HANDLE, PROJECT_HANDLE];
export const SEARCH_OR_COMMAND_MODE_PLACEHOLDER = sprintf(
s__(
- 'CommandPalette|Type %{commandHandle} for command, %{userHandle} for user, %{projectHandle} for project, %{issueHandle} for issue, %{pathHandle} for project file or perform generic search...',
+ 'CommandPalette|Type %{commandHandle} for command, %{userHandle} for user, %{projectHandle} for project, %{pathHandle} for project file, or perform generic search...',
),
{
commandHandle: COMMAND_HANDLE,
diff --git a/app/assets/javascripts/vue_shared/components/ci_icon.vue b/app/assets/javascripts/vue_shared/components/ci_icon.vue
index 0d7547d88a1..6670b931416 100644
--- a/app/assets/javascripts/vue_shared/components/ci_icon.vue
+++ b/app/assets/javascripts/vue_shared/components/ci_icon.vue
@@ -36,6 +36,15 @@ export default {
status: {
type: Object,
required: true,
+ validator(status) {
+ const { group, icon } = status;
+ return (
+ typeof group === 'string' &&
+ group.length &&
+ typeof icon === 'string' &&
+ icon.startsWith('status_')
+ );
+ },
},
size: {
type: Number,
@@ -69,7 +78,7 @@ export default {
computed: {
wrapperStyleClasses() {
const status = this.status.group;
- return `ci-status-icon ci-status-icon-${status} js-ci-status-icon-${status} gl-rounded-full gl-justify-content-center gl-line-height-0`;
+ return `ci-status-icon ci-status-icon-${status} gl-rounded-full gl-justify-content-center gl-line-height-0`;
},
icon() {
return this.isBorderless ? `${this.status.icon}_borderless` : this.status.icon;
@@ -84,7 +93,6 @@ export default {
{ interactive: isInteractive, active: isActive, borderless: isBorderless },
]"
:style="{ height: `${size}px`, width: `${size}px` }"
- data-testid="ci-icon-wrapper"
>
<gl-icon :name="icon" :size="size" :class="cssClasses" :aria-label="status.icon" />
</span>
diff --git a/app/assets/stylesheets/page_bundles/jira_connect.scss b/app/assets/stylesheets/page_bundles/jira_connect.scss
index 2c54c819543..6972e98b0bf 100644
--- a/app/assets/stylesheets/page_bundles/jira_connect.scss
+++ b/app/assets/stylesheets/page_bundles/jira_connect.scss
@@ -9,6 +9,8 @@
@import '@gitlab/ui/src/components/base/alert/alert';
@import '@gitlab/ui/src/components/base/avatar/avatar';
@import '@gitlab/ui/src/components/base/button/button';
+@import '@gitlab/ui/src/components/base/banner/banner';
+@import '@gitlab/ui/src/components/base/card/card';
@import '@gitlab/ui/src/components/base/icon/icon';
@import '@gitlab/ui/src/components/base/link/link';
@import '@gitlab/ui/src/components/base/loading_icon/loading_icon';
@@ -23,7 +25,7 @@
@import '@gitlab/ui/src/components/base/form/form_group/form_group';
@import '@gitlab/ui/src/components/base/search_box_by_type/search_box_by_type';
-$header-height: 40px;
+$header-height: $gl-spacing-scale-8;
.jira-connect-header {
min-height: $header-height;
@@ -35,6 +37,6 @@ $header-height: 40px;
.jira-connect-app {
margin-top: $header-height;
- height: calc(100% - #{$header-height});
- max-width: 1000px;
+ height: 100%;
+ max-height: calc(100% - #{$header-height + $gl-spacing-scale-7 * 2});
}
diff --git a/app/graphql/types/ci/job_type.rb b/app/graphql/types/ci/job_type.rb
index a779ceb2e2a..02b10f3e4bd 100644
--- a/app/graphql/types/ci/job_type.rb
+++ b/app/graphql/types/ci/job_type.rb
@@ -87,8 +87,10 @@ module Types
description: 'Play path of the job.'
field :playable, GraphQL::Types::Boolean, null: false, method: :playable?,
description: 'Indicates the job can be played.'
- field :previous_stage_jobs_or_needs, Types::Ci::JobNeedUnion.connection_type, null: true,
- description: 'Jobs that must complete before the job runs. Returns `BuildNeed`, which is the needed jobs if the job uses the `needs` keyword, or the previous stage jobs otherwise.'
+ field :previous_stage_jobs_or_needs, Types::Ci::JobNeedUnion.connection_type,
+ null: true,
+ description: 'Jobs that must complete before the job runs. Returns `BuildNeed`, ' \
+ 'which is the needed jobs if the job uses the `needs` keyword, or the previous stage jobs otherwise.'
field :ref_name, GraphQL::Types::String, null: true,
description: 'Ref name of the job.'
field :ref_path, GraphQL::Types::String, null: true,
@@ -179,7 +181,9 @@ module Types
stages = pipeline.stages.by_position(positions)
stages.each do |stage|
- loader.call([pipeline, stage.position], stage.latest_statuses)
+ # Without `.to_a`, the memoization will only preserve the activerecord relation object. And when there is
+ # a call, the SQL query will be executed again.
+ loader.call([pipeline, stage.position], stage.latest_statuses.to_a)
end
end
end
diff --git a/app/graphql/types/ci/stage_type.rb b/app/graphql/types/ci/stage_type.rb
index c0f3d1db57b..a9d8075329d 100644
--- a/app/graphql/types/ci/stage_type.rb
+++ b/app/graphql/types/ci/stage_type.rb
@@ -33,7 +33,7 @@ module Types
by_pipeline = keys.group_by(&:pipeline)
include_needs = keys.any? do |k|
k.requires?(%i[nodes jobs nodes needs]) ||
- k.requires?(%i[nodes jobs nodes previousStageJobsAndNeeds])
+ k.requires?(%i[nodes jobs nodes previousStageJobsOrNeeds])
end
by_pipeline.each do |pl, key_group|
diff --git a/app/models/user.rb b/app/models/user.rb
index 7fd5d25d7e0..93c15229e03 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -317,6 +317,9 @@ class User < ApplicationRecord
validates :color_scheme_id, allow_nil: true, inclusion: { in: Gitlab::ColorSchemes.valid_ids,
message: ->(*) { _("%{placeholder} is not a valid color scheme") % { placeholder: '%{value}' } } }
+ validates :hide_no_ssh_key, allow_nil: false, inclusion: { in: [true, false] }
+ validates :hide_no_password, allow_nil: false, inclusion: { in: [true, false] }
+ validates :notified_of_own_activity, allow_nil: false, inclusion: { in: [true, false] }
after_initialize :set_projects_limit
before_validation :sanitize_attrs
diff --git a/app/models/user_preference.rb b/app/models/user_preference.rb
index e527542e357..78ccce2aaae 100644
--- a/app/models/user_preference.rb
+++ b/app/models/user_preference.rb
@@ -23,6 +23,8 @@ class UserPreference < ApplicationRecord
format: { with: ColorsHelper::HEX_COLOR_PATTERN },
allow_blank: true
+ validates :time_display_relative, allow_nil: false, inclusion: { in: [true, false] }
+ validates :render_whitespace_in_code, allow_nil: false, inclusion: { in: [true, false] }
validates :pass_user_identities_to_ci_jwt, allow_nil: false, inclusion: { in: [true, false] }
validates :pinned_nav_items, json_schema: { filename: 'pinned_nav_items' }
diff --git a/app/views/admin/application_settings/_help_page.html.haml b/app/views/admin/application_settings/_help_page.html.haml
index e76a83662af..9509806fc41 100644
--- a/app/views/admin/application_settings/_help_page.html.haml
+++ b/app/views/admin/application_settings/_help_page.html.haml
@@ -18,7 +18,7 @@
.form-group
= f.label :help_page_documentation_base_url, _('Documentation pages URL'), class: 'gl-font-weight-bold'
= f.text_field :help_page_documentation_base_url, class: 'form-control gl-form-input', placeholder: 'https://docs.gitlab.com'
- - docs_link_url = help_page_path('user/admin_area/settings/help_page', anchor: 'destination-requirements')
+ - docs_link_url = help_page_path('administration/settings/help_page', anchor: 'destination-requirements')
- docs_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: docs_link_url }
%span.form-text.text-muted#support_help_block= html_escape(_('Requests for pages at %{code_start}%{help_text_url}%{code_end} redirect to the URL. The destination must meet certain requirements. %{docs_link_start}Learn more.%{docs_link_end}')) % { code_start: '<code>'.html_safe, help_text_url: help_url, code_end: '</code>'.html_safe, docs_link_start: docs_link_start, docs_link_end: '</a>'.html_safe }
= f.submit _('Save changes'), pajamas_button: true
diff --git a/doc/administration/custom_project_templates.md b/doc/administration/custom_project_templates.md
new file mode 100644
index 00000000000..2bbbb5649e6
--- /dev/null
+++ b/doc/administration/custom_project_templates.md
@@ -0,0 +1,73 @@
+---
+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
+---
+
+# Custom instance-level project templates **(PREMIUM SELF)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/6860) in GitLab 11.2.
+
+GitLab administrators can set a group to be the source of project templates that are
+selectable when a new project is created on the instance. These templates can be selected
+when you go to **New project > Create from template** and select the **Instance** tab.
+
+Every project in the group, but not its subgroups, can be selected when a new project
+is created, based on the user's access permissions:
+
+- Public projects can be selected by any authenticated user as a template for a new project,
+ if all enabled [project features](../user/project/settings/index.md#configure-project-visibility-features-and-permissions)
+ except for **GitLab Pages** and **Security and Compliance** are set to **Everyone With Access**.
+ The same applies to internal projects.
+- Private projects can be selected only by users who are members of the projects.
+
+The **Metrics Dashboard** is set to **Only Project Members** when you create a new project. Make
+sure you change it to **Everyone With Access** before making it a project template.
+
+Repository and database information that are copied over to each new project are
+identical to the data exported with the [GitLab Project Import/Export](../user/project/settings/import_export.md).
+
+To set project templates at the group level, see [Custom group-level project templates](../user/group/custom_project_templates.md).
+
+## Select instance-level project template group
+
+To select the group to use as the source for the project templates:
+
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
+1. Select **Settings > Templates**.
+1. Expand **Custom project templates**.
+1. Select a group to use.
+1. Select **Save changes**.
+
+Projects in subgroups of the template group are **not** included in the template list.
+
+## What is copied from the templates
+
+The entire custom instance-level project templates repository is copied, including:
+
+- Branches
+- Commits
+- Tags
+
+If the user:
+
+- Has the Owner role on the custom instance-level project templates project or is a GitLab administrator, all project settings are copied over to the new
+ project.
+- Doesn't have the Owner role or is not a GitLab administrator, project [deploy keys](../user/project/deploy_keys/index.md#view-deploy-keys) and project
+ [webhooks](../user/project/integrations/webhooks.md) aren't copied over because they contain sensitive data.
+
+To learn more about what is migrated, see
+[Items that are exported](../user/project/settings/import_export.md#items-that-are-exported).
+
+<!-- ## 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/docs_self_host.md b/doc/administration/docs_self_host.md
index 54f8c15a922..43aa5f3d871 100644
--- a/doc/administration/docs_self_host.md
+++ b/doc/administration/docs_self_host.md
@@ -163,7 +163,7 @@ To extract the HTML files of the documentation site:
## Redirect the `/help` links to the new Docs site
After your local product documentation site is running,
-[redirect the help links](../user/admin_area/settings/help_page.md#redirect-help-pages)
+[redirect the help links](../administration/settings/help_page.md#redirect-help-pages)
in the GitLab application to your local site, by using the fully qualified domain
name as the documentation URL. For example, if you used the
[Docker method](#self-host-the-product-documentation-with-docker), enter `http://0.0.0.0:4000`.
diff --git a/doc/administration/email_from_gitlab.md b/doc/administration/email_from_gitlab.md
new file mode 100644
index 00000000000..9272f58d2b9
--- /dev/null
+++ b/doc/administration/email_from_gitlab.md
@@ -0,0 +1,61 @@
+---
+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: howto, reference
+---
+
+# Email from GitLab **(PREMIUM SELF)**
+
+GitLab provides a tool to administrators for emailing all users, or users of
+a chosen group or project, right from the Admin Area. Users receive the email
+at their primary email address.
+
+For information about email notifications originating from GitLab, read
+[GitLab notification emails](../user/profile/notifications.md).
+
+## Use-cases
+
+- Notify your users about a new project, a new feature, or a new product launch.
+- Notify your users about a new deployment, or that downtime is expected
+ for a particular reason.
+
+## Sending emails to users from GitLab
+
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
+1. Select **Overview > Users**.
+1. Select **Send email to users**.
+
+ ![administrators](img/email1.png)
+
+1. Compose an email and choose where to send it (all users or users of a
+ chosen group or project). The email body only supports plain text messages.
+ HTML, Markdown, and other rich text formats are not supported, and is
+ sent as plain text to users.
+
+ ![compose an email](img/email2.png)
+
+NOTE:
+[Starting with GitLab 13.0](https://gitlab.com/gitlab-org/gitlab/-/issues/31509), email notifications can be sent only once every 10 minutes. This helps minimize performance issues.
+
+## Unsubscribing from emails
+
+Users can choose to unsubscribe from receiving emails from GitLab by following
+the unsubscribe link in the email. Unsubscribing is unauthenticated in order
+to keep this feature simple.
+
+On unsubscribe, users receive an email notification that unsubscribe happened.
+The endpoint that provides the unsubscribe option is rate-limited.
+
+<!-- ## 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/geo/replication/troubleshooting.md b/doc/administration/geo/replication/troubleshooting.md
index 5f88ca8aec8..c63480db389 100644
--- a/doc/administration/geo/replication/troubleshooting.md
+++ b/doc/administration/geo/replication/troubleshooting.md
@@ -240,7 +240,7 @@ This machine's Geo node name matches a database record ... no
```
For more information about recommended site names in the description of the Name field, see
-[Geo Admin Area Common Settings](../../../user/admin_area/geo_sites.md#common-settings).
+[Geo Admin Area Common Settings](../../../administration/geo_sites.md#common-settings).
### Reverify all uploads (or any SSF data type which is verified)
@@ -1346,7 +1346,7 @@ To fix this issue, set the primary site's internal URL to a URL that is:
- Accessible from all secondary sites.
1. Visit the primary site.
-1. [Set up the internal URLs](../../../user/admin_area/geo_sites.md#set-up-the-internal-urls).
+1. [Set up the internal URLs](../../../administration/geo_sites.md#set-up-the-internal-urls).
### Secondary site returns `Received HTTP code 403 from proxy after CONNECT`
diff --git a/doc/administration/geo_sites.md b/doc/administration/geo_sites.md
new file mode 100644
index 00000000000..81cc3a87941
--- /dev/null
+++ b/doc/administration/geo_sites.md
@@ -0,0 +1,119 @@
+---
+stage: Systems
+group: Geo
+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
+---
+
+# Geo sites Admin Area **(PREMIUM SELF)**
+
+You can configure various settings for GitLab Geo sites. For more information, see
+[Geo documentation](../administration/geo/index.md).
+
+On either the primary or secondary site:
+
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
+1. Select **Geo > Sites**.
+
+## Common settings
+
+All Geo sites have the following settings:
+
+| Setting | Description |
+| --------| ----------- |
+| Primary | This marks a Geo site as **primary** site. There can be only one **primary** site. |
+| Name | The unique identifier for the Geo site. It's highly recommended to use a physical location as a name. Good examples are "London Office" or "us-east-1". Avoid words like "primary", "secondary", "Geo", or "DR". This makes the failover process easier because the physical location does not change, but the Geo site role can. All nodes in a single Geo site use the same site name. Nodes use the `gitlab_rails['geo_node_name']` setting in `/etc/gitlab/gitlab.rb` to lookup their Geo site record in the PostgreSQL database. If `gitlab_rails['geo_node_name']` is not set, the node's `external_url` with trailing slash is used as fallback. The value of `Name` is case-sensitive, and most characters are allowed. |
+| URL | The instance's user-facing URL. |
+
+The site you're currently browsing is indicated with a blue `Current` label, and
+the **primary** node is listed first as `Primary site`.
+
+## Secondary site settings
+
+**Secondary** sites have a number of additional settings available:
+
+| Setting | Description |
+|---------------------------|-------------|
+| Selective synchronization | Enable Geo [selective sync](../administration/geo/replication/configuration.md#selective-synchronization) for this **secondary** site. |
+| Repository sync capacity | Number of concurrent requests this **secondary** site makes to the **primary** site when backfilling repositories. |
+| File sync capacity | Number of concurrent requests this **secondary** site makes to the **primary** site when backfilling files. |
+
+## Geo backfill
+
+**Secondary** sites are notified of changes to repositories and files by the **primary** site,
+and always attempt to synchronize those changes as quickly as possible.
+
+Backfill is the act of populating the **secondary** site with repositories and files that
+existed *before* the **secondary** site was added to the database. Because there may be
+extremely large numbers of repositories and files, it's not feasible to attempt to
+download them all at once; so, GitLab places an upper limit on the concurrency of
+these operations.
+
+How long the backfill takes is dependent on the maximum concurrency, but higher
+values place more strain on the **primary** site. The limits are configurable.
+If your **primary** site has lots of surplus capacity,
+you can increase the values to complete backfill in a shorter time. If it's
+under heavy load and backfill reduces its availability for standard requests,
+you can decrease them.
+
+## Set up the internal URLs
+
+> Setting up internal URLs in secondary sites was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77179) in GitLab 14.7.
+
+You can set up a different URL for synchronization between the primary and secondary site.
+
+The **primary** site's Internal URL is used by **secondary** sites to contact it
+(to sync repositories, for example). The name Internal URL distinguishes it from
+[External URL](https://docs.gitlab.com/omnibus/settings/configuration.html#configuring-the-external-url-for-gitlab),
+which is used by users. Internal URL does not need to be a private address.
+
+When [Geo secondary proxying](../administration/geo/secondary_proxy/index.md) is enabled,
+the primary uses the secondary's internal URL to contact it directly.
+
+The internal URL defaults to external URL. To change it:
+
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
+1. Select **Geo > Sites**.
+1. Select **Edit** on the site you want to customize.
+1. Edit the internal URL.
+1. Select **Save changes**.
+
+When enabled, the Admin Area for Geo shows replication details for each site directly
+from the primary site's UI, and through the Geo secondary proxy, if enabled.
+
+WARNING:
+We recommend using an HTTPS connection while configuring the Geo sites. To avoid
+breaking communication between **primary** and **secondary** sites when using
+HTTPS, customize your Internal URL to point to a load balancer with TLS
+terminated at the load balancer.
+
+WARNING:
+Starting with GitLab 13.3 and [until 13.11](https://gitlab.com/gitlab-org/gitlab/-/issues/325522),
+if you use an internal URL that is not accessible to the users, the
+OAuth authorization flow does not work properly, because users are redirected
+to the internal URL instead of the external one.
+
+## Multiple secondary sites behind a load balancer
+
+**Secondary** sites can use identical external URLs if
+a unique `name` is set for each Geo site. The `gitlab.rb` setting
+`gitlab_rails['geo_node_name']` must:
+
+- Be set for each GitLab instance that runs `puma`, `sidekiq`, or `geo_logcursor`.
+- Match a Geo site name.
+
+The load balancer must use sticky sessions to avoid authentication
+failures and cross-site request errors.
+
+<!-- ## 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/user/admin_area/img/email1.png b/doc/administration/img/email1.png
index e79ccc3e9a9..e79ccc3e9a9 100644
--- a/doc/user/admin_area/img/email1.png
+++ b/doc/administration/img/email1.png
Binary files differ
diff --git a/doc/user/admin_area/img/email2.png b/doc/administration/img/email2.png
index d073c0e42da..d073c0e42da 100644
--- a/doc/user/admin_area/img/email2.png
+++ b/doc/administration/img/email2.png
Binary files differ
diff --git a/doc/administration/settings/help_page.md b/doc/administration/settings/help_page.md
new file mode 100644
index 00000000000..53899ded106
--- /dev/null
+++ b/doc/administration/settings/help_page.md
@@ -0,0 +1,111 @@
+---
+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: howto
+---
+
+# Customize the Help and sign-in page messages **(FREE SELF)**
+
+In large organizations, it is useful to have information about who to contact or where
+to go for help. You can customize and display this information on the GitLab `/help` page and on
+the GitLab sign-in page.
+
+## Add a help message to the Help page
+
+You can add a help message, which is shown at the top of the GitLab `/help` page (for example,
+<https://gitlab.com/help>):
+
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
+1. Select **Settings > Preferences**.
+1. Expand **Sign-in and Help page**.
+1. In **Additional text to show on the Help page**, enter the information you want to display on `/help`.
+1. Select **Save changes**.
+
+You can now see the message on `/help`.
+
+NOTE:
+By default, `/help` is visible to unauthenticated users. However, if the
+[**Public** visibility level](../../user/admin_area/settings/visibility_and_access_controls.md#restrict-visibility-levels)
+is restricted, `/help` is visible only to authenticated users.
+
+## Add a help message to the sign-in page
+
+You can add a help message, which is shown on the GitLab sign-in page. The message appears on the sign-in page:
+
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
+1. Select **Settings > Preferences**.
+1. Expand **Sign-in and Help page**.
+1. In **Additional text to show on the sign-in page**, enter the information you want to
+ display on the sign-in page.
+1. Select **Save changes**.
+
+You can now see the message on the sign-in page.
+
+## Hide marketing-related entries from the Help page
+
+GitLab marketing-related entries are occasionally shown on the Help page. To hide these entries:
+
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
+1. Select **Settings > Preferences**.
+1. Expand **Sign-in and Help page**.
+1. Select the **Hide marketing-related entries from the Help page** checkbox.
+1. Select **Save changes**.
+
+## Set a custom Support page URL
+
+You can specify a custom URL to which users are directed when they:
+
+- Select **Support** from the Help dropdown list.
+- Select **See our website for help** on the Help page.
+
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
+1. Select **Settings > Preferences**.
+1. Expand **Sign-in and Help page**.
+1. In the **Support page URL** field, enter the URL.
+1. Select **Save changes**.
+
+## Redirect `/help` pages
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/43157) in GitLab 13.5.
+> - [Feature flag `help_page_documentation_redirect`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/71737) removed in GitLab 14.4.
+> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/71737) in GitLab 14.4.
+
+You can redirect all `/help` links to a destination that meets the [necessary requirements](#destination-requirements).
+
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
+1. Select **Settings > Preferences**.
+1. Expand **Sign-in and Help page**.
+1. In the **Documentation pages URL** field, enter the URL.
+1. Select **Save changes**.
+
+If the "Documentation pages URL" field is empty, the GitLab instance displays a basic version of the documentation sourced from the [`doc` directory](https://gitlab.com/gitlab-org/gitlab/-/tree/master/doc) of GitLab.
+
+### Destination requirements
+
+When redirecting `/help`, GitLab:
+
+- Redirects requests to the specified URL.
+- Appends `ee` and the documentation path, which includes the version number, to the URL.
+- Appends `.html` to the URL, and removes `.md` if necessary.
+
+For example, if the URL is set to `https://docs.gitlab.com`, requests for
+`/help/user/admin_area/settings/help_page.md` redirect to:
+`https://docs.gitlab.com/${VERSION}/ee/user/admin_area/settings/help_page.html`.
+
+<!-- ## 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/settings/incident_management_rate_limits.md b/doc/administration/settings/incident_management_rate_limits.md
new file mode 100644
index 00000000000..2a74c843107
--- /dev/null
+++ b/doc/administration/settings/incident_management_rate_limits.md
@@ -0,0 +1,39 @@
+---
+type: reference
+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
+---
+
+# Incident management rate limits **(ULTIMATE SELF)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/17859) in GitLab 12.5.
+
+You can limit the number of inbound alerts for [incidents](../../operations/incident_management/incidents.md)
+that can be created in a period of time. The inbound [incident management](../../operations/incident_management/index.md)
+alert limit can help prevent overloading your incident responders by reducing the
+number of alerts or duplicate issues.
+
+As an example, if you set a limit of `10` requests every `60` seconds,
+and `11` requests are sent to an [alert integration endpoint](../../operations/incident_management/integrations.md) within one minute,
+the eleventh request is blocked. Access to the endpoint is allowed again after one minute.
+
+This limit is:
+
+- Applied independently per project.
+- Not applied per IP address.
+- Disabled by default.
+
+Requests that exceed the limit are logged into `auth.log`.
+
+## Set a limit on inbound alerts
+
+To set inbound incident management alert limits:
+
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
+1. Select **Settings > Network**.
+1. Expand **Incident Management Limits**.
+1. Select the **Enable Incident Management inbound alert limit** checkbox.
+1. Optional. Input a custom value for **Maximum requests per project per rate limit period**. Default is 3600.
+1. Optional. Input a custom value for **Rate limit period**. Default is 3600 seconds.
diff --git a/doc/api/cluster_agents.md b/doc/api/cluster_agents.md
index 1753757e5d9..5abdece3909 100644
--- a/doc/api/cluster_agents.md
+++ b/doc/api/cluster_agents.md
@@ -366,7 +366,8 @@ Example response:
## Create an agent token
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/347046) in GitLab 15.0.
-> - Two-token limit [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/361030) in GitLab 16.1.
+> - Two-token limit [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/361030/) in GitLab 16.1 with a [flag](../administration/feature_flags.md) named `cluster_agents_limit_tokens_created`.
+> - Two-token limit [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/412399) in GitLab 16.2. Feature flag `cluster_agents_limit_tokens_created` removed.
Creates a new token for an agent.
diff --git a/doc/ci/environments/deployment_approvals.md b/doc/ci/environments/deployment_approvals.md
index 4d5297dce7c..2a9b381c517 100644
--- a/doc/ci/environments/deployment_approvals.md
+++ b/doc/ci/environments/deployment_approvals.md
@@ -163,7 +163,7 @@ require `Administrator` to approve every deployment job in `Production`.
![multiple approval rules](img/multiple_approval_rules_v16_0.png)
-### Allow self-approval **(PREMIUM)**
+### Allow self-approval
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/381418) in GitLab 15.8.
> - Automatic approval [removed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/124638) in GitLab 16.2 due to [usability issues](https://gitlab.com/gitlab-org/gitlab/-/issues/391258).
diff --git a/doc/ci/pipelines/index.md b/doc/ci/pipelines/index.md
index 5d8a81b4802..45af40a4cea 100644
--- a/doc/ci/pipelines/index.md
+++ b/doc/ci/pipelines/index.md
@@ -88,7 +88,7 @@ This table lists the refspecs injected for each pipeline type:
|--------------- |---------------------------------------- |
| pipeline for branches | `+<sha>:refs/pipelines/<id>` and `+refs/heads/<name>:refs/remotes/origin/<name>` |
| pipeline for tags | `+<sha>:refs/pipelines/<id>` and `+refs/tags/<name>:refs/tags/<name>` |
-| [merge request pipeline](../pipelines/merge_request_pipelines.md) | `+<sha>:refs/pipelines/<id>` |
+| [merge request pipeline](../pipelines/merge_request_pipelines.md) | `+refs/pipelines/<id>:refs/pipelines/<id>` |
The refs `refs/heads/<name>` and `refs/tags/<name>` exist in your
project repository. GitLab generates the special ref `refs/pipelines/<id>` during a
diff --git a/doc/development/product_qualified_lead_guide/index.md b/doc/development/product_qualified_lead_guide/index.md
index 2b78f012159..cf25d83c39a 100644
--- a/doc/development/product_qualified_lead_guide/index.md
+++ b/doc/development/product_qualified_lead_guide/index.md
@@ -131,8 +131,8 @@ The flow of a PQL lead is as follows:
```mermaid
sequenceDiagram
Trial Frontend Forms ->>TrialsController#create_lead: GitLab.com frontend sends [lead] to backend
- TrialsController#create_lead->>CreateLeadService: [lead]
- TrialsController#create_lead->>ApplyTrialService: [lead] Apply the trial
+ TrialsController#create->>CreateLeadService: [lead]
+ TrialsController#create->>ApplyTrialService: [lead] Apply the trial
CreateLeadService->>SubscriptionPortalClient#generate_trial(sync_to_gl=false): [lead] Creates customer account on CustomersDot
ApplyTrialService->>SubscriptionPortalClient#generate_trial(sync_to_gl=true): [lead] Asks CustomersDot to apply the trial on namespace
SubscriptionPortalClient#generate_trial(sync_to_gl=false)->>CustomersDot|TrialsController#create(sync_to_gl=false): GitLab.com sends [lead] to CustomersDot
@@ -169,8 +169,8 @@ sequenceDiagram
```mermaid
sequenceDiagram
- HandRaiseForm Vue Component->>TrialsController#create_hand_raise_lead: GitLab.com frontend sends [lead] to backend
- Subscriptions::HandRaiseLeadsController#create->>CreateHandRaiseLeadService: [lead]
+ HandRaiseForm Vue Component->>HandRaiseLeadsController#create: GitLab.com frontend sends [lead] to backend
+ HandRaiseLeadsController#create->>CreateHandRaiseLeadService: [lead]
CreateHandRaiseLeadService->>SubscriptionPortalClient: [lead]
SubscriptionPortalClient->>CustomersDot|TrialsController#create_hand_raise_lead: GitLab.com sends [lead] to CustomersDot
```
diff --git a/doc/subscriptions/bronze_starter.md b/doc/subscriptions/bronze_starter.md
index b981a63a8b7..b0115cd7e7e 100644
--- a/doc/subscriptions/bronze_starter.md
+++ b/doc/subscriptions/bronze_starter.md
@@ -16,7 +16,7 @@ The following features remain available to Bronze and Starter customers, even th
the tiers are no longer mentioned in GitLab documentation:
- [Activate GitLab EE with a license](../user/admin_area/license.md)
-- [Add a help message to the sign-in page](../user/admin_area/settings/help_page.md#add-a-help-message-to-the-sign-in-page)
+- [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)
- Description templates:
diff --git a/doc/user/admin_area/custom_project_templates.md b/doc/user/admin_area/custom_project_templates.md
index 0e0acf4af57..dc773b0aaca 100644
--- a/doc/user/admin_area/custom_project_templates.md
+++ b/doc/user/admin_area/custom_project_templates.md
@@ -1,73 +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
+redirect_to: '../../administration/custom_project_templates.md'
+remove_date: '2023-10-10'
---
-# Custom instance-level project templates **(PREMIUM SELF)**
+This document was moved to [another location](../../administration/custom_project_templates.md).
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/6860) in GitLab 11.2.
-
-GitLab administrators can set a group to be the source of project templates that are
-selectable when a new project is created on the instance. These templates can be selected
-when you go to **New project > Create from template** and select the **Instance** tab.
-
-Every project in the group, but not its subgroups, can be selected when a new project
-is created, based on the user's access permissions:
-
-- Public projects can be selected by any authenticated user as a template for a new project,
- if all enabled [project features](../project/settings/index.md#configure-project-visibility-features-and-permissions)
- except for **GitLab Pages** and **Security and Compliance** are set to **Everyone With Access**.
- The same applies to internal projects.
-- Private projects can be selected only by users who are members of the projects.
-
-The **Metrics Dashboard** is set to **Only Project Members** when you create a new project. Make
-sure you change it to **Everyone With Access** before making it a project template.
-
-Repository and database information that are copied over to each new project are
-identical to the data exported with the [GitLab Project Import/Export](../project/settings/import_export.md).
-
-To set project templates at the group level, see [Custom group-level project templates](../group/custom_project_templates.md).
-
-## Select instance-level project template group
-
-To select the group to use as the source for the project templates:
-
-1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
-1. Select **Admin Area**.
-1. Select **Settings > Templates**.
-1. Expand **Custom project templates**.
-1. Select a group to use.
-1. Select **Save changes**.
-
-Projects in subgroups of the template group are **not** included in the template list.
-
-## What is copied from the templates
-
-The entire custom instance-level project templates repository is copied, including:
-
-- Branches
-- Commits
-- Tags
-
-If the user:
-
-- Has the Owner role on the custom instance-level project templates project or is a GitLab administrator, all project settings are copied over to the new
- project.
-- Doesn't have the Owner role or is not a GitLab administrator, project [deploy keys](../project/deploy_keys/index.md#view-deploy-keys) and project
- [webhooks](../project/integrations/webhooks.md) aren't copied over because they contain sensitive data.
-
-To learn more about what is migrated, see
-[Items that are exported](../project/settings/import_export.md#items-that-are-exported).
-
-<!-- ## 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-10>. -->
+<!-- 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/email_from_gitlab.md b/doc/user/admin_area/email_from_gitlab.md
index fbdfe437719..e5194f05381 100644
--- a/doc/user/admin_area/email_from_gitlab.md
+++ b/doc/user/admin_area/email_from_gitlab.md
@@ -1,61 +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: howto, reference
+redirect_to: '../../administration/email_from_gitlab.md'
+remove_date: '2023-10-10'
---
-# Email from GitLab **(PREMIUM SELF)**
+This document was moved to [another location](../../administration/email_from_gitlab.md).
-GitLab provides a tool to administrators for emailing all users, or users of
-a chosen group or project, right from the Admin Area. Users receive the email
-at their primary email address.
-
-For information about email notifications originating from GitLab, read
-[GitLab notification emails](../profile/notifications.md).
-
-## Use-cases
-
-- Notify your users about a new project, a new feature, or a new product launch.
-- Notify your users about a new deployment, or that downtime is expected
- for a particular reason.
-
-## Sending emails to users from GitLab
-
-1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
-1. Select **Admin Area**.
-1. Select **Overview > Users**.
-1. Select **Send email to users**.
-
- ![administrators](img/email1.png)
-
-1. Compose an email and choose where to send it (all users or users of a
- chosen group or project). The email body only supports plain text messages.
- HTML, Markdown, and other rich text formats are not supported, and is
- sent as plain text to users.
-
- ![compose an email](img/email2.png)
-
-NOTE:
-[Starting with GitLab 13.0](https://gitlab.com/gitlab-org/gitlab/-/issues/31509), email notifications can be sent only once every 10 minutes. This helps minimize performance issues.
-
-## Unsubscribing from emails
-
-Users can choose to unsubscribe from receiving emails from GitLab by following
-the unsubscribe link in the email. Unsubscribing is unauthenticated in order
-to keep this feature simple.
-
-On unsubscribe, users receive an email notification that unsubscribe happened.
-The endpoint that provides the unsubscribe option is rate-limited.
-
-<!-- ## 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-10>. -->
+<!-- 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/geo_sites.md b/doc/user/admin_area/geo_sites.md
index 3bae90aaec8..cd0f2f5646a 100644
--- a/doc/user/admin_area/geo_sites.md
+++ b/doc/user/admin_area/geo_sites.md
@@ -1,119 +1,11 @@
---
-stage: Systems
-group: Geo
-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/geo_sites.md'
+remove_date: '2023-10-10'
---
-# Geo sites Admin Area **(PREMIUM SELF)**
+This document was moved to [another location](../../administration/geo_sites.md).
-You can configure various settings for GitLab Geo sites. For more information, see
-[Geo documentation](../../administration/geo/index.md).
-
-On either the primary or secondary site:
-
-1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
-1. Select **Admin Area**.
-1. Select **Geo > Sites**.
-
-## Common settings
-
-All Geo sites have the following settings:
-
-| Setting | Description |
-| --------| ----------- |
-| Primary | This marks a Geo site as **primary** site. There can be only one **primary** site. |
-| Name | The unique identifier for the Geo site. It's highly recommended to use a physical location as a name. Good examples are "London Office" or "us-east-1". Avoid words like "primary", "secondary", "Geo", or "DR". This makes the failover process easier because the physical location does not change, but the Geo site role can. All nodes in a single Geo site use the same site name. Nodes use the `gitlab_rails['geo_node_name']` setting in `/etc/gitlab/gitlab.rb` to lookup their Geo site record in the PostgreSQL database. If `gitlab_rails['geo_node_name']` is not set, the node's `external_url` with trailing slash is used as fallback. The value of `Name` is case-sensitive, and most characters are allowed. |
-| URL | The instance's user-facing URL. |
-
-The site you're currently browsing is indicated with a blue `Current` label, and
-the **primary** node is listed first as `Primary site`.
-
-## Secondary site settings
-
-**Secondary** sites have a number of additional settings available:
-
-| Setting | Description |
-|---------------------------|-------------|
-| Selective synchronization | Enable Geo [selective sync](../../administration/geo/replication/configuration.md#selective-synchronization) for this **secondary** site. |
-| Repository sync capacity | Number of concurrent requests this **secondary** site makes to the **primary** site when backfilling repositories. |
-| File sync capacity | Number of concurrent requests this **secondary** site makes to the **primary** site when backfilling files. |
-
-## Geo backfill
-
-**Secondary** sites are notified of changes to repositories and files by the **primary** site,
-and always attempt to synchronize those changes as quickly as possible.
-
-Backfill is the act of populating the **secondary** site with repositories and files that
-existed *before* the **secondary** site was added to the database. Because there may be
-extremely large numbers of repositories and files, it's not feasible to attempt to
-download them all at once; so, GitLab places an upper limit on the concurrency of
-these operations.
-
-How long the backfill takes is dependent on the maximum concurrency, but higher
-values place more strain on the **primary** site. The limits are configurable.
-If your **primary** site has lots of surplus capacity,
-you can increase the values to complete backfill in a shorter time. If it's
-under heavy load and backfill reduces its availability for standard requests,
-you can decrease them.
-
-## Set up the internal URLs
-
-> Setting up internal URLs in secondary sites was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77179) in GitLab 14.7.
-
-You can set up a different URL for synchronization between the primary and secondary site.
-
-The **primary** site's Internal URL is used by **secondary** sites to contact it
-(to sync repositories, for example). The name Internal URL distinguishes it from
-[External URL](https://docs.gitlab.com/omnibus/settings/configuration.html#configuring-the-external-url-for-gitlab),
-which is used by users. Internal URL does not need to be a private address.
-
-When [Geo secondary proxying](../../administration/geo/secondary_proxy/index.md) is enabled,
-the primary uses the secondary's internal URL to contact it directly.
-
-The internal URL defaults to external URL. To change it:
-
-1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
-1. Select **Admin Area**.
-1. Select **Geo > Sites**.
-1. Select **Edit** on the site you want to customize.
-1. Edit the internal URL.
-1. Select **Save changes**.
-
-When enabled, the Admin Area for Geo shows replication details for each site directly
-from the primary site's UI, and through the Geo secondary proxy, if enabled.
-
-WARNING:
-We recommend using an HTTPS connection while configuring the Geo sites. To avoid
-breaking communication between **primary** and **secondary** sites when using
-HTTPS, customize your Internal URL to point to a load balancer with TLS
-terminated at the load balancer.
-
-WARNING:
-Starting with GitLab 13.3 and [until 13.11](https://gitlab.com/gitlab-org/gitlab/-/issues/325522),
-if you use an internal URL that is not accessible to the users, the
-OAuth authorization flow does not work properly, because users are redirected
-to the internal URL instead of the external one.
-
-## Multiple secondary sites behind a load balancer
-
-**Secondary** sites can use identical external URLs if
-a unique `name` is set for each Geo site. The `gitlab.rb` setting
-`gitlab_rails['geo_node_name']` must:
-
-- Be set for each GitLab instance that runs `puma`, `sidekiq`, or `geo_logcursor`.
-- Match a Geo site name.
-
-The load balancer must use sticky sessions to avoid authentication
-failures and cross-site request errors.
-
-<!-- ## 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-10>. -->
+<!-- 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/help_page.md b/doc/user/admin_area/settings/help_page.md
index febd794b04c..38fe5c3b54c 100644
--- a/doc/user/admin_area/settings/help_page.md
+++ b/doc/user/admin_area/settings/help_page.md
@@ -1,111 +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: howto
+redirect_to: '../../../administration/settings/help_page.md'
+remove_date: '2023-10-07'
---
-# Customize the Help and sign-in page messages **(FREE SELF)**
+This document was moved to [another location](../../../administration/settings/help_page.md).
-In large organizations, it is useful to have information about who to contact or where
-to go for help. You can customize and display this information on the GitLab `/help` page and on
-the GitLab sign-in page.
-
-## Add a help message to the Help page
-
-You can add a help message, which is shown at the top of the GitLab `/help` page (for example,
-<https://gitlab.com/help>):
-
-1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
-1. Select **Admin Area**.
-1. Select **Settings > Preferences**.
-1. Expand **Sign-in and Help page**.
-1. In **Additional text to show on the Help page**, enter the information you want to display on `/help`.
-1. Select **Save changes**.
-
-You can now see the message on `/help`.
-
-NOTE:
-By default, `/help` is visible to unauthenticated users. However, if the
-[**Public** visibility level](visibility_and_access_controls.md#restrict-visibility-levels)
-is restricted, `/help` is visible only to authenticated users.
-
-## Add a help message to the sign-in page
-
-You can add a help message, which is shown on the GitLab sign-in page. The message appears on the sign-in page:
-
-1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
-1. Select **Admin Area**.
-1. Select **Settings > Preferences**.
-1. Expand **Sign-in and Help page**.
-1. In **Additional text to show on the sign-in page**, enter the information you want to
- display on the sign-in page.
-1. Select **Save changes**.
-
-You can now see the message on the sign-in page.
-
-## Hide marketing-related entries from the Help page
-
-GitLab marketing-related entries are occasionally shown on the Help page. To hide these entries:
-
-1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
-1. Select **Admin Area**.
-1. Select **Settings > Preferences**.
-1. Expand **Sign-in and Help page**.
-1. Select the **Hide marketing-related entries from the Help page** checkbox.
-1. Select **Save changes**.
-
-## Set a custom Support page URL
-
-You can specify a custom URL to which users are directed when they:
-
-- Select **Support** from the Help dropdown list.
-- Select **See our website for help** on the Help page.
-
-1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
-1. Select **Admin Area**.
-1. Select **Settings > Preferences**.
-1. Expand **Sign-in and Help page**.
-1. In the **Support page URL** field, enter the URL.
-1. Select **Save changes**.
-
-## Redirect `/help` pages
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/43157) in GitLab 13.5.
-> - [Feature flag `help_page_documentation_redirect`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/71737) removed in GitLab 14.4.
-> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/71737) in GitLab 14.4.
-
-You can redirect all `/help` links to a destination that meets the [necessary requirements](#destination-requirements).
-
-1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
-1. Select **Admin Area**.
-1. Select **Settings > Preferences**.
-1. Expand **Sign-in and Help page**.
-1. In the **Documentation pages URL** field, enter the URL.
-1. Select **Save changes**.
-
-If the "Documentation pages URL" field is empty, the GitLab instance displays a basic version of the documentation sourced from the [`doc` directory](https://gitlab.com/gitlab-org/gitlab/-/tree/master/doc) of GitLab.
-
-### Destination requirements
-
-When redirecting `/help`, GitLab:
-
-- Redirects requests to the specified URL.
-- Appends `ee` and the documentation path, which includes the version number, to the URL.
-- Appends `.html` to the URL, and removes `.md` if necessary.
-
-For example, if the URL is set to `https://docs.gitlab.com`, requests for
-`/help/user/admin_area/settings/help_page.md` redirect to:
-`https://docs.gitlab.com/${VERSION}/ee/user/admin_area/settings/help_page.html`.
-
-<!-- ## 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-07>. -->
+<!-- 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/incident_management_rate_limits.md b/doc/user/admin_area/settings/incident_management_rate_limits.md
index 0b6e572837e..ad11d6f7f36 100644
--- a/doc/user/admin_area/settings/incident_management_rate_limits.md
+++ b/doc/user/admin_area/settings/incident_management_rate_limits.md
@@ -1,39 +1,11 @@
---
-type: reference
-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/settings/incident_management_rate_limits.md'
+remove_date: '2023-10-10'
---
-# Incident management rate limits **(ULTIMATE SELF)**
+This document was moved to [another location](../../../administration/settings/incident_management_rate_limits.md).
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/17859) in GitLab 12.5.
-
-You can limit the number of inbound alerts for [incidents](../../../operations/incident_management/incidents.md)
-that can be created in a period of time. The inbound [incident management](../../../operations/incident_management/index.md)
-alert limit can help prevent overloading your incident responders by reducing the
-number of alerts or duplicate issues.
-
-As an example, if you set a limit of `10` requests every `60` seconds,
-and `11` requests are sent to an [alert integration endpoint](../../../operations/incident_management/integrations.md) within one minute,
-the eleventh request is blocked. Access to the endpoint is allowed again after one minute.
-
-This limit is:
-
-- Applied independently per project.
-- Not applied per IP address.
-- Disabled by default.
-
-Requests that exceed the limit are logged into `auth.log`.
-
-## Set a limit on inbound alerts
-
-To set inbound incident management alert limits:
-
-1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
-1. Select **Admin Area**.
-1. Select **Settings > Network**.
-1. Expand **Incident Management Limits**.
-1. Select the **Enable Incident Management inbound alert limit** checkbox.
-1. Optional. Input a custom value for **Maximum requests per project per rate limit period**. Default is 3600.
-1. Optional. Input a custom value for **Rate limit period**. Default is 3600 seconds.
+<!-- This redirect file can be deleted after <2023-10-10>. -->
+<!-- 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/clusters/agent/work_with_agent.md b/doc/user/clusters/agent/work_with_agent.md
index 8bf9ac7cf06..e8fb399d1b0 100644
--- a/doc/user/clusters/agent/work_with_agent.md
+++ b/doc/user/clusters/agent/work_with_agent.md
@@ -107,7 +107,8 @@ For more information about debugging, see [troubleshooting documentation](troubl
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/327152) in GitLab 14.9.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/336641) in GitLab 14.10, the agent token can be revoked from the UI.
-> - Two-token limit [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/361030) in GitLab 16.1.
+> - Two-token limit [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/361030/) in GitLab 16.1 with a [flag](../../../administration/feature_flags.md) named `cluster_agents_limit_tokens_created`.
+> - Two-token limit [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/412399) in GitLab 16.2. Feature flag `cluster_agents_limit_tokens_created` removed.
An agent can have only two active tokens at one time.
diff --git a/doc/user/group/custom_project_templates.md b/doc/user/group/custom_project_templates.md
index cbab83dd61e..6bd57079c67 100644
--- a/doc/user/group/custom_project_templates.md
+++ b/doc/user/group/custom_project_templates.md
@@ -17,7 +17,7 @@ You can [customize the list](../project/index.md#create-a-project) of available
that all projects in your group have the same list. To do this, you populate a subgroup with the projects you want to
use as templates.
-You can also configure [custom templates for the instance](../admin_area/custom_project_templates.md).
+You can also configure [custom templates for the instance](../../administration/custom_project_templates.md).
## Set up group-level project templates
diff --git a/doc/user/profile/notifications.md b/doc/user/profile/notifications.md
index cc0b67eed52..0b769ff7eeb 100644
--- a/doc/user/profile/notifications.md
+++ b/doc/user/profile/notifications.md
@@ -14,7 +14,7 @@ Stay informed about what's happening in GitLab with email notifications.
You can receive updates about activity in issues, merge requests, epics, and designs.
For the tool that GitLab administrators can use to send messages to users, read
-[Email from GitLab](../admin_area/email_from_gitlab.md).
+[Email from GitLab](../../administration/email_from_gitlab.md).
## Who receives notifications
@@ -345,7 +345,7 @@ If you no longer wish to receive any email notifications:
**Disabled**.
On self-managed installations, even after doing this, your instance administrator
-[can still email you](../admin_area/email_from_gitlab.md).
+[can still email you](../../administration/email_from_gitlab.md).
To unsubscribe, select the unsubscribe link in one of these emails.
## Email headers you can use to filter email
diff --git a/doc/user/project/settings/import_export.md b/doc/user/project/settings/import_export.md
index 6cc2b51f077..814a4b04f3a 100644
--- a/doc/user/project/settings/import_export.md
+++ b/doc/user/project/settings/import_export.md
@@ -186,7 +186,7 @@ Items that are **not** exported include:
- Links to related merge requests
Migrating projects with file exports uses the same export and import mechanisms as creating projects from templates at the [group](../../group/custom_project_templates.md) and
-[instance](../../admin_area/custom_project_templates.md) levels. Therefore, the list of exported items is the same.
+[instance](../../../administration/custom_project_templates.md) levels. Therefore, the list of exported items is the same.
## Import a project and its data
diff --git a/lib/api/users.rb b/lib/api/users.rb
index e390654107d..fff0e9fee06 100644
--- a/lib/api/users.rb
+++ b/lib/api/users.rb
@@ -134,7 +134,7 @@ module API
entity = current_user&.can_read_all_resources? ? Entities::UserWithAdmin : Entities::UserBasic
if entity == Entities::UserWithAdmin
- users = users.preload(:identities, :webauthn_registrations, :namespace, :followers, :followees, :user_preference)
+ users = users.preload(:identities, :webauthn_registrations, :namespace, :followers, :followees, :user_preference, :user_detail)
end
users, options = with_custom_attributes(users, { with: entity, current_user: current_user })
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 0d4f8341345..23073ccaea7 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -11315,7 +11315,7 @@ msgstr ""
msgid "CommandPalette|Project files"
msgstr ""
-msgid "CommandPalette|Type %{commandHandle} for command, %{userHandle} for user, %{projectHandle} for project, %{issueHandle} for issue, %{pathHandle} for project file or perform generic search..."
+msgid "CommandPalette|Type %{commandHandle} for command, %{userHandle} for user, %{projectHandle} for project, %{pathHandle} for project file, or perform generic search..."
msgstr ""
msgid "CommandPalette|command"
@@ -20958,6 +20958,9 @@ msgstr ""
msgid "Gitpod|https://gitpod.example.com"
msgstr ""
+msgid "Give feedback"
+msgstr ""
+
msgid "Give us some feedback"
msgstr ""
@@ -25849,9 +25852,15 @@ msgstr ""
msgid "JiraConnect|Sign in to link groups"
msgstr ""
+msgid "JiraConnect|Tell us what you think!"
+msgstr ""
+
msgid "JiraConnect|The Jira user is not a site administrator. Check the permissions in Jira and try again."
msgstr ""
+msgid "JiraConnect|We would love to learn more about your experience with the GitLab for Jira Cloud App."
+msgstr ""
+
msgid "JiraConnect|Welcome to GitLab for Jira"
msgstr ""
diff --git a/spec/features/projects/blobs/blob_show_spec.rb b/spec/features/projects/blobs/blob_show_spec.rb
index 62cd9fd9a56..30a81ccc071 100644
--- a/spec/features/projects/blobs/blob_show_spec.rb
+++ b/spec/features/projects/blobs/blob_show_spec.rb
@@ -943,7 +943,7 @@ RSpec.describe 'File blob', :js, feature_category: :groups_and_projects do
page.within('.commit-actions') do
expect(page).to have_css('.ci-status-icon')
expect(page).to have_css('.ci-status-icon-running')
- expect(page).to have_css('.js-ci-status-icon-running')
+ expect(page).to have_selector('[data-testid="status_running-icon"]')
end
end
end
diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb
index 73ada3669a1..bb49fb734d7 100644
--- a/spec/features/projects/pipelines/pipeline_spec.rb
+++ b/spec/features/projects/pipelines/pipeline_spec.rb
@@ -165,7 +165,7 @@ RSpec.describe 'Pipeline', :js, feature_category: :groups_and_projects do
it 'shows a running icon and a cancel action for the running build' do
page.within('#ci-badge-deploy') do
- expect(page).to have_selector('.js-ci-status-icon-running')
+ expect(page).to have_selector('[data-testid="status_running-icon"]')
expect(page).to have_selector('.js-icon-cancel')
expect(page).to have_content('deploy')
end
@@ -187,7 +187,7 @@ RSpec.describe 'Pipeline', :js, feature_category: :groups_and_projects do
it 'shows a preparing icon and a cancel action' do
page.within('#ci-badge-prepare') do
- expect(page).to have_selector('.js-ci-status-icon-preparing')
+ expect(page).to have_selector('[data-testid="status_preparing-icon"]')
expect(page).to have_selector('.js-icon-cancel')
expect(page).to have_content('prepare')
end
@@ -209,7 +209,7 @@ RSpec.describe 'Pipeline', :js, feature_category: :groups_and_projects do
it 'shows the success icon and a retry action for the successful build' do
page.within('#ci-badge-build') do
- expect(page).to have_selector('.js-ci-status-icon-success')
+ expect(page).to have_selector('[data-testid="status_success-icon"]')
expect(page).to have_content('build')
end
@@ -238,7 +238,7 @@ RSpec.describe 'Pipeline', :js, feature_category: :groups_and_projects do
it 'shows the scheduled icon and an unschedule action for the delayed job' do
page.within('#ci-badge-delayed-job') do
- expect(page).to have_selector('.js-ci-status-icon-scheduled')
+ expect(page).to have_selector('[data-testid="status_scheduled-icon"]')
expect(page).to have_content('delayed-job')
end
@@ -263,7 +263,7 @@ RSpec.describe 'Pipeline', :js, feature_category: :groups_and_projects do
it 'shows the failed icon and a retry action for the failed build' do
page.within('#ci-badge-test') do
- expect(page).to have_selector('.js-ci-status-icon-failed')
+ expect(page).to have_selector('[data-testid="status_failed-icon"]')
expect(page).to have_content('test')
end
@@ -297,7 +297,7 @@ RSpec.describe 'Pipeline', :js, feature_category: :groups_and_projects do
it 'shows the skipped icon and a play action for the manual build' do
page.within('#ci-badge-manual-build') do
- expect(page).to have_selector('.js-ci-status-icon-manual')
+ expect(page).to have_selector('[data-testid="status_manual-icon"]')
expect(page).to have_content('manual')
end
@@ -323,7 +323,7 @@ RSpec.describe 'Pipeline', :js, feature_category: :groups_and_projects do
end
it 'shows the success icon and the generic comit status build' do
- expect(page).to have_selector('.js-ci-status-icon-success')
+ expect(page).to have_selector('[data-testid="status_success-icon"]')
expect(page).to have_content('jenkins')
expect(page).to have_link('jenkins', href: 'http://gitlab.com/status')
end
diff --git a/spec/frontend/ci/reports/components/summary_row_spec.js b/spec/frontend/ci/reports/components/summary_row_spec.js
index b1ae9e26b5b..d4d2ac29fb1 100644
--- a/spec/frontend/ci/reports/components/summary_row_spec.js
+++ b/spec/frontend/ci/reports/components/summary_row_spec.js
@@ -38,7 +38,7 @@ describe('Summary row', () => {
it('renders provided icon', () => {
createComponent();
- expect(findStatusIcon().classes()).toContain('js-ci-status-icon-warning');
+ expect(findStatusIcon().find('[data-testid="status_warning-icon"]').exists()).toBe(true);
});
it('renders help popover if popoverOptions are provided', () => {
diff --git a/spec/frontend/ide/components/ide_status_bar_spec.js b/spec/frontend/ide/components/ide_status_bar_spec.js
index 0ee16f98e7e..fe392a64013 100644
--- a/spec/frontend/ide/components/ide_status_bar_spec.js
+++ b/spec/frontend/ide/components/ide_status_bar_spec.js
@@ -1,6 +1,6 @@
-import { mount } from '@vue/test-utils';
import _ from 'lodash';
import { TEST_HOST } from 'helpers/test_constants';
+import { mountExtended } from 'helpers/vue_test_utils_helper';
import IdeStatusBar from '~/ide/components/ide_status_bar.vue';
import IdeStatusMR from '~/ide/components/ide_status_mr.vue';
import { rightSidebarViews } from '~/ide/constants';
@@ -15,6 +15,8 @@ jest.mock('~/lib/utils/poll');
describe('IdeStatusBar component', () => {
let wrapper;
+ const dummyIntervalId = 1337;
+ let dispatchMock;
const findMRStatus = () => wrapper.findComponent(IdeStatusMR);
@@ -31,14 +33,21 @@ describe('IdeStatusBar component', () => {
...state,
});
- wrapper = mount(IdeStatusBar, { store });
+ wrapper = mountExtended(IdeStatusBar, { store });
+ dispatchMock = jest.spyOn(store, 'dispatch');
};
+ beforeEach(() => {
+ jest.spyOn(window, 'setInterval').mockReturnValue(dummyIntervalId);
+ });
+
+ const findCommitShaLink = () => wrapper.findByTestId('commit-sha-content');
+
describe('default', () => {
it('triggers a setInterval', () => {
mountComponent();
- expect(wrapper.vm.intervalId).not.toBe(null);
+ expect(window.setInterval).toHaveBeenCalledTimes(1);
});
it('renders the statusbar', () => {
@@ -47,34 +56,10 @@ describe('IdeStatusBar component', () => {
expect(wrapper.classes()).toEqual(['ide-status-bar']);
});
- describe('commitAgeUpdate', () => {
- beforeEach(() => {
- mountComponent();
- jest.spyOn(wrapper.vm, 'commitAgeUpdate').mockImplementation(() => {});
- });
-
- afterEach(() => {
- jest.clearAllTimers();
- });
-
- it('gets called every second', () => {
- expect(wrapper.vm.commitAgeUpdate).not.toHaveBeenCalled();
-
- jest.advanceTimersByTime(1000);
-
- expect(wrapper.vm.commitAgeUpdate.mock.calls).toHaveLength(1);
-
- jest.advanceTimersByTime(1000);
-
- expect(wrapper.vm.commitAgeUpdate.mock.calls).toHaveLength(2);
- });
- });
-
describe('getCommitPath', () => {
it('returns the path to the commit details', () => {
mountComponent();
-
- expect(wrapper.vm.getCommitPath('abc123de')).toBe('/commit/abc123de');
+ expect(findCommitShaLink().attributes('href')).toBe('/commit/abc123de');
});
});
@@ -95,11 +80,10 @@ describe('IdeStatusBar component', () => {
},
};
mountComponent({ pipelines });
- jest.spyOn(wrapper.vm, 'openRightPane').mockImplementation(() => {});
wrapper.find('button').trigger('click');
- expect(wrapper.vm.openRightPane).toHaveBeenCalledWith(rightSidebarViews.pipelines);
+ expect(dispatchMock).toHaveBeenCalledWith('rightPane/open', rightSidebarViews.pipelines);
});
});
diff --git a/spec/frontend/ide/mock_data.js b/spec/frontend/ide/mock_data.js
index 557626b3cca..b1f192e1d98 100644
--- a/spec/frontend/ide/mock_data.js
+++ b/spec/frontend/ide/mock_data.js
@@ -13,6 +13,7 @@ export const projectData = {
can_push: true,
commit: {
id: '123',
+ short_id: 'abc123de',
},
},
},
@@ -79,6 +80,7 @@ export const jobs = [
path: 'testing',
status: {
icon: 'status_success',
+ group: 'success',
text: 'passed',
},
stage: 'test',
diff --git a/spec/frontend/jira_connect/subscriptions/components/app_spec.js b/spec/frontend/jira_connect/subscriptions/components/app_spec.js
index 26a9d07321c..ea578836a12 100644
--- a/spec/frontend/jira_connect/subscriptions/components/app_spec.js
+++ b/spec/frontend/jira_connect/subscriptions/components/app_spec.js
@@ -7,6 +7,7 @@ import SignInPage from '~/jira_connect/subscriptions/pages/sign_in/sign_in_page.
import SubscriptionsPage from '~/jira_connect/subscriptions/pages/subscriptions_page.vue';
import UserLink from '~/jira_connect/subscriptions/components/user_link.vue';
import BrowserSupportAlert from '~/jira_connect/subscriptions/components/browser_support_alert.vue';
+import FeedbackBanner from '~/jira_connect/subscriptions/components/feedback_banner.vue';
import createStore from '~/jira_connect/subscriptions/store';
import { SET_ALERT } from '~/jira_connect/subscriptions/store/mutation_types';
import { I18N_DEFAULT_SIGN_IN_ERROR_MESSAGE } from '~/jira_connect/subscriptions/constants';
@@ -31,6 +32,7 @@ describe('JiraConnectApp', () => {
const findSubscriptionsPage = () => wrapper.findComponent(SubscriptionsPage);
const findUserLink = () => wrapper.findComponent(UserLink);
const findBrowserSupportAlert = () => wrapper.findComponent(BrowserSupportAlert);
+ const findFeedbackBanner = () => wrapper.findComponent(FeedbackBanner);
const createComponent = ({ provide, initialState = {} } = {}) => {
store = createStore({ ...initialState, subscriptions: [mockSubscription] });
@@ -66,6 +68,12 @@ describe('JiraConnectApp', () => {
expect(findJiraConnectApp().exists()).toBe(false);
});
+ it('renders FeedbackBanner', () => {
+ createComponent();
+
+ expect(findFeedbackBanner().exists()).toBe(true);
+ });
+
describe.each`
scenario | currentUser | expectUserLink | expectSignInPage | expectSubscriptionsPage
${'user is not signed in'} | ${undefined} | ${false} | ${true} | ${false}
diff --git a/spec/frontend/jira_connect/subscriptions/components/feedback_banner_spec.js b/spec/frontend/jira_connect/subscriptions/components/feedback_banner_spec.js
new file mode 100644
index 00000000000..8debfaad5bb
--- /dev/null
+++ b/spec/frontend/jira_connect/subscriptions/components/feedback_banner_spec.js
@@ -0,0 +1,45 @@
+import { GlBanner } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import FeedbackBanner from '~/jira_connect/subscriptions/components/feedback_banner.vue';
+import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
+
+describe('FeedbackBanner', () => {
+ let wrapper;
+
+ const createComponent = () => {
+ wrapper = shallowMount(FeedbackBanner);
+ };
+
+ const findBanner = () => wrapper.findComponent(GlBanner);
+ const findLocalStorageSync = () => wrapper.findComponent(LocalStorageSync);
+
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('renders a banner with button', () => {
+ expect(findBanner().props()).toMatchObject({
+ title: FeedbackBanner.i18n.title,
+ buttonText: FeedbackBanner.i18n.buttonText,
+ buttonLink: FeedbackBanner.feedbackIssueUrl,
+ });
+ });
+
+ it('uses localStorage with default value as false', () => {
+ expect(findLocalStorageSync().props().value).toBe(false);
+ });
+
+ describe('when banner is dimsissed', () => {
+ beforeEach(() => {
+ findBanner().vm.$emit('close');
+ });
+
+ it('hides the banner', () => {
+ expect(findBanner().exists()).toBe(false);
+ });
+
+ it('updates localStorage value to true', () => {
+ expect(findLocalStorageSync().props().value).toBe(true);
+ });
+ });
+});
diff --git a/spec/frontend/jobs/components/job/job_container_item_spec.js b/spec/frontend/jobs/components/job/job_container_item_spec.js
index 9f5ef88c702..39782130d38 100644
--- a/spec/frontend/jobs/components/job/job_container_item_spec.js
+++ b/spec/frontend/jobs/components/job/job_container_item_spec.js
@@ -9,8 +9,8 @@ import job from '../../mock_data';
describe('JobContainerItem', () => {
let wrapper;
- const findCiIconComponent = () => wrapper.findComponent(CiIcon);
- const findGlIconComponent = () => wrapper.findComponent(GlIcon);
+ const findCiIcon = () => wrapper.findComponent(CiIcon);
+ const findGlIcon = () => wrapper.findComponent(GlIcon);
function createComponent(jobData = {}, props = { isActive: false, retried: false }) {
wrapper = shallowMount(JobContainerItem, {
@@ -30,7 +30,7 @@ describe('JobContainerItem', () => {
});
it('displays a status icon', () => {
- expect(findCiIconComponent().props('status')).toBe(job.status);
+ expect(findCiIcon().props('status')).toBe(job.status);
});
it('displays the job name', () => {
@@ -50,9 +50,7 @@ describe('JobContainerItem', () => {
});
it('displays an arrow sprite icon', () => {
- const icon = findGlIconComponent();
-
- expect(icon.props('name')).toBe('arrow-right');
+ expect(findGlIcon().props('name')).toBe('arrow-right');
});
});
@@ -62,9 +60,7 @@ describe('JobContainerItem', () => {
});
it('displays a retry icon', () => {
- const icon = findGlIconComponent();
-
- expect(icon.props('name')).toBe('retry');
+ expect(findGlIcon().props('name')).toBe('retry');
});
});
diff --git a/spec/frontend/vue_merge_request_widget/components/states/mr_widget_failed_to_merge_spec.js b/spec/frontend/vue_merge_request_widget/components/states/mr_widget_failed_to_merge_spec.js
index 38e5422325a..e1c88d7d3b6 100644
--- a/spec/frontend/vue_merge_request_widget/components/states/mr_widget_failed_to_merge_spec.js
+++ b/spec/frontend/vue_merge_request_widget/components/states/mr_widget_failed_to_merge_spec.js
@@ -1,4 +1,4 @@
-import { shallowMount } from '@vue/test-utils';
+import { shallowMount, mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import MrWidgetFailedToMerge from '~/vue_merge_request_widget/components/states/mr_widget_failed_to_merge.vue';
import StateContainer from '~/vue_merge_request_widget/components/state_container.vue';
@@ -8,17 +8,14 @@ describe('MRWidgetFailedToMerge', () => {
const dummyIntervalId = 1337;
let wrapper;
- const createComponent = (props = {}, data = {}) => {
- wrapper = shallowMount(MrWidgetFailedToMerge, {
+ const createComponent = (props = {}, mountFn = shallowMount) => {
+ wrapper = mountFn(MrWidgetFailedToMerge, {
propsData: {
mr: {
mergeError: 'Merge error happened',
},
...props,
},
- data() {
- return data;
- },
});
};
@@ -121,7 +118,9 @@ describe('MRWidgetFailedToMerge', () => {
describe('while it is refreshing', () => {
it('renders Refresing now', async () => {
- createComponent({}, { isRefreshing: true });
+ createComponent({});
+
+ wrapper.vm.refresh();
await nextTick();
@@ -138,8 +137,10 @@ describe('MRWidgetFailedToMerge', () => {
createComponent();
});
- it('renders warning icon and disabled merge button', () => {
- expect(wrapper.find('.js-ci-status-icon-warning')).not.toBeNull();
+ it('renders failed icon', () => {
+ createComponent({}, mount);
+
+ expect(wrapper.find('[data-testid="status-failed-icon"]').exists()).toBe(true);
});
it('renders given error', () => {
diff --git a/spec/frontend/vue_shared/components/ci_icon_spec.js b/spec/frontend/vue_shared/components/ci_icon_spec.js
index 295b91fda81..c907b776b91 100644
--- a/spec/frontend/vue_shared/components/ci_icon_spec.js
+++ b/spec/frontend/vue_shared/components/ci_icon_spec.js
@@ -5,14 +5,19 @@ import CiIcon from '~/vue_shared/components/ci_icon.vue';
describe('CI Icon component', () => {
let wrapper;
- const findIconWrapper = () => wrapper.find('[data-testid="ci-icon-wrapper"]');
-
- it('should render a span element with an svg', () => {
+ const createComponent = (props) => {
wrapper = shallowMount(CiIcon, {
propsData: {
- status: {
- icon: 'status_success',
- },
+ ...props,
+ },
+ });
+ };
+
+ it('should render a span element with an svg', () => {
+ createComponent({
+ status: {
+ group: 'success',
+ icon: 'status_success',
},
});
@@ -20,49 +25,43 @@ describe('CI Icon component', () => {
expect(wrapper.findComponent(GlIcon).exists()).toBe(true);
});
- describe('active icons', () => {
- it.each`
- isActive | cssClass
- ${true} | ${'active'}
- ${false} | ${'active'}
- `('active should be $isActive', ({ isActive, cssClass }) => {
+ describe.each`
+ isActive
+ ${true}
+ ${false}
+ `('when isActive is $isActive', ({ isActive }) => {
+ it(`"active" class is ${isActive ? 'not ' : ''}added`, () => {
wrapper = shallowMount(CiIcon, {
propsData: {
status: {
+ group: 'success',
icon: 'status_success',
},
isActive,
},
});
- if (isActive) {
- expect(findIconWrapper().classes()).toContain(cssClass);
- } else {
- expect(findIconWrapper().classes()).not.toContain(cssClass);
- }
+ expect(wrapper.classes('active')).toBe(isActive);
});
});
- describe('interactive icons', () => {
- it.each`
- isInteractive | cssClass
- ${true} | ${'interactive'}
- ${false} | ${'interactive'}
- `('interactive should be $isInteractive', ({ isInteractive, cssClass }) => {
+ describe.each`
+ isInteractive
+ ${true}
+ ${false}
+ `('when isInteractive is $isInteractive', ({ isInteractive }) => {
+ it(`"interactive" class is ${isInteractive ? 'not ' : ''}added`, () => {
wrapper = shallowMount(CiIcon, {
propsData: {
status: {
+ group: 'success',
icon: 'status_success',
},
isInteractive,
},
});
- if (isInteractive) {
- expect(findIconWrapper().classes()).toContain(cssClass);
- } else {
- expect(findIconWrapper().classes()).not.toContain(cssClass);
- }
+ expect(wrapper.classes('interactive')).toBe(isInteractive);
});
});
diff --git a/spec/models/user_preference_spec.rb b/spec/models/user_preference_spec.rb
index 729635b5a27..b2881d30924 100644
--- a/spec/models/user_preference_spec.rb
+++ b/spec/models/user_preference_spec.rb
@@ -8,6 +8,16 @@ RSpec.describe UserPreference, feature_category: :user_profile do
let(:user_preference) { create(:user_preference, user: user) }
describe 'validations' do
+ it { is_expected.to validate_inclusion_of(:time_display_relative).in_array([true, false]) }
+ it { is_expected.to validate_inclusion_of(:render_whitespace_in_code).in_array([true, false]) }
+
+ it do
+ is_expected.to validate_numericality_of(:tab_width)
+ .only_integer
+ .is_greater_than_or_equal_to(Gitlab::TabWidth::MIN)
+ .is_less_than_or_equal_to(Gitlab::TabWidth::MAX)
+ end
+
describe 'diffs_deletion_color and diffs_addition_color' do
using RSpec::Parameterized::TableSyntax
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 9066b3f32bc..e0a216b9d63 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -666,6 +666,10 @@ RSpec.describe User, feature_category: :user_profile do
end
it { is_expected.to validate_presence_of(:projects_limit) }
+ it { is_expected.to define_enum_for(:project_view).with_values(%i(readme activity files wiki)) }
+ it { is_expected.to validate_inclusion_of(:hide_no_ssh_key).in_array([true, false]) }
+ it { is_expected.to validate_inclusion_of(:hide_no_password).in_array([true, false]) }
+ it { is_expected.to validate_inclusion_of(:notified_of_own_activity).in_array([true, false]) }
it { is_expected.to validate_numericality_of(:projects_limit) }
it { is_expected.to allow_value(0).for(:projects_limit) }
it { is_expected.not_to allow_value(-1).for(:projects_limit) }
diff --git a/spec/requests/api/graphql/project/jobs_spec.rb b/spec/requests/api/graphql/project/jobs_spec.rb
index aea6cad9e62..2c45c7e9b79 100644
--- a/spec/requests/api/graphql/project/jobs_spec.rb
+++ b/spec/requests/api/graphql/project/jobs_spec.rb
@@ -11,6 +11,9 @@ RSpec.describe 'Query.project.jobs', feature_category: :continuous_integration d
create(:ci_pipeline, project: project, user: user)
end
+ let!(:job1) { create(:ci_build, pipeline: pipeline, name: 'job 1') }
+ let!(:job2) { create(:ci_build, pipeline: pipeline, name: 'job 2') }
+
let(:query) do
<<~QUERY
{
@@ -18,11 +21,6 @@ RSpec.describe 'Query.project.jobs', feature_category: :continuous_integration d
jobs {
nodes {
name
- previousStageJobsAndNeeds {
- nodes {
- name
- }
- }
}
}
}
@@ -30,27 +28,10 @@ RSpec.describe 'Query.project.jobs', feature_category: :continuous_integration d
QUERY
end
- it 'does not generate N+1 queries', :request_store, :use_sql_query_cache do
- build_stage = create(:ci_stage, position: 1, name: 'build', project: project, pipeline: pipeline)
- test_stage = create(:ci_stage, position: 2, name: 'test', project: project, pipeline: pipeline)
- create(:ci_build, pipeline: pipeline, name: 'docker 1 2', ci_stage: build_stage)
- create(:ci_build, pipeline: pipeline, name: 'docker 2 2', ci_stage: build_stage)
- create(:ci_build, pipeline: pipeline, name: 'rspec 1 2', ci_stage: test_stage)
- test_job = create(:ci_build, pipeline: pipeline, name: 'rspec 2 2', ci_stage: test_stage)
- create(:ci_build_need, build: test_job, name: 'docker 1 2')
-
+ it 'fetches jobs' do
post_graphql(query, current_user: user)
+ expect_graphql_errors_to_be_empty
- control = ActiveRecord::QueryRecorder.new(skip_cached: false) do
- post_graphql(query, current_user: user)
- end
-
- create(:ci_build, name: 'test-a', ci_stage: test_stage, pipeline: pipeline)
- test_b_job = create(:ci_build, name: 'test-b', ci_stage: test_stage, pipeline: pipeline)
- create(:ci_build_need, build: test_b_job, name: 'docker 2 2')
-
- expect do
- post_graphql(query, current_user: user)
- end.not_to exceed_all_query_limit(control)
+ expect(graphql_data['project']['jobs']['nodes'].pluck('name')).to contain_exactly('job 1', 'job 2')
end
end
diff --git a/spec/requests/api/graphql/project/pipeline_spec.rb b/spec/requests/api/graphql/project/pipeline_spec.rb
index fb1489372fc..d20ee5bfdff 100644
--- a/spec/requests/api/graphql/project/pipeline_spec.rb
+++ b/spec/requests/api/graphql/project/pipeline_spec.rb
@@ -337,16 +337,33 @@ RSpec.describe 'getting pipeline information nested in a project', feature_categ
end
end
- context 'N+1 queries on pipeline jobs' do
+ context 'N+1 queries on pipeline jobs.previousStageJobsOrNeeds' do
let(:pipeline) { create(:ci_pipeline, project: project) }
let(:fields) do
<<~FIELDS
- jobs {
+ stages {
nodes {
- previousStageJobsAndNeeds {
+ groups {
nodes {
- name
+ jobs {
+ nodes {
+ previousStageJobsOrNeeds {
+ nodes {
+ ... on JobNeedUnion {
+ ... on CiBuildNeed {
+ id
+ name
+ }
+ ... on CiJob {
+ id
+ name
+ }
+ }
+ }
+ }
+ }
+ }
}
}
}
@@ -357,13 +374,15 @@ RSpec.describe 'getting pipeline information nested in a project', feature_categ
it 'does not generate N+1 queries', :request_store, :use_sql_query_cache do
build_stage = create(:ci_stage, position: 1, name: 'build', project: project, pipeline: pipeline)
test_stage = create(:ci_stage, position: 2, name: 'test', project: project, pipeline: pipeline)
- create(:ci_build, pipeline: pipeline, name: 'docker 1 2', ci_stage: build_stage)
+
+ docker_1_2 = create(:ci_build, pipeline: pipeline, name: 'docker 1 2', ci_stage: build_stage)
create(:ci_build, pipeline: pipeline, name: 'docker 2 2', ci_stage: build_stage)
create(:ci_build, pipeline: pipeline, name: 'rspec 1 2', ci_stage: test_stage)
- test_job = create(:ci_build, pipeline: pipeline, name: 'rspec 2 2', ci_stage: test_stage)
- create(:ci_build_need, build: test_job, name: 'docker 1 2')
+ create(:ci_build, :dependent, needed: docker_1_2, pipeline: pipeline, name: 'rspec 2 2', ci_stage: test_stage)
+ # warm up
post_graphql(query, current_user: current_user)
+ expect_graphql_errors_to_be_empty
control = ActiveRecord::QueryRecorder.new(skip_cached: false) do
post_graphql(query, current_user: current_user)
@@ -371,7 +390,7 @@ RSpec.describe 'getting pipeline information nested in a project', feature_categ
create(:ci_build, name: 'test-a', ci_stage: test_stage, pipeline: pipeline)
test_b_job = create(:ci_build, name: 'test-b', ci_stage: test_stage, pipeline: pipeline)
- create(:ci_build_need, build: test_b_job, name: 'docker 2 2')
+ create(:ci_build, :dependent, needed: test_b_job, pipeline: pipeline, name: 'docker 2 2', ci_stage: test_stage)
expect do
post_graphql(query, current_user: current_user)
@@ -424,6 +443,7 @@ RSpec.describe 'getting pipeline information nested in a project', feature_categ
# warm up
post_graphql(query, current_user: current_user)
+ expect_graphql_errors_to_be_empty
control = ActiveRecord::QueryRecorder.new(skip_cached: false) do
post_graphql(query, current_user: current_user)