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/issue_templates/Security developer workflow.md1
-rw-r--r--app/assets/javascripts/ide/components/new_dropdown/index.vue2
-rw-r--r--app/assets/javascripts/issues/list/graphql.js11
-rw-r--r--app/assets/javascripts/issues/list/index.js4
-rw-r--r--app/assets/javascripts/lib/apollo/indexed_db_persistent_storage.js97
-rw-r--r--app/assets/javascripts/lib/apollo/local_db.js14
-rw-r--r--app/assets/javascripts/lib/graphql.js54
-rw-r--r--app/assets/javascripts/notes/components/note_actions.vue2
-rw-r--r--app/views/layouts/minimal.html.haml2
-rw-r--r--app/views/projects/mattermosts/new.html.haml1
-rw-r--r--app/views/projects/settings/packages_and_registries/cleanup_tags.html.haml1
-rw-r--r--app/views/shared/integrations/edit.html.haml1
-rw-r--r--app/views/shared/integrations/overrides.html.haml1
-rw-r--r--config/webpack.vendor.config.js25
-rw-r--r--doc/architecture/blueprints/_template.md3
-rw-r--r--doc/architecture/blueprints/cells/cells-feature-admin-area.md2
-rw-r--r--doc/architecture/blueprints/cells/cells-feature-agent-for-kubernetes.md2
-rw-r--r--doc/architecture/blueprints/cells/cells-feature-backups.md2
-rw-r--r--doc/architecture/blueprints/cells/cells-feature-ci-runners.md2
-rw-r--r--doc/architecture/blueprints/cells/cells-feature-container-registry.md2
-rw-r--r--doc/architecture/blueprints/cells/cells-feature-contributions-forks.md2
-rw-r--r--doc/architecture/blueprints/cells/cells-feature-dashboard.md2
-rw-r--r--doc/architecture/blueprints/cells/cells-feature-data-migration.md2
-rw-r--r--doc/architecture/blueprints/cells/cells-feature-database-sequences.md2
-rw-r--r--doc/architecture/blueprints/cells/cells-feature-git-access.md2
-rw-r--r--doc/architecture/blueprints/cells/cells-feature-gitlab-pages.md2
-rw-r--r--doc/architecture/blueprints/cells/cells-feature-global-search.md2
-rw-r--r--doc/architecture/blueprints/cells/cells-feature-graphql.md2
-rw-r--r--doc/architecture/blueprints/cells/cells-feature-organizations.md2
-rw-r--r--doc/architecture/blueprints/cells/cells-feature-personal-namespaces.md2
-rw-r--r--doc/architecture/blueprints/cells/cells-feature-router-endpoints-classification.md2
-rw-r--r--doc/architecture/blueprints/cells/cells-feature-schema-changes.md2
-rw-r--r--doc/architecture/blueprints/cells/cells-feature-secrets.md2
-rw-r--r--doc/architecture/blueprints/cells/cells-feature-snippets.md2
-rw-r--r--doc/architecture/blueprints/cells/cells-feature-template.md2
-rw-r--r--doc/architecture/blueprints/cells/cells-feature-uploads.md2
-rw-r--r--doc/architecture/blueprints/cells/index.md2
-rw-r--r--doc/architecture/blueprints/cells/proposal-stateless-router-with-buffering-requests.md2
-rw-r--r--doc/architecture/blueprints/cells/proposal-stateless-router-with-routes-learning.md2
-rw-r--r--doc/architecture/blueprints/ci_data_decay/index.md2
-rw-r--r--doc/architecture/blueprints/ci_data_decay/pipeline_partitioning.md2
-rw-r--r--doc/architecture/blueprints/ci_pipeline_components/index.md2
-rw-r--r--doc/architecture/blueprints/ci_scale/index.md2
-rw-r--r--doc/architecture/blueprints/clickhouse_usage/index.md2
-rw-r--r--doc/architecture/blueprints/code_search_with_zoekt/index.md2
-rw-r--r--doc/architecture/blueprints/composable_codebase_using_rails_engines/index.md2
-rw-r--r--doc/architecture/blueprints/consolidating_groups_and_projects/index.md2
-rw-r--r--doc/architecture/blueprints/container_registry_metadata_database/index.md2
-rw-r--r--doc/architecture/blueprints/database_testing/index.md2
-rw-r--r--doc/architecture/blueprints/gitlab_agent_deployments/index.md2
-rw-r--r--doc/architecture/blueprints/gitlab_observability_backend/metrics/index.md2
-rw-r--r--doc/architecture/blueprints/graphql_api/index.md2
-rw-r--r--doc/architecture/blueprints/object_storage/index.md2
-rw-r--r--doc/architecture/blueprints/rate_limiting/index.md2
-rw-r--r--doc/architecture/blueprints/remote_development/index.md2
-rw-r--r--doc/architecture/blueprints/runner_scaling/index.md2
-rw-r--r--doc/architecture/blueprints/runner_tokens/index.md2
-rw-r--r--doc/architecture/blueprints/secret_detection/index.md2
-rw-r--r--doc/architecture/blueprints/work_items/index.md2
-rw-r--r--doc/user/admin_area/custom_project_templates.md18
-rw-r--r--doc/user/application_security/policies/index.md8
-rw-r--r--doc/user/group/index.md9
-rw-r--r--doc/user/group/manage.md9
-rw-r--r--jest.config.base.js2
-rw-r--r--lib/backup/gitaly_backup.rb11
-rw-r--r--lib/backup/repositories.rb8
-rw-r--r--package.json2
-rw-r--r--qa/qa/specs/features/browser_ui/8_monitor/alert_management/recovery_alert_resolves_correct_alert_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/8_monitor/incident_management/recovery_alert_closes_correct_incident_spec.rb7
-rw-r--r--spec/frontend/ide/components/new_dropdown/index_spec.js56
-rw-r--r--spec/frontend/lib/apollo/indexed_db_persistent_storage_spec.js90
-rw-r--r--spec/frontend/lib/apollo/mock_data/cache_with_persist_directive_and_field.json151
-rw-r--r--spec/frontend/test_setup.js13
-rw-r--r--spec/lib/backup/gitaly_backup_spec.rb11
-rw-r--r--spec/lib/backup/repositories_spec.rb10
-rw-r--r--yarn.lock75
76 files changed, 566 insertions, 228 deletions
diff --git a/.gitlab/issue_templates/Security developer workflow.md b/.gitlab/issue_templates/Security developer workflow.md
index 3857303f2c4..294d699ea2f 100644
--- a/.gitlab/issue_templates/Security developer workflow.md
+++ b/.gitlab/issue_templates/Security developer workflow.md
@@ -13,6 +13,7 @@ Set the title to: `Description of the original issue`
- [ ] Add a `~severity::x` label to the issue and all associated merge requests.
- [ ] **IMPORTANT**: Mark this [issue as linked] to the Security Release Tracking Issue. You can find it [here](https://gitlab.com/gitlab-org/gitlab/-/issues?sort=created_date&state=opened&label_name[]=upcoming+security+release). This issue
MUST be linked for the release bot to know that the associated merge requests should be merged for this security release.
+- [ ] Mark this [issue as linked] to the `gitlab-org/gitlab` issue that describes the security vulnerability.
- Fill out the [Links section](#links):
- [ ] Next to **Issue on GitLab**, add a link to the `gitlab-org/gitlab` issue that describes the security vulnerability.
- [ ] If this change affects the public interface (public API or UI) of the product, post in the `#support_gitlab-com` Slack channel to explain the impact and discuss a mitigation plan for users that might be affected. If you need Support feedback or approval, reach out in `#spt_managers` Slack channel or mention `@gitlab-com/support/managers`.
diff --git a/app/assets/javascripts/ide/components/new_dropdown/index.vue b/app/assets/javascripts/ide/components/new_dropdown/index.vue
index ea1dbee4669..9f83de840b9 100644
--- a/app/assets/javascripts/ide/components/new_dropdown/index.vue
+++ b/app/assets/javascripts/ide/components/new_dropdown/index.vue
@@ -69,7 +69,7 @@ export default {
>
<gl-icon name="ellipsis_v" />
</button>
- <ul ref="dropdownMenu" class="dropdown-menu dropdown-menu-right">
+ <ul ref="dropdownMenu" class="dropdown-menu dropdown-menu-right" data-testid="dropdown-menu">
<template v-if="type === 'tree'">
<li>
<item-button
diff --git a/app/assets/javascripts/issues/list/graphql.js b/app/assets/javascripts/issues/list/graphql.js
index b590006929a..96330f69965 100644
--- a/app/assets/javascripts/issues/list/graphql.js
+++ b/app/assets/javascripts/issues/list/graphql.js
@@ -1,5 +1,5 @@
import produce from 'immer';
-import createDefaultClient from '~/lib/graphql';
+import createDefaultClient, { createApolloClientWithCaching } from '~/lib/graphql';
import getIssuesQuery from 'ee_else_ce/issues/list/queries/get_issues.query.graphql';
const resolvers = {
@@ -22,6 +22,9 @@ const resolvers = {
},
};
-export const gqlClient = gon.features?.frontendCaching
- ? createDefaultClient(resolvers, { localCacheKey: 'issues_list' })
- : createDefaultClient(resolvers);
+export async function gqlClient() {
+ const client = gon.features?.frontendCaching
+ ? await createApolloClientWithCaching(resolvers, { localCacheKey: 'issues_list' })
+ : createDefaultClient(resolvers);
+ return client;
+}
diff --git a/app/assets/javascripts/issues/list/index.js b/app/assets/javascripts/issues/list/index.js
index aca894549e4..720946ea330 100644
--- a/app/assets/javascripts/issues/list/index.js
+++ b/app/assets/javascripts/issues/list/index.js
@@ -42,7 +42,7 @@ export function mountJiraIssuesListApp() {
});
}
-export function mountIssuesListApp() {
+export async function mountIssuesListApp() {
const el = document.querySelector('.js-issues-list-root');
if (!el) {
@@ -100,7 +100,7 @@ export function mountIssuesListApp() {
el,
name: 'IssuesListRoot',
apolloProvider: new VueApollo({
- defaultClient: gqlClient,
+ defaultClient: await gqlClient(),
}),
router: new VueRouter({
base: window.location.pathname,
diff --git a/app/assets/javascripts/lib/apollo/indexed_db_persistent_storage.js b/app/assets/javascripts/lib/apollo/indexed_db_persistent_storage.js
new file mode 100644
index 00000000000..5d2a002bf85
--- /dev/null
+++ b/app/assets/javascripts/lib/apollo/indexed_db_persistent_storage.js
@@ -0,0 +1,97 @@
+/* eslint-disable no-underscore-dangle */
+/* eslint-disable class-methods-use-this */
+import { db } from './local_db';
+
+/**
+ * IndexedDB implementation of apollo-cache-persist [PersistentStorage][1]
+ *
+ * [1]: https://github.com/apollographql/apollo-cache-persist/blob/d536c741d1f2828a0ef9abda343a9186dd8dbff2/src/types/index.ts#L15
+ */
+export class IndexedDBPersistentStorage {
+ static async create() {
+ await db.open();
+
+ return new IndexedDBPersistentStorage();
+ }
+
+ async getItem(queryId) {
+ const resultObj = {};
+ const selectedQuery = await db.table('queries').get(queryId);
+ const tableNames = new Set(db.tables.map((table) => table.name));
+
+ if (selectedQuery) {
+ resultObj.ROOT_QUERY = selectedQuery;
+
+ const lookupTable = [];
+
+ const parseObjectsForRef = async (selObject) => {
+ const ops = Object.values(selObject).map(async (child) => {
+ if (!child) {
+ return;
+ }
+
+ if (child.__ref) {
+ const pathId = child.__ref;
+ const [refType, ...refKeyParts] = pathId.split(':');
+ const refKey = refKeyParts.join(':');
+
+ if (
+ !resultObj[pathId] &&
+ !lookupTable.includes(pathId) &&
+ tableNames.has(refType.toLowerCase())
+ ) {
+ lookupTable.push(pathId);
+ const selectedEntity = await db.table(refType.toLowerCase()).get(refKey);
+ if (selectedEntity) {
+ await parseObjectsForRef(selectedEntity);
+ resultObj[pathId] = selectedEntity;
+ }
+ }
+ } else if (typeof child === 'object') {
+ await parseObjectsForRef(child);
+ }
+ });
+
+ return Promise.all(ops);
+ };
+
+ await parseObjectsForRef(resultObj.ROOT_QUERY);
+ }
+
+ return resultObj;
+ }
+
+ async setItem(key, value) {
+ await this.#setQueryResults(key, JSON.parse(value));
+ }
+
+ async removeItem() {
+ // apollo-cache-persist only ever calls this when we're removing everything, so let's blow it all away
+ // https://gitlab.com/gitlab-org/gitlab/-/merge_requests/113745#note_1329175993
+
+ await Promise.all(
+ db.tables.map((table) => {
+ return table.clear();
+ }),
+ );
+ }
+
+ async #setQueryResults(queryId, results) {
+ await Promise.all(
+ Object.keys(results).map((id) => {
+ const objectType = id.split(':')[0];
+ if (objectType === 'ROOT_QUERY') {
+ return db.table('queries').put(results[id], queryId);
+ }
+ const key = objectType.toLowerCase();
+ const tableExists = db.tables.some((table) => table.name === key);
+ if (tableExists) {
+ return db.table(key).put(results[id], id);
+ }
+ return new Promise((resolve) => {
+ resolve();
+ });
+ }),
+ );
+ }
+}
diff --git a/app/assets/javascripts/lib/apollo/local_db.js b/app/assets/javascripts/lib/apollo/local_db.js
new file mode 100644
index 00000000000..cda30ff9d42
--- /dev/null
+++ b/app/assets/javascripts/lib/apollo/local_db.js
@@ -0,0 +1,14 @@
+/* eslint-disable @gitlab/require-i18n-strings */
+import Dexie from 'dexie';
+
+export const db = new Dexie('GLLocalCache');
+db.version(1).stores({
+ pages: 'url, timestamp',
+ queries: '',
+ project: 'id',
+ group: 'id',
+ usercore: 'id',
+ issue: 'id, state, title',
+ label: 'id, title',
+ milestone: 'id',
+});
diff --git a/app/assets/javascripts/lib/graphql.js b/app/assets/javascripts/lib/graphql.js
index c0e923b2670..150a1b16e58 100644
--- a/app/assets/javascripts/lib/graphql.js
+++ b/app/assets/javascripts/lib/graphql.js
@@ -1,7 +1,7 @@
import { ApolloClient, InMemoryCache, ApolloLink, HttpLink } from '@apollo/client/core';
import { BatchHttpLink } from '@apollo/client/link/batch-http';
import { createUploadLink } from 'apollo-upload-client';
-import { persistCacheSync, LocalStorageWrapper } from 'apollo3-cache-persist';
+import { persistCache } from 'apollo3-cache-persist';
import ActionCableLink from '~/actioncable_link';
import { apolloCaptchaLink } from '~/captcha/apollo_captcha_link';
import possibleTypes from '~/graphql_shared/possible_types.json';
@@ -104,7 +104,7 @@ Object.defineProperty(window, 'pendingApolloRequests', {
},
});
-export default (resolvers = {}, config = {}) => {
+function createApolloClient(resolvers = {}, config = {}) {
const {
baseUrl,
batchMax = 10,
@@ -113,7 +113,6 @@ export default (resolvers = {}, config = {}) => {
typeDefs,
path = '/api/graphql',
useGet = false,
- localCacheKey = null,
} = config;
let ac = null;
let uri = `${gon.relative_url_root || ''}${path}`;
@@ -237,16 +236,6 @@ export default (resolvers = {}, config = {}) => {
},
});
- if (localCacheKey) {
- persistCacheSync({
- cache: newCache,
- // we leave NODE_ENV here temporarily for visibility so developers can easily see caching happening in dev mode
- debug: process.env.NODE_ENV === 'development',
- storage: new LocalStorageWrapper(window.localStorage),
- persistenceMapper,
- });
- }
-
ac = new ApolloClient({
typeDefs,
link: appLink,
@@ -262,5 +251,42 @@ export default (resolvers = {}, config = {}) => {
acs.push(ac);
- return ac;
+ return { client: ac, cache: newCache };
+}
+
+export async function createApolloClientWithCaching(resolvers = {}, config = {}) {
+ const { localCacheKey = null } = config;
+ const { client, cache } = createApolloClient(resolvers, config);
+
+ if (localCacheKey) {
+ let storage;
+
+ // Test that we can use IndexedDB. If not, no persisting for you!
+ try {
+ const { IndexedDBPersistentStorage } = await import(
+ /* webpackChunkName: 'indexed_db_persistent_storage' */ './apollo/indexed_db_persistent_storage'
+ );
+
+ storage = await IndexedDBPersistentStorage.create();
+ } catch (error) {
+ return client;
+ }
+
+ await persistCache({
+ cache,
+ // we leave NODE_ENV here temporarily for visibility so developers can easily see caching happening in dev mode
+ debug: process.env.NODE_ENV === 'development',
+ storage,
+ key: localCacheKey,
+ persistenceMapper,
+ });
+ }
+
+ return client;
+}
+
+export default (resolvers = {}, config = {}) => {
+ const { client } = createApolloClient(resolvers, config);
+
+ return client;
};
diff --git a/app/assets/javascripts/notes/components/note_actions.vue b/app/assets/javascripts/notes/components/note_actions.vue
index 14497a239ca..bce17aebd64 100644
--- a/app/assets/javascripts/notes/components/note_actions.vue
+++ b/app/assets/javascripts/notes/components/note_actions.vue
@@ -367,7 +367,7 @@ export default {
@click="closeTooltip"
/>
<!-- eslint-enable @gitlab/vue-no-data-toggle -->
- <ul class="dropdown-menu more-actions-dropdown dropdown-open-left">
+ <ul class="dropdown-menu more-actions-dropdown dropdown-menu-right">
<gl-dropdown-item
v-if="canEdit"
class="js-note-edit gl-sm-display-none!"
diff --git a/app/views/layouts/minimal.html.haml b/app/views/layouts/minimal.html.haml
index b5cb8f2af37..b9008c4837c 100644
--- a/app/views/layouts/minimal.html.haml
+++ b/app/views/layouts/minimal.html.haml
@@ -11,7 +11,7 @@
.content-wrapper.content-wrapper-margin.gl-pt-6{ class: 'gl-md-pt-11!' }
.alert-wrapper.gl-force-block-formatting-context
= render "layouts/broadcast"
- .limit-container-width{ class: container_class }
+ %div{ class: container_class }
%main#content-body.content
= render "layouts/flash" unless @hide_flash
= yield
diff --git a/app/views/projects/mattermosts/new.html.haml b/app/views/projects/mattermosts/new.html.haml
index 8254198bd41..025ca1e1fd4 100644
--- a/app/views/projects/mattermosts/new.html.haml
+++ b/app/views/projects/mattermosts/new.html.haml
@@ -2,7 +2,6 @@
- add_to_breadcrumbs @integration.title, scoped_edit_integration_path(@integration, project: @project, group: @group)
- breadcrumb_title _('New')
- page_title @integration.title, _('Integrations')
-- @content_class = 'limit-container-width' unless fluid_layout
- if @teams_error_message
= render Pajamas::AlertComponent.new(variant: :danger) do |c|
diff --git a/app/views/projects/settings/packages_and_registries/cleanup_tags.html.haml b/app/views/projects/settings/packages_and_registries/cleanup_tags.html.haml
index 0f2fa7c2aaa..ad9ba0b506c 100644
--- a/app/views/projects/settings/packages_and_registries/cleanup_tags.html.haml
+++ b/app/views/projects/settings/packages_and_registries/cleanup_tags.html.haml
@@ -1,6 +1,5 @@
- add_to_breadcrumbs _('Packages and registries settings'), project_settings_packages_and_registries_path(@project)
- breadcrumb_title s_('ContainerRegistry|Cleanup policies')
- page_title s_('ContainerRegistry|Cleanup policies'), _('Packages and registries settings')
-- @content_class = 'limit-container-width' unless fluid_layout
#js-registry-settings-cleanup-image-tags{ data: cleanup_settings_data }
diff --git a/app/views/shared/integrations/edit.html.haml b/app/views/shared/integrations/edit.html.haml
index 0ae0eea59d8..9d613d2ad94 100644
--- a/app/views/shared/integrations/edit.html.haml
+++ b/app/views/shared/integrations/edit.html.haml
@@ -1,7 +1,6 @@
- add_to_breadcrumbs _('Integrations'), scoped_integrations_path(project: @project, group: @group)
- breadcrumb_title @integration.title
- page_title @integration.title, _('Integrations')
-- @content_class = 'limit-container-width' unless fluid_layout
%h2.gl-mb-4
= @integration.title
diff --git a/app/views/shared/integrations/overrides.html.haml b/app/views/shared/integrations/overrides.html.haml
index a63053bde0a..c25527a605c 100644
--- a/app/views/shared/integrations/overrides.html.haml
+++ b/app/views/shared/integrations/overrides.html.haml
@@ -1,7 +1,6 @@
- add_to_breadcrumbs _('Integrations'), scoped_integrations_path(project: @project, group: @group)
- breadcrumb_title @integration.title
- page_title @integration.title, _('Integrations')
-- @content_class = 'limit-container-width' unless fluid_layout
%h1.page-title.gl-font-size-h-display
= @integration.title
diff --git a/config/webpack.vendor.config.js b/config/webpack.vendor.config.js
index e02448b59af..a2a8f76cff3 100644
--- a/config/webpack.vendor.config.js
+++ b/config/webpack.vendor.config.js
@@ -25,25 +25,26 @@ module.exports = {
entry: {
vendor: [
- 'jquery/dist/jquery.slim.js',
+ '@apollo/client/core',
+ '@gitlab/at.js',
'core-js',
+ 'dexie',
+ 'dompurify',
'echarts',
- 'lodash',
- 'vuex',
- 'vue',
- 'pikaday',
- '@gitlab/at.js',
'jed',
- 'mermaid',
+ 'jquery/dist/jquery.slim.js',
'katex',
- 'three',
+ 'lodash',
+ 'mermaid',
'moment-mini',
- 'dompurify',
- 'sortablejs/modular/sortable.esm.js',
+ 'mousetrap',
+ 'pikaday',
'popper.js',
- '@apollo/client/core',
+ 'sortablejs/modular/sortable.esm.js',
'source-map',
- 'mousetrap',
+ 'three',
+ 'vue',
+ 'vuex',
],
},
diff --git a/doc/architecture/blueprints/_template.md b/doc/architecture/blueprints/_template.md
index 64b79f996e0..e22cc2e6857 100644
--- a/doc/architecture/blueprints/_template.md
+++ b/doc/architecture/blueprints/_template.md
@@ -55,6 +55,9 @@ Blueprint statuses you can use:
-->
+<!-- Blueprints often contain forward-looking statements -->
+<!-- vale gitlab.FutureTense = NO -->
+
# {+ Title of Blueprint +}
<!--
diff --git a/doc/architecture/blueprints/cells/cells-feature-admin-area.md b/doc/architecture/blueprints/cells/cells-feature-admin-area.md
index c4b096042be..31d5388d40b 100644
--- a/doc/architecture/blueprints/cells/cells-feature-admin-area.md
+++ b/doc/architecture/blueprints/cells/cells-feature-admin-area.md
@@ -4,6 +4,8 @@ group: Tenant Scale
description: 'Cells: Admin Area'
---
+<!-- vale gitlab.FutureTense = NO -->
+
This document is a work-in-progress and represents a very early state of the
Cells design. Significant aspects are not documented, though we expect to add
them in the future. This is one possible architecture for Cells, and we intend to
diff --git a/doc/architecture/blueprints/cells/cells-feature-agent-for-kubernetes.md b/doc/architecture/blueprints/cells/cells-feature-agent-for-kubernetes.md
index e136c36a760..37347cf836d 100644
--- a/doc/architecture/blueprints/cells/cells-feature-agent-for-kubernetes.md
+++ b/doc/architecture/blueprints/cells/cells-feature-agent-for-kubernetes.md
@@ -4,6 +4,8 @@ group: Tenant Scale
description: 'Cells: Agent for Kubernetes'
---
+<!-- vale gitlab.FutureTense = NO -->
+
This document is a work-in-progress and represents a very early state of the
Cells design. Significant aspects are not documented, though we expect to add
them in the future. This is one possible architecture for Cells, and we intend to
diff --git a/doc/architecture/blueprints/cells/cells-feature-backups.md b/doc/architecture/blueprints/cells/cells-feature-backups.md
index be1bef5bcb9..d596bdd2078 100644
--- a/doc/architecture/blueprints/cells/cells-feature-backups.md
+++ b/doc/architecture/blueprints/cells/cells-feature-backups.md
@@ -4,6 +4,8 @@ group: Tenant Scale
description: 'Cells: Backups'
---
+<!-- vale gitlab.FutureTense = NO -->
+
This document is a work-in-progress and represents a very early state of the
Cells design. Significant aspects are not documented, though we expect to add
them in the future. This is one possible architecture for Cells, and we intend to
diff --git a/doc/architecture/blueprints/cells/cells-feature-ci-runners.md b/doc/architecture/blueprints/cells/cells-feature-ci-runners.md
index 244321e2f42..e352be17dd3 100644
--- a/doc/architecture/blueprints/cells/cells-feature-ci-runners.md
+++ b/doc/architecture/blueprints/cells/cells-feature-ci-runners.md
@@ -4,6 +4,8 @@ group: Tenant Scale
description: 'Cells: CI Runners'
---
+<!-- vale gitlab.FutureTense = NO -->
+
This document is a work-in-progress and represents a very early state of the
Cells design. Significant aspects are not documented, though we expect to add
them in the future. This is one possible architecture for Cells, and we intend to
diff --git a/doc/architecture/blueprints/cells/cells-feature-container-registry.md b/doc/architecture/blueprints/cells/cells-feature-container-registry.md
index 53f68acca65..a5761808941 100644
--- a/doc/architecture/blueprints/cells/cells-feature-container-registry.md
+++ b/doc/architecture/blueprints/cells/cells-feature-container-registry.md
@@ -4,6 +4,8 @@ group: Tenant Scale
description: 'Cells: Container Registry'
---
+<!-- vale gitlab.FutureTense = NO -->
+
This document is a work-in-progress and represents a very early state of the
Cells design. Significant aspects are not documented, though we expect to add
them in the future. This is one possible architecture for Cells, and we intend to
diff --git a/doc/architecture/blueprints/cells/cells-feature-contributions-forks.md b/doc/architecture/blueprints/cells/cells-feature-contributions-forks.md
index eba58a24694..3e498c24144 100644
--- a/doc/architecture/blueprints/cells/cells-feature-contributions-forks.md
+++ b/doc/architecture/blueprints/cells/cells-feature-contributions-forks.md
@@ -4,6 +4,8 @@ group: Tenant Scale
description: 'Cells: Contributions: Forks'
---
+<!-- vale gitlab.FutureTense = NO -->
+
This document is a work-in-progress and represents a very early state of the
Cells design. Significant aspects are not documented, though we expect to add
them in the future. This is one possible architecture for Cells, and we intend to
diff --git a/doc/architecture/blueprints/cells/cells-feature-dashboard.md b/doc/architecture/blueprints/cells/cells-feature-dashboard.md
index 8a18f91013d..135f69c6ed3 100644
--- a/doc/architecture/blueprints/cells/cells-feature-dashboard.md
+++ b/doc/architecture/blueprints/cells/cells-feature-dashboard.md
@@ -4,6 +4,8 @@ group: Tenant Scale
description: 'Cells: Dashboard'
---
+<!-- vale gitlab.FutureTense = NO -->
+
This document is a work-in-progress and represents a very early state of the
Cells design. Significant aspects are not documented, though we expect to add
them in the future. This is one possible architecture for Cells, and we intend to
diff --git a/doc/architecture/blueprints/cells/cells-feature-data-migration.md b/doc/architecture/blueprints/cells/cells-feature-data-migration.md
index af6a9275d7c..ef0865b4081 100644
--- a/doc/architecture/blueprints/cells/cells-feature-data-migration.md
+++ b/doc/architecture/blueprints/cells/cells-feature-data-migration.md
@@ -4,6 +4,8 @@ group: Tenant Scale
description: 'Cells: Data migration'
---
+<!-- vale gitlab.FutureTense = NO -->
+
DISCLAIMER:
This page may contain information related to upcoming products, features and
functionality. It is important to note that the information presented is for
diff --git a/doc/architecture/blueprints/cells/cells-feature-database-sequences.md b/doc/architecture/blueprints/cells/cells-feature-database-sequences.md
index 9edfc7e7b16..d94dc3be864 100644
--- a/doc/architecture/blueprints/cells/cells-feature-database-sequences.md
+++ b/doc/architecture/blueprints/cells/cells-feature-database-sequences.md
@@ -4,6 +4,8 @@ group: Tenant Scale
description: 'Cells: Database Sequences'
---
+<!-- vale gitlab.FutureTense = NO -->
+
DISCLAIMER:
This page may contain information related to upcoming products, features and
functionality. It is important to note that the information presented is for
diff --git a/doc/architecture/blueprints/cells/cells-feature-git-access.md b/doc/architecture/blueprints/cells/cells-feature-git-access.md
index f10920324ba..70b3f136904 100644
--- a/doc/architecture/blueprints/cells/cells-feature-git-access.md
+++ b/doc/architecture/blueprints/cells/cells-feature-git-access.md
@@ -4,6 +4,8 @@ group: Tenant Scale
description: 'Cells: Git Access'
---
+<!-- vale gitlab.FutureTense = NO -->
+
This document is a work-in-progress and represents a very early state of the
Cells design. Significant aspects are not documented, though we expect to add
them in the future. This is one possible architecture for Cells, and we intend to
diff --git a/doc/architecture/blueprints/cells/cells-feature-gitlab-pages.md b/doc/architecture/blueprints/cells/cells-feature-gitlab-pages.md
index c91c1c35422..7e4ab785095 100644
--- a/doc/architecture/blueprints/cells/cells-feature-gitlab-pages.md
+++ b/doc/architecture/blueprints/cells/cells-feature-gitlab-pages.md
@@ -4,6 +4,8 @@ group: Tenant Scale
description: 'Cells: GitLab Pages'
---
+<!-- vale gitlab.FutureTense = NO -->
+
This document is a work-in-progress and represents a very early state of the
Cells design. Significant aspects are not documented, though we expect to add
them in the future. This is one possible architecture for Cells, and we intend to
diff --git a/doc/architecture/blueprints/cells/cells-feature-global-search.md b/doc/architecture/blueprints/cells/cells-feature-global-search.md
index a25efa4b19f..c1e2b93bc2d 100644
--- a/doc/architecture/blueprints/cells/cells-feature-global-search.md
+++ b/doc/architecture/blueprints/cells/cells-feature-global-search.md
@@ -4,6 +4,8 @@ group: Tenant Scale
description: 'Cells: Global search'
---
+<!-- vale gitlab.FutureTense = NO -->
+
DISCLAIMER:
This page may contain information related to upcoming products, features and
functionality. It is important to note that the information presented is for
diff --git a/doc/architecture/blueprints/cells/cells-feature-graphql.md b/doc/architecture/blueprints/cells/cells-feature-graphql.md
index f3054b7fab4..d936a1b81ba 100644
--- a/doc/architecture/blueprints/cells/cells-feature-graphql.md
+++ b/doc/architecture/blueprints/cells/cells-feature-graphql.md
@@ -4,6 +4,8 @@ group: Tenant Scale
description: 'Cells: GraphQL'
---
+<!-- vale gitlab.FutureTense = NO -->
+
DISCLAIMER:
This page may contain information related to upcoming products, features and
functionality. It is important to note that the information presented is for
diff --git a/doc/architecture/blueprints/cells/cells-feature-organizations.md b/doc/architecture/blueprints/cells/cells-feature-organizations.md
index 0cf0ad446e7..03178d9e6ce 100644
--- a/doc/architecture/blueprints/cells/cells-feature-organizations.md
+++ b/doc/architecture/blueprints/cells/cells-feature-organizations.md
@@ -4,6 +4,8 @@ group: Tenant Scale
description: 'Cells: Organizations'
---
+<!-- vale gitlab.FutureTense = NO -->
+
DISCLAIMER:
This page may contain information related to upcoming products, features and
functionality. It is important to note that the information presented is for
diff --git a/doc/architecture/blueprints/cells/cells-feature-personal-namespaces.md b/doc/architecture/blueprints/cells/cells-feature-personal-namespaces.md
index 22d3e5956dc..e8f5c250a8e 100644
--- a/doc/architecture/blueprints/cells/cells-feature-personal-namespaces.md
+++ b/doc/architecture/blueprints/cells/cells-feature-personal-namespaces.md
@@ -4,6 +4,8 @@ group: Tenant Scale
description: 'Cells: Personal Namespaces'
---
+<!-- vale gitlab.FutureTense = NO -->
+
This document is a work-in-progress and represents a very early state of the
Cells design. Significant aspects are not documented, though we expect to add
them in the future. This is one possible architecture for Cells, and we intend to
diff --git a/doc/architecture/blueprints/cells/cells-feature-router-endpoints-classification.md b/doc/architecture/blueprints/cells/cells-feature-router-endpoints-classification.md
index e005b3bed8d..7c2974ca258 100644
--- a/doc/architecture/blueprints/cells/cells-feature-router-endpoints-classification.md
+++ b/doc/architecture/blueprints/cells/cells-feature-router-endpoints-classification.md
@@ -4,6 +4,8 @@ group: Tenant Scale
description: 'Cells: Router Endpoints Classification'
---
+<!-- vale gitlab.FutureTense = NO -->
+
DISCLAIMER:
This page may contain information related to upcoming products, features and
functionality. It is important to note that the information presented is for
diff --git a/doc/architecture/blueprints/cells/cells-feature-schema-changes.md b/doc/architecture/blueprints/cells/cells-feature-schema-changes.md
index b1e430eec66..d712b24a8a0 100644
--- a/doc/architecture/blueprints/cells/cells-feature-schema-changes.md
+++ b/doc/architecture/blueprints/cells/cells-feature-schema-changes.md
@@ -4,6 +4,8 @@ group: Tenant Scale
description: 'Cells: Schema changes'
---
+<!-- vale gitlab.FutureTense = NO -->
+
DISCLAIMER:
This page may contain information related to upcoming products, features and
functionality. It is important to note that the information presented is for
diff --git a/doc/architecture/blueprints/cells/cells-feature-secrets.md b/doc/architecture/blueprints/cells/cells-feature-secrets.md
index f6fd18eb168..20260c89ccd 100644
--- a/doc/architecture/blueprints/cells/cells-feature-secrets.md
+++ b/doc/architecture/blueprints/cells/cells-feature-secrets.md
@@ -4,6 +4,8 @@ group: Tenant Scale
description: 'Cells: Secrets'
---
+<!-- vale gitlab.FutureTense = NO -->
+
This document is a work-in-progress and represents a very early state of the
Cells design. Significant aspects are not documented, though we expect to add
them in the future. This is one possible architecture for Cells, and we intend to
diff --git a/doc/architecture/blueprints/cells/cells-feature-snippets.md b/doc/architecture/blueprints/cells/cells-feature-snippets.md
index 2b64dacfbd3..f5e72c0e3a0 100644
--- a/doc/architecture/blueprints/cells/cells-feature-snippets.md
+++ b/doc/architecture/blueprints/cells/cells-feature-snippets.md
@@ -4,6 +4,8 @@ group: Tenant Scale
description: 'Cells: Snippets'
---
+<!-- vale gitlab.FutureTense = NO -->
+
This document is a work-in-progress and represents a very early state of the
Cells design. Significant aspects are not documented, though we expect to add
them in the future. This is one possible architecture for Cells, and we intend to
diff --git a/doc/architecture/blueprints/cells/cells-feature-template.md b/doc/architecture/blueprints/cells/cells-feature-template.md
index 394002a68a7..3cece3dc99e 100644
--- a/doc/architecture/blueprints/cells/cells-feature-template.md
+++ b/doc/architecture/blueprints/cells/cells-feature-template.md
@@ -4,6 +4,8 @@ group: Tenant Scale
description: 'Cells: Problem A'
---
+<!-- vale gitlab.FutureTense = NO -->
+
This document is a work-in-progress and represents a very early state of the
Cells design. Significant aspects are not documented, though we expect to add
them in the future. This is one possible architecture for Cells, and we intend to
diff --git a/doc/architecture/blueprints/cells/cells-feature-uploads.md b/doc/architecture/blueprints/cells/cells-feature-uploads.md
index 15c65089e18..fdac3a9977c 100644
--- a/doc/architecture/blueprints/cells/cells-feature-uploads.md
+++ b/doc/architecture/blueprints/cells/cells-feature-uploads.md
@@ -4,6 +4,8 @@ group: Tenant Scale
description: 'Cells: Uploads'
---
+<!-- vale gitlab.FutureTense = NO -->
+
This document is a work-in-progress and represents a very early state of the
Cells design. Significant aspects are not documented, though we expect to add
them in the future. This is one possible architecture for Cells, and we intend to
diff --git a/doc/architecture/blueprints/cells/index.md b/doc/architecture/blueprints/cells/index.md
index f3839d54e09..1fa53222827 100644
--- a/doc/architecture/blueprints/cells/index.md
+++ b/doc/architecture/blueprints/cells/index.md
@@ -8,6 +8,8 @@ owning-stage: "~devops::enablement"
participating-stages: []
---
+<!-- vale gitlab.FutureTense = NO -->
+
# Cells
This document is a work-in-progress and represents a very early state of the Cells design. Significant aspects are not documented, though we expect to add them in the future.
diff --git a/doc/architecture/blueprints/cells/proposal-stateless-router-with-buffering-requests.md b/doc/architecture/blueprints/cells/proposal-stateless-router-with-buffering-requests.md
index d241701898c..ebf08c88ef6 100644
--- a/doc/architecture/blueprints/cells/proposal-stateless-router-with-buffering-requests.md
+++ b/doc/architecture/blueprints/cells/proposal-stateless-router-with-buffering-requests.md
@@ -4,6 +4,8 @@ group: Tenant Scale
description: 'Cells Stateless Router Proposal'
---
+<!-- vale gitlab.FutureTense = NO -->
+
This document is a work-in-progress and represents a very early state of the
Pods design. Significant aspects are not documented, though we expect to add
them in the future. This is one possible architecture for Pods, and we intend to
diff --git a/doc/architecture/blueprints/cells/proposal-stateless-router-with-routes-learning.md b/doc/architecture/blueprints/cells/proposal-stateless-router-with-routes-learning.md
index 826c74da83e..7602a9d3f4d 100644
--- a/doc/architecture/blueprints/cells/proposal-stateless-router-with-routes-learning.md
+++ b/doc/architecture/blueprints/cells/proposal-stateless-router-with-routes-learning.md
@@ -4,6 +4,8 @@ group: Tenant Scale
description: 'Cells Stateless Router Proposal'
---
+<!-- vale gitlab.FutureTense = NO -->
+
This document is a work-in-progress and represents a very early state of the
Cells design. Significant aspects are not documented, though we expect to add
them in the future. This is one possible architecture for Cells, and we intend to
diff --git a/doc/architecture/blueprints/ci_data_decay/index.md b/doc/architecture/blueprints/ci_data_decay/index.md
index d65764f83b6..2eac27def18 100644
--- a/doc/architecture/blueprints/ci_data_decay/index.md
+++ b/doc/architecture/blueprints/ci_data_decay/index.md
@@ -8,6 +8,8 @@ owning-stage: "~devops::verify"
participating-stages: []
---
+<!-- vale gitlab.FutureTense = NO -->
+
# CI/CD data time decay
## Summary
diff --git a/doc/architecture/blueprints/ci_data_decay/pipeline_partitioning.md b/doc/architecture/blueprints/ci_data_decay/pipeline_partitioning.md
index ff4424a5e87..5dea1090507 100644
--- a/doc/architecture/blueprints/ci_data_decay/pipeline_partitioning.md
+++ b/doc/architecture/blueprints/ci_data_decay/pipeline_partitioning.md
@@ -8,6 +8,8 @@ owning-stage: "~devops::verify"
description: 'Pipeline data partitioning design'
---
+<!-- vale gitlab.FutureTense = NO -->
+
# Pipeline data partitioning design
## What problem are we trying to solve?
diff --git a/doc/architecture/blueprints/ci_pipeline_components/index.md b/doc/architecture/blueprints/ci_pipeline_components/index.md
index 6d8e87d2dd4..f482262fa72 100644
--- a/doc/architecture/blueprints/ci_pipeline_components/index.md
+++ b/doc/architecture/blueprints/ci_pipeline_components/index.md
@@ -8,6 +8,8 @@ owning-stage: "~devops::verify"
participating-stages: []
---
+<!-- vale gitlab.FutureTense = NO -->
+
# CI/CD Catalog
## Summary
diff --git a/doc/architecture/blueprints/ci_scale/index.md b/doc/architecture/blueprints/ci_scale/index.md
index adb62ecf68a..3a6ed4ae9b1 100644
--- a/doc/architecture/blueprints/ci_scale/index.md
+++ b/doc/architecture/blueprints/ci_scale/index.md
@@ -7,6 +7,8 @@ approvers: [ "@cheryl.li", "@jreporter" ]
owning-stage: "~devops::verify"
---
+<!-- vale gitlab.FutureTense = NO -->
+
# CI/CD Scaling
## Summary
diff --git a/doc/architecture/blueprints/clickhouse_usage/index.md b/doc/architecture/blueprints/clickhouse_usage/index.md
index 2781ea15a55..610ff81f571 100644
--- a/doc/architecture/blueprints/clickhouse_usage/index.md
+++ b/doc/architecture/blueprints/clickhouse_usage/index.md
@@ -8,6 +8,8 @@ owning-stage: "~devops::data_stores"
participating-stages: ["~section::ops", "~section::dev"]
---
+<!-- vale gitlab.FutureTense = NO -->
+
# ClickHouse Usage at GitLab
## Summary
diff --git a/doc/architecture/blueprints/code_search_with_zoekt/index.md b/doc/architecture/blueprints/code_search_with_zoekt/index.md
index ca74460b98a..db608b763b8 100644
--- a/doc/architecture/blueprints/code_search_with_zoekt/index.md
+++ b/doc/architecture/blueprints/code_search_with_zoekt/index.md
@@ -8,6 +8,8 @@ owning-stage: "~devops::enablement"
participating-stages: []
---
+<!-- vale gitlab.FutureTense = NO -->
+
# Use Zoekt For code search
## Summary
diff --git a/doc/architecture/blueprints/composable_codebase_using_rails_engines/index.md b/doc/architecture/blueprints/composable_codebase_using_rails_engines/index.md
index 12254fa7920..5b82716cb21 100644
--- a/doc/architecture/blueprints/composable_codebase_using_rails_engines/index.md
+++ b/doc/architecture/blueprints/composable_codebase_using_rails_engines/index.md
@@ -8,6 +8,8 @@ owning-stage: "~devops::non_devops"
participating-stages: []
---
+<!-- vale gitlab.FutureTense = NO -->
+
# Composable GitLab Codebase
NOTE:
diff --git a/doc/architecture/blueprints/consolidating_groups_and_projects/index.md b/doc/architecture/blueprints/consolidating_groups_and_projects/index.md
index 88034f60caf..56f46d27e8e 100644
--- a/doc/architecture/blueprints/consolidating_groups_and_projects/index.md
+++ b/doc/architecture/blueprints/consolidating_groups_and_projects/index.md
@@ -9,6 +9,8 @@ owning-stage: "~devops::data_stores"
participating-stages: []
---
+<!-- vale gitlab.FutureTense = NO -->
+
# Consolidating Groups and Projects
There are numerous features that exist exclusively within groups or
diff --git a/doc/architecture/blueprints/container_registry_metadata_database/index.md b/doc/architecture/blueprints/container_registry_metadata_database/index.md
index f3bcf1e4e59..b77aaf598e6 100644
--- a/doc/architecture/blueprints/container_registry_metadata_database/index.md
+++ b/doc/architecture/blueprints/container_registry_metadata_database/index.md
@@ -8,6 +8,8 @@ owning-stage: "~devops::package"
participating-stages: []
---
+<!-- vale gitlab.FutureTense = NO -->
+
# Container Registry Metadata Database
## Usage of the GitLab Container Registry
diff --git a/doc/architecture/blueprints/database_testing/index.md b/doc/architecture/blueprints/database_testing/index.md
index 4e142a9345c..79560dd3959 100644
--- a/doc/architecture/blueprints/database_testing/index.md
+++ b/doc/architecture/blueprints/database_testing/index.md
@@ -8,6 +8,8 @@ owning-stage: "~devops::data_stores"
participating-stages: []
---
+<!-- vale gitlab.FutureTense = NO -->
+
# Database Testing
**Notice:** This blueprint has been partially implemented. We still plan to
diff --git a/doc/architecture/blueprints/gitlab_agent_deployments/index.md b/doc/architecture/blueprints/gitlab_agent_deployments/index.md
index 0e5b5f0b248..d8d26389d7d 100644
--- a/doc/architecture/blueprints/gitlab_agent_deployments/index.md
+++ b/doc/architecture/blueprints/gitlab_agent_deployments/index.md
@@ -8,6 +8,8 @@ owning-stage: "~devops::release"
participating-stages: [Configure, Release]
---
+<!-- vale gitlab.FutureTense = NO -->
+
# View and manage resources deployed by GitLab Agent For Kuberenetes
## Summary
diff --git a/doc/architecture/blueprints/gitlab_observability_backend/metrics/index.md b/doc/architecture/blueprints/gitlab_observability_backend/metrics/index.md
index 82d1596bc90..3edb01d9140 100644
--- a/doc/architecture/blueprints/gitlab_observability_backend/metrics/index.md
+++ b/doc/architecture/blueprints/gitlab_observability_backend/metrics/index.md
@@ -8,6 +8,8 @@ owning-stage: "~monitor::observability"
participating-stages: []
---
+<!-- vale gitlab.FutureTense = NO -->
+
# GitLab Observability Backend - Metrics
## Summary
diff --git a/doc/architecture/blueprints/graphql_api/index.md b/doc/architecture/blueprints/graphql_api/index.md
index 95ff834cd27..2c277049434 100644
--- a/doc/architecture/blueprints/graphql_api/index.md
+++ b/doc/architecture/blueprints/graphql_api/index.md
@@ -8,6 +8,8 @@ owning-stage: "~devops::manage"
participating-stages: []
---
+<!-- vale gitlab.FutureTense = NO -->
+
# GraphQL API
[GraphQL](https://graphql.org/) is a data query and manipulation language for
diff --git a/doc/architecture/blueprints/object_storage/index.md b/doc/architecture/blueprints/object_storage/index.md
index 6718705a7c8..5d83d5058a0 100644
--- a/doc/architecture/blueprints/object_storage/index.md
+++ b/doc/architecture/blueprints/object_storage/index.md
@@ -8,6 +8,8 @@ owning-stage: "~devops::data_stores"
participating-stages: []
---
+<!-- vale gitlab.FutureTense = NO -->
+
# Object storage: `direct_upload` consolidation
## Abstract
diff --git a/doc/architecture/blueprints/rate_limiting/index.md b/doc/architecture/blueprints/rate_limiting/index.md
index 92364040962..17808267032 100644
--- a/doc/architecture/blueprints/rate_limiting/index.md
+++ b/doc/architecture/blueprints/rate_limiting/index.md
@@ -8,6 +8,8 @@ owning-stage: "~devops::enablement"
participating-stages: []
---
+<!-- vale gitlab.FutureTense = NO -->
+
# Next Rate Limiting Architecture
## Summary
diff --git a/doc/architecture/blueprints/remote_development/index.md b/doc/architecture/blueprints/remote_development/index.md
index 162ae04f6b6..01b72ccdcfb 100644
--- a/doc/architecture/blueprints/remote_development/index.md
+++ b/doc/architecture/blueprints/remote_development/index.md
@@ -8,6 +8,8 @@ owning-stage: "~devops::create"
participating-stages: []
---
+<!-- vale gitlab.FutureTense = NO -->
+
# Remote Development
## Summary
diff --git a/doc/architecture/blueprints/runner_scaling/index.md b/doc/architecture/blueprints/runner_scaling/index.md
index 53401d80e34..421b380a9f7 100644
--- a/doc/architecture/blueprints/runner_scaling/index.md
+++ b/doc/architecture/blueprints/runner_scaling/index.md
@@ -8,6 +8,8 @@ owning-stage: "~devops::verify"
participating-stages: []
---
+<!-- vale gitlab.FutureTense = NO -->
+
# Next Runner Auto-scaling Architecture
## Summary
diff --git a/doc/architecture/blueprints/runner_tokens/index.md b/doc/architecture/blueprints/runner_tokens/index.md
index 359eadb18c5..0e70b97d2c7 100644
--- a/doc/architecture/blueprints/runner_tokens/index.md
+++ b/doc/architecture/blueprints/runner_tokens/index.md
@@ -8,6 +8,8 @@ owning-stage: "~devops::verify"
participating-stages: []
---
+<!-- vale gitlab.FutureTense = NO -->
+
# Next GitLab Runner Token Architecture
## Summary
diff --git a/doc/architecture/blueprints/secret_detection/index.md b/doc/architecture/blueprints/secret_detection/index.md
index 5dca2efcf37..9911fd04667 100644
--- a/doc/architecture/blueprints/secret_detection/index.md
+++ b/doc/architecture/blueprints/secret_detection/index.md
@@ -8,6 +8,8 @@ owning-stage: "~devops::secure"
participating-stages: []
---
+<!-- vale gitlab.FutureTense = NO -->
+
# Secret Detection as a platform-wide experience
## Summary
diff --git a/doc/architecture/blueprints/work_items/index.md b/doc/architecture/blueprints/work_items/index.md
index 2c854ecea59..f067d9fab52 100644
--- a/doc/architecture/blueprints/work_items/index.md
+++ b/doc/architecture/blueprints/work_items/index.md
@@ -8,6 +8,8 @@ owning-stage: "~devops::plan"
participating-stages: []
---
+<!-- vale gitlab.FutureTense = NO -->
+
# Work Items
This document is a work-in-progress. Some aspects are not documented, though we expect to add them in the future.
diff --git a/doc/user/admin_area/custom_project_templates.md b/doc/user/admin_area/custom_project_templates.md
index 78819def5de..ea42596059e 100644
--- a/doc/user/admin_area/custom_project_templates.md
+++ b/doc/user/admin_area/custom_project_templates.md
@@ -41,6 +41,24 @@ To select the group to use as the source for the project templates:
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
diff --git a/doc/user/application_security/policies/index.md b/doc/user/application_security/policies/index.md
index 1f53b671ed1..6f6b4390b7d 100644
--- a/doc/user/application_security/policies/index.md
+++ b/doc/user/application_security/policies/index.md
@@ -24,8 +24,12 @@ GitLab supports the following security policies:
All security policies are stored as YAML in a separate security policy project that gets linked to
the development project, group, or sub-group. This association can be a one-to-many relationship, allowing one security
-policy project to apply to multiple development projects, groups, or sub-groups. Linked projects are not required to be in
-the same group as the development projects to which they are linked.
+policy project to apply to multiple development projects, groups, or sub-groups:
+
+- For self-managed GitLab instances, linked projects are not required to be in the same group
+ or the same subgroup as the development projects to which they are linked.
+- For GitLab SaaS, the security policy project is required to be in the same top-level group
+ as the development project, although, it is not necessary for the project to be in the same subgroup.
![Security Policy Project Linking Diagram](img/association_diagram.png)
diff --git a/doc/user/group/index.md b/doc/user/group/index.md
index fc904ed5779..5fe8931f794 100644
--- a/doc/user/group/index.md
+++ b/doc/user/group/index.md
@@ -21,7 +21,14 @@ For larger organizations, you can also create [subgroups](subgroups/index.md).
For more information about creating and managing your groups, see [Manage groups](manage.md).
NOTE:
-Self-managed customers should create a top-level group so you can see an overview of your organization. We are working on creating an [organization view](https://gitlab.com/groups/gitlab-org/-/epics/9266), so you can see all groups.
+Self-managed customers should create a top-level group so you can see an overview of
+your organization. For more information about efforts to create an
+organization view of all groups, [see epic 9266](https://gitlab.com/groups/gitlab-org/-/epics/9266).
+A top-level group can also have one complete
+[Security Dashboard and Center](../application_security/security_dashboard/index.md),
+[Vulnerability](../application_security/vulnerability_report/index.md#vulnerability-report) and
+[Compliance Report](../compliance/compliance_report/index.md), and
+[Value stream analytics](../group/value_stream_analytics/index.md#value-stream-analytics-for-groups).
## Group visibility
diff --git a/doc/user/group/manage.md b/doc/user/group/manage.md
index eadcf67dabe..695786a84d5 100644
--- a/doc/user/group/manage.md
+++ b/doc/user/group/manage.md
@@ -9,7 +9,14 @@ info: To determine the technical writer assigned to the Stage/Group associated w
Use groups to manage one or more related projects at the same time.
NOTE:
-Self-managed customers should create a top-level group so you can see an overview of your organization. We are working on creating an [organization view](https://gitlab.com/groups/gitlab-org/-/epics/9266), so you can see all groups.
+Self-managed customers should create a top-level group so you can see an overview of
+your organization. For more information about efforts to create an
+organization view of all groups, [see epic 9266](https://gitlab.com/groups/gitlab-org/-/epics/9266).
+A top-level group can also have one complete
+[Security Dashboard and Center](../application_security/security_dashboard/index.md),
+[Vulnerability](../application_security/vulnerability_report/index.md#vulnerability-report) and
+[Compliance Report](../compliance/compliance_report/index.md), and
+[Value stream analytics](../group/value_stream_analytics/index.md#value-stream-analytics-for-groups).
## View groups
diff --git a/jest.config.base.js b/jest.config.base.js
index 3394d8c7742..08ee2d87a60 100644
--- a/jest.config.base.js
+++ b/jest.config.base.js
@@ -114,6 +114,7 @@ module.exports = (path, options = {}) => {
'^ee_else_ce_jest/(.*)$': '<rootDir>/spec/frontend/$1',
'^jquery$': '<rootDir>/node_modules/jquery/dist/jquery.slim.js',
'^@sentry/browser$': '<rootDir>/app/assets/javascripts/sentry/sentry_browser_wrapper.js',
+ '^dexie$': '<rootDir>/node_modules/dexie/dist/dexie.min.js',
...extModuleNameMapper,
...vueModuleNameMappers,
};
@@ -207,6 +208,7 @@ module.exports = (path, options = {}) => {
'lowlight',
'vscode-languageserver-types',
'yaml',
+ 'dexie',
...gfmParserDependencies,
];
diff --git a/lib/backup/gitaly_backup.rb b/lib/backup/gitaly_backup.rb
index 354025ffb85..53c998efd71 100644
--- a/lib/backup/gitaly_backup.rb
+++ b/lib/backup/gitaly_backup.rb
@@ -9,14 +9,15 @@ module Backup
# @param [StringIO] progress IO interface to output progress
# @param [Integer] max_parallelism max parallelism when running backups
# @param [Integer] storage_parallelism max parallelism per storage (is affected by max_parallelism)
- def initialize(progress, max_parallelism: nil, storage_parallelism: nil, incremental: false, backup_id: nil)
+ # @param [Boolean] incremental if incremental backups should be created.
+ def initialize(progress, max_parallelism: nil, storage_parallelism: nil, incremental: false)
@progress = progress
@max_parallelism = max_parallelism
@storage_parallelism = storage_parallelism
@incremental = incremental
end
- def start(type, backup_repos_path, backup_id: nil)
+ def start(type, backup_repos_path, backup_id: nil, remove_all_repositories: nil)
raise Error, 'already started' if started?
if type == :create && !incremental?
@@ -35,9 +36,13 @@ module Backup
args = ['-layout', 'pointer']
args += ['-parallel', @max_parallelism.to_s] if @max_parallelism
args += ['-parallel-storage', @storage_parallelism.to_s] if @storage_parallelism
- if type == :create
+
+ case type
+ when :create
args += ['-incremental'] if incremental?
args += ['-id', backup_id] if backup_id
+ when :restore
+ args += ['-remove-all-repositories', remove_all_repositories.join(',')] if remove_all_repositories
end
@input_stream, stdout, @thread = Open3.popen2(build_env, bin_path, command, '-path', backup_repos_path, *args)
diff --git a/lib/backup/repositories.rb b/lib/backup/repositories.rb
index 4f4a098f374..218df3fcb6c 100644
--- a/lib/backup/repositories.rb
+++ b/lib/backup/repositories.rb
@@ -30,7 +30,7 @@ module Backup
override :restore
def restore(destination_path)
- strategy.start(:restore, destination_path)
+ strategy.start(:restore, destination_path, remove_all_repositories: remove_all_repositories)
enqueue_consecutive
ensure
@@ -44,6 +44,12 @@ module Backup
attr_reader :strategy, :storages, :paths
+ def remove_all_repositories
+ return if paths.present?
+
+ storages.presence || Gitlab.config.repositories.storages.keys
+ end
+
def enqueue_consecutive
enqueue_consecutive_projects
enqueue_consecutive_snippets
diff --git a/package.json b/package.json
index 262c823f077..4aadf6bf911 100644
--- a/package.json
+++ b/package.json
@@ -123,6 +123,7 @@
"d3-selection": "^1.2.0",
"dateformat": "^5.0.1",
"deckar01-task_list": "^2.3.1",
+ "dexie": "^3.2.3",
"diff": "^3.4.0",
"dompurify": "^2.4.5",
"dropzone": "^4.2.0",
@@ -237,6 +238,7 @@
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-no-jquery": "2.7.0",
"eslint-plugin-no-unsanitized": "^4.0.2",
+ "fake-indexeddb": "^4.0.1",
"gettext-extractor": "^3.7.0",
"gettext-extractor-vue": "^5.1.0",
"glob": "^7.1.6",
diff --git a/qa/qa/specs/features/browser_ui/8_monitor/alert_management/recovery_alert_resolves_correct_alert_spec.rb b/qa/qa/specs/features/browser_ui/8_monitor/alert_management/recovery_alert_resolves_correct_alert_spec.rb
index 433d286686b..af088d2978a 100644
--- a/qa/qa/specs/features/browser_ui/8_monitor/alert_management/recovery_alert_resolves_correct_alert_spec.rb
+++ b/qa/qa/specs/features/browser_ui/8_monitor/alert_management/recovery_alert_resolves_correct_alert_spec.rb
@@ -26,7 +26,12 @@ module QA
context(
'when using HTTP endpoint integration',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/393589'
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/393589',
+ quarantine: {
+ only: { pipeline: :nightly },
+ type: :bug,
+ issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/395512'
+ }
) do
include_context 'sends and resolves test alerts'
diff --git a/qa/qa/specs/features/browser_ui/8_monitor/incident_management/recovery_alert_closes_correct_incident_spec.rb b/qa/qa/specs/features/browser_ui/8_monitor/incident_management/recovery_alert_closes_correct_incident_spec.rb
index fe3cd5a432b..aadca29de0c 100644
--- a/qa/qa/specs/features/browser_ui/8_monitor/incident_management/recovery_alert_closes_correct_incident_spec.rb
+++ b/qa/qa/specs/features/browser_ui/8_monitor/incident_management/recovery_alert_closes_correct_incident_spec.rb
@@ -27,7 +27,12 @@ module QA
context(
'when using HTTP endpoint integration',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/393842'
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/393842',
+ quarantine: {
+ only: { pipeline: :nightly },
+ type: :bug,
+ issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/403596'
+ }
) do
include_context 'sends and resolves test alerts'
diff --git a/spec/frontend/ide/components/new_dropdown/index_spec.js b/spec/frontend/ide/components/new_dropdown/index_spec.js
index 01dcb174c41..a2371abe955 100644
--- a/spec/frontend/ide/components/new_dropdown/index_spec.js
+++ b/spec/frontend/ide/components/new_dropdown/index_spec.js
@@ -1,33 +1,50 @@
-import { mount } from '@vue/test-utils';
+import Vue from 'vue';
+import Vuex from 'vuex';
+import { mountExtended } from 'helpers/vue_test_utils_helper';
import NewDropdown from '~/ide/components/new_dropdown/index.vue';
import Button from '~/ide/components/new_dropdown/button.vue';
-import { createStore } from '~/ide/stores';
+import Modal from '~/ide/components/new_dropdown/modal.vue';
+import { stubComponent } from 'helpers/stub_component';
+
+Vue.use(Vuex);
describe('new dropdown component', () => {
let wrapper;
+ const openMock = jest.fn();
+ const deleteEntryMock = jest.fn();
const findAllButtons = () => wrapper.findAllComponents(Button);
- const mountComponent = () => {
- const store = createStore();
- store.state.currentProjectId = 'abcproject';
- store.state.path = '';
- store.state.trees['abcproject/mybranch'] = { tree: [] };
+ const mountComponent = (props = {}) => {
+ const fakeStore = () => {
+ return new Vuex.Store({
+ actions: {
+ deleteEntry: deleteEntryMock,
+ },
+ });
+ };
- wrapper = mount(NewDropdown, {
- store,
+ wrapper = mountExtended(NewDropdown, {
+ store: fakeStore(),
propsData: {
branch: 'main',
path: '',
mouseOver: false,
type: 'tree',
+ ...props,
+ },
+ stubs: {
+ NewModal: stubComponent(Modal, {
+ methods: {
+ open: openMock,
+ },
+ }),
},
});
};
beforeEach(() => {
mountComponent();
- jest.spyOn(wrapper.vm.$refs.newModal, 'open').mockImplementation(() => {});
});
it('renders new file, upload and new directory links', () => {
@@ -38,37 +55,34 @@ describe('new dropdown component', () => {
describe('createNewItem', () => {
it('opens modal for a blob when new file is clicked', () => {
- findAllButtons().at(0).trigger('click');
+ findAllButtons().at(0).vm.$emit('click');
- expect(wrapper.vm.$refs.newModal.open).toHaveBeenCalledWith('blob', '');
+ expect(openMock).toHaveBeenCalledWith('blob', '');
});
it('opens modal for a tree when new directory is clicked', () => {
- findAllButtons().at(2).trigger('click');
+ findAllButtons().at(2).vm.$emit('click');
- expect(wrapper.vm.$refs.newModal.open).toHaveBeenCalledWith('tree', '');
+ expect(openMock).toHaveBeenCalledWith('tree', '');
});
});
describe('isOpen', () => {
it('scrolls dropdown into view', async () => {
- jest.spyOn(wrapper.vm.$refs.dropdownMenu, 'scrollIntoView').mockImplementation(() => {});
+ const dropdownMenu = wrapper.findByTestId('dropdown-menu');
+ const scrollIntoViewSpy = jest.spyOn(dropdownMenu.element, 'scrollIntoView');
await wrapper.setProps({ isOpen: true });
- expect(wrapper.vm.$refs.dropdownMenu.scrollIntoView).toHaveBeenCalledWith({
- block: 'nearest',
- });
+ expect(scrollIntoViewSpy).toHaveBeenCalledWith({ block: 'nearest' });
});
});
describe('delete entry', () => {
it('calls delete action', () => {
- jest.spyOn(wrapper.vm, 'deleteEntry').mockImplementation(() => {});
-
findAllButtons().at(4).trigger('click');
- expect(wrapper.vm.deleteEntry).toHaveBeenCalledWith('');
+ expect(deleteEntryMock).toHaveBeenCalledWith(expect.anything(), '');
});
});
});
diff --git a/spec/frontend/lib/apollo/indexed_db_persistent_storage_spec.js b/spec/frontend/lib/apollo/indexed_db_persistent_storage_spec.js
new file mode 100644
index 00000000000..f96364a918e
--- /dev/null
+++ b/spec/frontend/lib/apollo/indexed_db_persistent_storage_spec.js
@@ -0,0 +1,90 @@
+import { IndexedDBPersistentStorage } from '~/lib/apollo/indexed_db_persistent_storage';
+import { db } from '~/lib/apollo/local_db';
+import CACHE_WITH_PERSIST_DIRECTIVE_AND_FIELDS from './mock_data/cache_with_persist_directive_and_field.json';
+
+describe('IndexedDBPersistentStorage', () => {
+ let subject;
+
+ const seedData = async (cacheKey, data = CACHE_WITH_PERSIST_DIRECTIVE_AND_FIELDS) => {
+ const { ROOT_QUERY, ...rest } = data;
+
+ await db.table('queries').put(ROOT_QUERY, cacheKey);
+
+ const asyncPuts = Object.entries(rest).map(async ([key, value]) => {
+ const {
+ groups: { type, gid },
+ } = /^(?<type>.+?):(?<gid>.+)$/.exec(key);
+ const tableName = type.toLowerCase();
+
+ if (tableName !== 'projectmember' && tableName !== 'groupmember') {
+ await db.table(tableName).put(value, gid);
+ }
+ });
+
+ await Promise.all(asyncPuts);
+ };
+
+ beforeEach(async () => {
+ subject = await IndexedDBPersistentStorage.create();
+ });
+
+ afterEach(() => {
+ db.close();
+ });
+
+ it('returns empty response if there is nothing stored in the DB', async () => {
+ const result = await subject.getItem('some-query');
+
+ expect(result).toEqual({});
+ });
+
+ it('returns stored cache if cache was persisted in IndexedDB', async () => {
+ await seedData('issues_list', CACHE_WITH_PERSIST_DIRECTIVE_AND_FIELDS);
+
+ const result = await subject.getItem('issues_list');
+ expect(result).toEqual(CACHE_WITH_PERSIST_DIRECTIVE_AND_FIELDS);
+ });
+
+ it('puts the results in database on `setItem` call', async () => {
+ await subject.setItem(
+ 'issues_list',
+ JSON.stringify({
+ ROOT_QUERY: 'ROOT_QUERY_KEY',
+ 'Project:gid://gitlab/Project/6': {
+ __typename: 'Project',
+ id: 'gid://gitlab/Project/6',
+ },
+ }),
+ );
+
+ await expect(db.table('queries').get('issues_list')).resolves.toEqual('ROOT_QUERY_KEY');
+ await expect(db.table('project').get('gid://gitlab/Project/6')).resolves.toEqual({
+ __typename: 'Project',
+ id: 'gid://gitlab/Project/6',
+ });
+ });
+
+ it('does not put results into non-existent table', async () => {
+ const queryId = 'issues_list';
+
+ await subject.setItem(
+ queryId,
+ JSON.stringify({
+ ROOT_QUERY: 'ROOT_QUERY_KEY',
+ 'DNE:gid://gitlab/DNE/1': {},
+ }),
+ );
+
+ expect(db.tables.map((x) => x.name)).not.toContain('dne');
+ });
+
+ it('when removeItem is called, clears all data', async () => {
+ await seedData('issues_list', CACHE_WITH_PERSIST_DIRECTIVE_AND_FIELDS);
+
+ await subject.removeItem();
+
+ const actual = await Promise.all(db.tables.map((x) => x.toArray()));
+
+ expect(actual).toEqual(db.tables.map(() => []));
+ });
+});
diff --git a/spec/frontend/lib/apollo/mock_data/cache_with_persist_directive_and_field.json b/spec/frontend/lib/apollo/mock_data/cache_with_persist_directive_and_field.json
index c0651517986..0dfc2240cc3 100644
--- a/spec/frontend/lib/apollo/mock_data/cache_with_persist_directive_and_field.json
+++ b/spec/frontend/lib/apollo/mock_data/cache_with_persist_directive_and_field.json
@@ -171,38 +171,6 @@
}
]
},
- "projectMembers({\"relations\":[\"DIRECT\",\"INHERITED\",\"INVITED_GROUPS\"],\"search\":\"\"})": {
- "__typename": "MemberInterfaceConnection",
- "nodes": [
- {
- "__ref": "ProjectMember:gid://gitlab/ProjectMember/54"
- },
- {
- "__ref": "ProjectMember:gid://gitlab/ProjectMember/53"
- },
- {
- "__ref": "ProjectMember:gid://gitlab/ProjectMember/52"
- },
- {
- "__ref": "GroupMember:gid://gitlab/GroupMember/26"
- },
- {
- "__ref": "GroupMember:gid://gitlab/GroupMember/25"
- },
- {
- "__ref": "GroupMember:gid://gitlab/GroupMember/11"
- },
- {
- "__ref": "GroupMember:gid://gitlab/GroupMember/10"
- },
- {
- "__ref": "GroupMember:gid://gitlab/GroupMember/9"
- },
- {
- "__ref": "GroupMember:gid://gitlab/GroupMember/1"
- }
- ]
- },
"milestones({\"includeAncestors\":true,\"searchTitle\":\"\",\"sort\":\"EXPIRED_LAST_DUE_DATE_ASC\",\"state\":\"active\"})": {
"__typename": "MilestoneConnection",
"nodes": [
@@ -1999,125 +1967,6 @@
"healthStatus": null,
"weight": null
},
- "UserCore:gid://gitlab/User/9": {
- "__typename": "UserCore",
- "id": "gid://gitlab/User/9",
- "avatarUrl": "https://secure.gravatar.com/avatar/175e76e391370beeb21914ab74c2efd4?s=80&d=identicon",
- "name": "Kiyoko Bahringer",
- "username": "jamie"
- },
- "ProjectMember:gid://gitlab/ProjectMember/54": {
- "__typename": "ProjectMember",
- "id": "gid://gitlab/ProjectMember/54",
- "user": {
- "__ref": "UserCore:gid://gitlab/User/9"
- }
- },
- "UserCore:gid://gitlab/User/19": {
- "__typename": "UserCore",
- "id": "gid://gitlab/User/19",
- "avatarUrl": "https://secure.gravatar.com/avatar/3126153e3301ebf7cc8f7c99e57007f2?s=80&d=identicon",
- "name": "Cecile Hermann",
- "username": "jeannetta_breitenberg"
- },
- "ProjectMember:gid://gitlab/ProjectMember/53": {
- "__typename": "ProjectMember",
- "id": "gid://gitlab/ProjectMember/53",
- "user": {
- "__ref": "UserCore:gid://gitlab/User/19"
- }
- },
- "UserCore:gid://gitlab/User/2": {
- "__typename": "UserCore",
- "id": "gid://gitlab/User/2",
- "avatarUrl": "https://secure.gravatar.com/avatar/a138e401136c90561f949297387a3bb9?s=80&d=identicon",
- "name": "Tish Treutel",
- "username": "liana.larkin"
- },
- "ProjectMember:gid://gitlab/ProjectMember/52": {
- "__typename": "ProjectMember",
- "id": "gid://gitlab/ProjectMember/52",
- "user": {
- "__ref": "UserCore:gid://gitlab/User/2"
- }
- },
- "UserCore:gid://gitlab/User/13": {
- "__typename": "UserCore",
- "id": "gid://gitlab/User/13",
- "avatarUrl": "https://secure.gravatar.com/avatar/0ce8057f452296a13b5620bb2d9ede57?s=80&d=identicon",
- "name": "Tammy Gusikowski",
- "username": "xuan_oreilly"
- },
- "GroupMember:gid://gitlab/GroupMember/26": {
- "__typename": "GroupMember",
- "id": "gid://gitlab/GroupMember/26",
- "user": {
- "__ref": "UserCore:gid://gitlab/User/13"
- }
- },
- "UserCore:gid://gitlab/User/21": {
- "__typename": "UserCore",
- "id": "gid://gitlab/User/21",
- "avatarUrl": "https://secure.gravatar.com/avatar/415b09d256f26403384363d7948c4d77?s=80&d=identicon",
- "name": "Twanna Hegmann",
- "username": "jamaal"
- },
- "GroupMember:gid://gitlab/GroupMember/25": {
- "__typename": "GroupMember",
- "id": "gid://gitlab/GroupMember/25",
- "user": {
- "__ref": "UserCore:gid://gitlab/User/21"
- }
- },
- "UserCore:gid://gitlab/User/14": {
- "__typename": "UserCore",
- "id": "gid://gitlab/User/14",
- "avatarUrl": "https://secure.gravatar.com/avatar/e99697c6664381b0351b7617717dd49b?s=80&d=identicon",
- "name": "Francie Cole",
- "username": "greg.wisoky"
- },
- "GroupMember:gid://gitlab/GroupMember/11": {
- "__typename": "GroupMember",
- "id": "gid://gitlab/GroupMember/11",
- "user": {
- "__ref": "UserCore:gid://gitlab/User/14"
- }
- },
- "UserCore:gid://gitlab/User/7": {
- "__typename": "UserCore",
- "id": "gid://gitlab/User/7",
- "avatarUrl": "https://secure.gravatar.com/avatar/3a382857e362d6cce60d3806dd173444?s=80&d=identicon",
- "name": "Ivan Carter",
- "username": "ethyl"
- },
- "GroupMember:gid://gitlab/GroupMember/10": {
- "__typename": "GroupMember",
- "id": "gid://gitlab/GroupMember/10",
- "user": {
- "__ref": "UserCore:gid://gitlab/User/7"
- }
- },
- "UserCore:gid://gitlab/User/15": {
- "__typename": "UserCore",
- "id": "gid://gitlab/User/15",
- "avatarUrl": "https://secure.gravatar.com/avatar/79653006ff557e081db02deaa4ca281c?s=80&d=identicon",
- "name": "Danuta Dare",
- "username": "maddie_hintz"
- },
- "GroupMember:gid://gitlab/GroupMember/9": {
- "__typename": "GroupMember",
- "id": "gid://gitlab/GroupMember/9",
- "user": {
- "__ref": "UserCore:gid://gitlab/User/15"
- }
- },
- "GroupMember:gid://gitlab/GroupMember/1": {
- "__typename": "GroupMember",
- "id": "gid://gitlab/GroupMember/1",
- "user": {
- "__ref": "UserCore:gid://gitlab/User/1"
- }
- },
"Milestone:gid://gitlab/Milestone/30": {
"__typename": "Milestone",
"id": "gid://gitlab/Milestone/30",
diff --git a/spec/frontend/test_setup.js b/spec/frontend/test_setup.js
index 3fb226e5ed3..03ce96bce5f 100644
--- a/spec/frontend/test_setup.js
+++ b/spec/frontend/test_setup.js
@@ -1,8 +1,15 @@
/* Setup for unit test environment */
// eslint-disable-next-line no-restricted-syntax
import { setImmediate } from 'timers';
+import Dexie from 'dexie';
+import { IDBKeyRange, IDBFactory } from 'fake-indexeddb';
import 'helpers/shared_test_setup';
+const indexedDB = new IDBFactory();
+
+Dexie.dependencies.indexedDB = indexedDB;
+Dexie.dependencies.IDBKeyRange = IDBKeyRange;
+
afterEach(() =>
// give Promises a bit more time so they fail the right test
// eslint-disable-next-line no-restricted-syntax
@@ -11,3 +18,9 @@ afterEach(() =>
jest.runOnlyPendingTimers();
}),
);
+
+afterEach(async () => {
+ const dbs = await indexedDB.databases();
+
+ await Promise.all(dbs.map(async (db) => indexedDB.deleteDatabase(db.name)));
+});
diff --git a/spec/lib/backup/gitaly_backup_spec.rb b/spec/lib/backup/gitaly_backup_spec.rb
index ad0e5553fa1..172fc28dd3e 100644
--- a/spec/lib/backup/gitaly_backup_spec.rb
+++ b/spec/lib/backup/gitaly_backup_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Backup::GitalyBackup do
+RSpec.describe Backup::GitalyBackup, feature_category: :backup_restore do
let(:max_parallelism) { nil }
let(:storage_parallelism) { nil }
let(:destination) { File.join(Gitlab.config.backup.path, 'repositories') }
@@ -181,6 +181,15 @@ RSpec.describe Backup::GitalyBackup do
expect(collect_commit_shas.call(project_snippet.repository)).to match_array(['6e44ba56a4748be361a841e759c20e421a1651a1'])
end
+ it 'clears specified storages when remove_all_repositories is set' do
+ expect(Open3).to receive(:popen2).with(expected_env, anything, 'restore', '-path', anything, '-layout', 'pointer', '-remove-all-repositories', 'default').and_call_original
+
+ copy_bundle_to_backup_path('project_repo.bundle', project.disk_path + '.bundle')
+ subject.start(:restore, destination, backup_id: backup_id, remove_all_repositories: %w[default])
+ subject.enqueue(project, Gitlab::GlRepository::PROJECT)
+ subject.finish!
+ end
+
context 'parallel option set' do
let(:max_parallelism) { 3 }
diff --git a/spec/lib/backup/repositories_spec.rb b/spec/lib/backup/repositories_spec.rb
index 8bcf1e46c33..c75f6c2ac89 100644
--- a/spec/lib/backup/repositories_spec.rb
+++ b/spec/lib/backup/repositories_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Backup::Repositories do
+RSpec.describe Backup::Repositories, feature_category: :backup_restore do
let(:progress) { spy(:stdout) }
let(:strategy) { spy(:strategy) }
let(:storages) { [] }
@@ -165,7 +165,7 @@ RSpec.describe Backup::Repositories do
it 'calls enqueue for each repository type', :aggregate_failures do
subject.restore(destination)
- expect(strategy).to have_received(:start).with(:restore, destination)
+ expect(strategy).to have_received(:start).with(:restore, destination, remove_all_repositories: %w[default])
expect(strategy).to have_received(:enqueue).with(project, Gitlab::GlRepository::PROJECT)
expect(strategy).to have_received(:enqueue).with(project, Gitlab::GlRepository::WIKI)
expect(strategy).to have_received(:enqueue).with(project, Gitlab::GlRepository::DESIGN)
@@ -246,7 +246,7 @@ RSpec.describe Backup::Repositories do
subject.restore(destination)
- expect(strategy).to have_received(:start).with(:restore, destination)
+ expect(strategy).to have_received(:start).with(:restore, destination, remove_all_repositories: %w[default])
expect(strategy).not_to have_received(:enqueue).with(excluded_project, Gitlab::GlRepository::PROJECT)
expect(strategy).not_to have_received(:enqueue).with(excluded_project_snippet, Gitlab::GlRepository::SNIPPET)
expect(strategy).not_to have_received(:enqueue).with(excluded_personal_snippet, Gitlab::GlRepository::SNIPPET)
@@ -268,7 +268,7 @@ RSpec.describe Backup::Repositories do
subject.restore(destination)
- expect(strategy).to have_received(:start).with(:restore, destination)
+ expect(strategy).to have_received(:start).with(:restore, destination, remove_all_repositories: nil)
expect(strategy).not_to have_received(:enqueue).with(excluded_project, Gitlab::GlRepository::PROJECT)
expect(strategy).not_to have_received(:enqueue).with(excluded_project_snippet, Gitlab::GlRepository::SNIPPET)
expect(strategy).not_to have_received(:enqueue).with(excluded_personal_snippet, Gitlab::GlRepository::SNIPPET)
@@ -289,7 +289,7 @@ RSpec.describe Backup::Repositories do
subject.restore(destination)
- expect(strategy).to have_received(:start).with(:restore, destination)
+ expect(strategy).to have_received(:start).with(:restore, destination, remove_all_repositories: nil)
expect(strategy).not_to have_received(:enqueue).with(excluded_project, Gitlab::GlRepository::PROJECT)
expect(strategy).not_to have_received(:enqueue).with(excluded_project_snippet, Gitlab::GlRepository::SNIPPET)
expect(strategy).not_to have_received(:enqueue).with(excluded_personal_snippet, Gitlab::GlRepository::SNIPPET)
diff --git a/yarn.lock b/yarn.lock
index dc187c2a6c8..743d9ed6674 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3270,6 +3270,11 @@ balanced-match@^2.0.0:
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-2.0.0.tgz#dc70f920d78db8b858535795867bf48f820633d9"
integrity sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==
+base64-arraybuffer-es6@^0.7.0:
+ version "0.7.0"
+ resolved "https://registry.yarnpkg.com/base64-arraybuffer-es6/-/base64-arraybuffer-es6-0.7.0.tgz#dbe1e6c87b1bf1ca2875904461a7de40f21abc86"
+ integrity sha512-ESyU/U1CFZDJUdr+neHRhNozeCv72Y7Vm0m1DCbjX3KBjT6eYocvAJlSk6+8+HkVwXlT1FNxhGW6q3UKAlCvvw==
+
base64-js@^1.0.2, base64-js@^1.3.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
@@ -5087,6 +5092,11 @@ detect-node@^2.0.4:
resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c"
integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==
+dexie@^3.2.3:
+ version "3.2.3"
+ resolved "https://registry.yarnpkg.com/dexie/-/dexie-3.2.3.tgz#f35c91ca797599df8e771b998e9ae9669c877f8c"
+ integrity sha512-iHayBd4UYryDCVUNa3PMsJMEnd8yjyh5p7a+RFeC8i8n476BC9wMhVvqiImq5zJZJf5Tuer+s4SSj+AA3x+ZbQ==
+
diff-sequences@^28.1.1:
version "28.1.1"
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-28.1.1.tgz#9989dc731266dc2903457a70e996f3a041913ac6"
@@ -5178,6 +5188,13 @@ domelementtype@^2.0.1, domelementtype@^2.2.0:
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57"
integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==
+domexception@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90"
+ integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==
+ dependencies:
+ webidl-conversions "^4.0.2"
+
domexception@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/domexception/-/domexception-4.0.0.tgz#4ad1be56ccadc86fc76d033353999a8037d03673"
@@ -5922,6 +5939,13 @@ extract-files@^11.0.0:
resolved "https://registry.yarnpkg.com/extract-files/-/extract-files-11.0.0.tgz#b72d428712f787eef1f5193aff8ab5351ca8469a"
integrity sha512-FuoE1qtbJ4bBVvv94CC7s0oTnKUGvQs+Rjf1L2SJFfS+HTVVjhPFtehPdQ0JiGPqVNfSSZvL5yzHHQq2Z4WNhQ==
+fake-indexeddb@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/fake-indexeddb/-/fake-indexeddb-4.0.1.tgz#09bb2468e21d0832b2177e894765fb109edac8fb"
+ integrity sha512-hFRyPmvEZILYgdcLBxVdHLik4Tj3gDTu/g7s9ZDOiU3sTNiGx+vEu1ri/AMsFJUZ/1sdRbAVrEcKndh3sViBcA==
+ dependencies:
+ realistic-structured-clone "^3.0.0"
+
fake-xml-http-request@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/fake-xml-http-request/-/fake-xml-http-request-2.1.1.tgz#279fdac235840d7a4dff77d98ec44bce9fc690a6"
@@ -8293,7 +8317,7 @@ lodash.values@^4.3.0:
resolved "https://registry.yarnpkg.com/lodash.values/-/lodash.values-4.3.0.tgz#a3a6c2b0ebecc5c2cba1c17e6e620fe81b53d347"
integrity sha1-o6bCsOvsxcLLocF+bmIP6BtT00c=
-lodash@^4.17.10, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21:
+lodash@^4.17.10, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@@ -10528,6 +10552,15 @@ readdirp@~3.6.0:
dependencies:
picomatch "^2.2.1"
+realistic-structured-clone@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/realistic-structured-clone/-/realistic-structured-clone-3.0.0.tgz#7b518049ce2dad41ac32b421cd297075b00e3e35"
+ integrity sha512-rOjh4nuWkAqf9PWu6JVpOWD4ndI+JHfgiZeMmujYcPi+fvILUu7g6l26TC1K5aBIp34nV+jE1cDO75EKOfHC5Q==
+ dependencies:
+ domexception "^1.0.1"
+ typeson "^6.1.0"
+ typeson-registry "^1.0.0-alpha.20"
+
rechoir@^0.7.0:
version "0.7.1"
resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.1.tgz#9478a96a1ca135b5e88fc027f03ee92d6c645686"
@@ -11909,6 +11942,13 @@ tough-cookie@^4.0.0:
punycode "^2.1.1"
universalify "^0.1.2"
+tr46@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240"
+ integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==
+ dependencies:
+ punycode "^2.1.1"
+
tr46@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/tr46/-/tr46-3.0.0.tgz#555c4e297a950617e8eeddef633c87d4d9d6cbf9"
@@ -12066,6 +12106,20 @@ typedarray@^0.0.6:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.5.tgz#123a3b214aaff3be32926f0d8f1f6e704eb89a72"
integrity sha512-6OSu9PTIzmn9TCDiovULTnET6BgXtDYL4Gg4szY+cGsc3JP1dQL8qvE8kShTRx1NIw4Q9IBHlwODjkjWEtMUyA==
+typeson-registry@^1.0.0-alpha.20:
+ version "1.0.0-alpha.39"
+ resolved "https://registry.yarnpkg.com/typeson-registry/-/typeson-registry-1.0.0-alpha.39.tgz#9e0f5aabd5eebfcffd65a796487541196f4b1211"
+ integrity sha512-NeGDEquhw+yfwNhguLPcZ9Oj0fzbADiX4R0WxvoY8nGhy98IbzQy1sezjoEFWOywOboj/DWehI+/aUlRVrJnnw==
+ dependencies:
+ base64-arraybuffer-es6 "^0.7.0"
+ typeson "^6.0.0"
+ whatwg-url "^8.4.0"
+
+typeson@^6.0.0, typeson@^6.1.0:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/typeson/-/typeson-6.1.0.tgz#5b2a53705a5f58ff4d6f82f965917cabd0d7448b"
+ integrity sha512-6FTtyGr8ldU0pfbvW/eOZrEtEkczHRUtduBnA90Jh9kMPCiFNnXIon3vF41N0S4tV1HHQt4Hk1j4srpESziCaA==
+
uc.micro@^1.0.1, uc.micro@^1.0.5:
version "1.0.6"
resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac"
@@ -12621,6 +12675,16 @@ webidl-conversions@^3.0.0:
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=
+webidl-conversions@^4.0.2:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad"
+ integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==
+
+webidl-conversions@^6.1.0:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514"
+ integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==
+
webidl-conversions@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a"
@@ -12805,6 +12869,15 @@ whatwg-url@^5.0.0:
tr46 "~0.0.3"
webidl-conversions "^3.0.0"
+whatwg-url@^8.4.0:
+ version "8.7.0"
+ resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77"
+ integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==
+ dependencies:
+ lodash "^4.7.0"
+ tr46 "^2.1.0"
+ webidl-conversions "^6.1.0"
+
which-boxed-primitive@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6"