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:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-09-08 00:07:25 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-09-08 00:07:25 +0300
commit4e9110c3c5b218bb8e1b183b9570426d9bbb0670 (patch)
treecd6662bef14ad8d7d6c1f4ccfdf27b8b4210d9bc
parent1869c23b11aeda0f8183dd324ebadf59505846f0 (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/assets/javascripts/ci/pipeline_details/dag/components/dag_graph.vue4
-rw-r--r--app/assets/javascripts/ci/pipeline_details/dag/utils/drawing_utils.js (renamed from app/assets/javascripts/ci/pipeline_details/dag/drawing_utils.js)0
-rw-r--r--app/assets/javascripts/ci/pipeline_details/dag/utils/interactions.js (renamed from app/assets/javascripts/ci/pipeline_details/dag/interactions.js)2
-rw-r--r--app/assets/javascripts/ci/pipeline_details/pipelines_list/components/pipelines_table.vue2
-rw-r--r--app/assets/javascripts/ci/pipeline_details/utils/parsing_utils.js2
-rw-r--r--app/assets/javascripts/commit/constants.js6
-rw-r--r--app/controllers/projects/pipelines_controller.rb7
-rw-r--r--app/models/integrations/telegram.rb7
-rw-r--r--app/views/profiles/gpg_keys/index.html.haml2
-rw-r--r--app/views/projects/commit/_signature_badge.html.haml6
-rw-r--r--config/events/p_analytics_ci_cd_deployment_frequency.yml24
-rw-r--r--config/events/p_analytics_ci_cd_lead_time.yml24
-rw-r--r--config/events/p_analytics_ci_cd_pipelines.yml24
-rw-r--r--config/feature_flags/development/bitbucket_server_parallel_importer.yml8
-rw-r--r--config/metrics/counts_28d/20211126084446_p_analytics_ci_cd_pipelines_monthly.yml3
-rw-r--r--config/metrics/counts_28d/20211126090835_p_analytics_ci_cd_deployment_frequency_monthly.yml3
-rw-r--r--config/metrics/counts_28d/20211126091206_p_analytics_ci_cd_lead_time_monthly.yml3
-rw-r--r--config/metrics/counts_7d/20211126084441_p_analytics_ci_cd_pipelines_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20211126090829_p_analytics_ci_cd_deployment_frequency_weekly.yml3
-rw-r--r--config/metrics/counts_7d/20211126091200_p_analytics_ci_cd_lead_time_weekly.yml3
-rw-r--r--data/deprecations/16-4-geo-legacy-component-routes-deprecation.yml17
-rw-r--r--data/whats_new/202212200001_15_07.yml4
-rw-r--r--doc/administration/clusters/kas.md49
-rw-r--r--doc/administration/credentials_inventory.md2
-rw-r--r--doc/administration/gitaly/configure_gitaly.md4
-rw-r--r--doc/api/commits.md2
-rw-r--r--doc/api/graphql/reference/index.md13
-rw-r--r--doc/api/integrations.md1
-rw-r--r--doc/api/tags.md2
-rw-r--r--doc/development/database/avoiding_downtime_in_migrations.md2
-rw-r--r--doc/development/fe_guide/guides.md13
-rw-r--r--doc/raketasks/x509_signatures.md2
-rw-r--r--doc/topics/git/index.md4
-rw-r--r--doc/update/deprecations.md19
-rw-r--r--doc/user/packages/package_registry/index.md9
-rw-r--r--doc/user/project/import/cvs.md6
-rw-r--r--doc/user/project/repository/gpg_signed_commits/index.md287
-rw-r--r--doc/user/project/repository/index.md2
-rw-r--r--doc/user/project/repository/push_rules.md4
-rw-r--r--doc/user/project/repository/signed_commits/gpg.md284
-rw-r--r--doc/user/project/repository/signed_commits/img/profile_settings_gpg_keys_single_key.png (renamed from doc/user/project/repository/gpg_signed_commits/img/profile_settings_gpg_keys_single_key.png)bin4366 -> 4366 bytes
-rw-r--r--doc/user/project/repository/signed_commits/img/project_signed_and_unsigned_commits.png (renamed from doc/user/project/repository/gpg_signed_commits/img/project_signed_and_unsigned_commits.png)bin42290 -> 42290 bytes
-rw-r--r--doc/user/project/repository/signed_commits/img/project_signed_commit_unverified_signature.png (renamed from doc/user/project/repository/gpg_signed_commits/img/project_signed_commit_unverified_signature.png)bin7188 -> 7188 bytes
-rw-r--r--doc/user/project/repository/signed_commits/img/project_signed_commit_verified_signature.png (renamed from doc/user/project/repository/gpg_signed_commits/img/project_signed_commit_verified_signature.png)bin9771 -> 9771 bytes
-rw-r--r--doc/user/project/repository/signed_commits/index.md14
-rw-r--r--doc/user/project/repository/signed_commits/ssh.md167
-rw-r--r--doc/user/project/repository/signed_commits/x509.md362
-rw-r--r--doc/user/project/repository/ssh_signed_commits/index.md170
-rw-r--r--doc/user/project/repository/x509_signed_commits/index.md365
-rw-r--r--doc/user/ssh.md2
-rw-r--r--lib/api/helpers/integrations_helpers.rb1
-rw-r--r--lib/generators/gitlab/analytics/internal_events_generator.rb6
-rw-r--r--lib/gitlab/bitbucket_server_import/importer.rb468
-rw-r--r--lib/gitlab/import_sources.rb6
-rw-r--r--lib/sidebars/projects/menus/issues_menu.rb2
-rw-r--r--locale/gitlab.pot14
-rw-r--r--qa/qa/service/docker_run/smocker.rb4
-rw-r--r--qa/qa/specs/features/shared_examples/audit_event_streaming_shared_examples.rb26
-rw-r--r--qa/qa/support/audit_event_streaming_service.rb19
-rw-r--r--spec/controllers/projects/pipelines_controller_spec.rb42
-rw-r--r--spec/frontend/ci/common/private/job_links_layer_spec.js (renamed from spec/frontend/pipelines/graph_shared/links_layer_spec.js)2
-rw-r--r--spec/frontend/ci/pipeline_details/dag/components/__snapshots__/dag_graph_spec.js.snap (renamed from spec/frontend/pipelines/components/dag/__snapshots__/dag_graph_spec.js.snap)0
-rw-r--r--spec/frontend/ci/pipeline_details/dag/components/dag_annotations_spec.js (renamed from spec/frontend/pipelines/components/dag/dag_annotations_spec.js)2
-rw-r--r--spec/frontend/ci/pipeline_details/dag/components/dag_graph_spec.js (renamed from spec/frontend/pipelines/components/dag/dag_graph_spec.js)6
-rw-r--r--spec/frontend/ci/pipeline_details/dag/dag_spec.js (renamed from spec/frontend/pipelines/components/dag/dag_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/dag/mock_data.js (renamed from spec/frontend/pipelines/components/dag/mock_data.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/dag/utils/drawing_utils_spec.js (renamed from spec/frontend/pipelines/components/dag/drawing_utils_spec.js)4
-rw-r--r--spec/frontend/ci/pipeline_details/graph/components/__snapshots__/links_inner_spec.js.snap (renamed from spec/frontend/pipelines/graph_shared/__snapshots__/links_inner_spec.js.snap)0
-rw-r--r--spec/frontend/ci/pipeline_details/graph/components/action_component_spec.js (renamed from spec/frontend/pipelines/graph/action_component_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/graph/components/graph_component_spec.js (renamed from spec/frontend/pipelines/graph/graph_component_spec.js)2
-rw-r--r--spec/frontend/ci/pipeline_details/graph/components/graph_view_selector_spec.js (renamed from spec/frontend/pipelines/graph/graph_view_selector_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/graph/components/job_group_dropdown_spec.js (renamed from spec/frontend/pipelines/graph/job_group_dropdown_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/graph/components/job_item_spec.js (renamed from spec/frontend/pipelines/graph/job_item_spec.js)2
-rw-r--r--spec/frontend/ci/pipeline_details/graph/components/job_name_component_spec.js (renamed from spec/frontend/pipelines/graph/job_name_component_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/graph/components/linked_pipeline_spec.js (renamed from spec/frontend/pipelines/graph/linked_pipeline_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/graph/components/linked_pipelines_column_spec.js (renamed from spec/frontend/pipelines/graph/linked_pipelines_column_spec.js)2
-rw-r--r--spec/frontend/ci/pipeline_details/graph/components/linked_pipelines_mock_data.js (renamed from spec/frontend/pipelines/graph/linked_pipelines_mock_data.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/graph/components/links_inner_spec.js (renamed from spec/frontend/pipelines/graph_shared/links_inner_spec.js)2
-rw-r--r--spec/frontend/ci/pipeline_details/graph/components/stage_column_component_spec.js (renamed from spec/frontend/pipelines/graph/stage_column_component_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/graph/graph_component_wrapper_spec.js (renamed from spec/frontend/pipelines/graph/graph_component_wrapper_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/graph/mock_data.js (renamed from spec/frontend/pipelines/graph/mock_data.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/header/pipeline_details_header_spec.js (renamed from spec/frontend/pipelines/pipeline_details_header_spec.js)2
-rw-r--r--spec/frontend/ci/pipeline_details/jobs/components/failed_jobs_table_spec.js (renamed from spec/frontend/pipelines/components/jobs/failed_jobs_table_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/jobs/failed_jobs_app_spec.js (renamed from spec/frontend/pipelines/components/jobs/failed_jobs_app_spec.js)2
-rw-r--r--spec/frontend/ci/pipeline_details/jobs/jobs_app_spec.js (renamed from spec/frontend/pipelines/components/jobs/jobs_app_spec.js)2
-rw-r--r--spec/frontend/ci/pipeline_details/linked_pipelines_mock.json (renamed from spec/frontend/pipelines/linked_pipelines_mock.json)0
-rw-r--r--spec/frontend/ci/pipeline_details/mock_data.js (renamed from spec/frontend/pipelines/mock_data.js)102
-rw-r--r--spec/frontend/ci/pipeline_details/pipeline_tabs_spec.js (renamed from spec/frontend/pipelines/pipeline_tabs_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/pipelines_list/components/nav_controls_spec.js (renamed from spec/frontend/pipelines/nav_controls_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/pipelines_list/components/pipeline_labels_spec.js (renamed from spec/frontend/pipelines/pipeline_labels_spec.js)2
-rw-r--r--spec/frontend/ci/pipeline_details/pipelines_list/components/pipeline_multi_actions_spec.js (renamed from spec/frontend/pipelines/pipeline_multi_actions_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/pipelines_list/components/pipeline_operations_spec.js (renamed from spec/frontend/pipelines/pipeline_operations_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/pipelines_list/components/pipeline_stop_modal_spec.js (renamed from spec/frontend/pipelines/components/pipelines_list/pipeline_stop_modal_spec.js)2
-rw-r--r--spec/frontend/ci/pipeline_details/pipelines_list/components/pipeline_triggerer_spec.js (renamed from spec/frontend/pipelines/pipeline_triggerer_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/pipelines_list/components/pipeline_url_spec.js (renamed from spec/frontend/pipelines/pipeline_url_spec.js)2
-rw-r--r--spec/frontend/ci/pipeline_details/pipelines_list/components/pipelines_artifacts_spec.js (renamed from spec/frontend/pipelines/pipelines_artifacts_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/pipelines_list/components/pipelines_filtered_search_spec.js (renamed from spec/frontend/pipelines/components/pipelines_filtered_search_spec.js)2
-rw-r--r--spec/frontend/ci/pipeline_details/pipelines_list/components/pipelines_manual_actions_spec.js (renamed from spec/frontend/pipelines/pipelines_manual_actions_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/pipelines_list/components/pipelines_table_spec.js (renamed from spec/frontend/pipelines/pipelines_table_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/pipelines_list/components/time_ago_spec.js (renamed from spec/frontend/pipelines/time_ago_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/pipelines_list/empty_state/ci_templates_spec.js (renamed from spec/frontend/pipelines/components/pipelines_list/empty_state/ci_templates_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/pipelines_list/empty_state/ios_templates_spec.js (renamed from spec/frontend/pipelines/components/pipelines_list/empty_state/ios_templates_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/pipelines_list/empty_state/no_ci_empty_state_spec.js (renamed from spec/frontend/pipelines/empty_state_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/pipelines_list/empty_state/pipelines_ci_templates_spec.js (renamed from spec/frontend/pipelines/components/pipelines_list/empty_state/pipelines_ci_templates_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/pipelines_list/failure_widget/failed_job_details_spec.js (renamed from spec/frontend/pipelines/components/pipelines_list/failure_widget/failed_job_details_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/pipelines_list/failure_widget/failed_jobs_list_spec.js (renamed from spec/frontend/pipelines/components/pipelines_list/failure_widget/failed_jobs_list_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/pipelines_list/failure_widget/mock.js (renamed from spec/frontend/pipelines/components/pipelines_list/failure_widget/mock.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/pipelines_list/failure_widget/pipeline_failed_jobs_widget_spec.js (renamed from spec/frontend/pipelines/components/pipelines_list/failure_widget/pipeline_failed_jobs_widget_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/pipelines_list/failure_widget/utils_spec.js (renamed from spec/frontend/pipelines/components/pipelines_list/failure_widget/utils_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/pipelines_list/pipelines_spec.js (renamed from spec/frontend/pipelines/pipelines_spec.js)3
-rw-r--r--spec/frontend/ci/pipeline_details/pipelines_list/tokens/pipeline_branch_name_token_spec.js (renamed from spec/frontend/pipelines/tokens/pipeline_branch_name_token_spec.js)2
-rw-r--r--spec/frontend/ci/pipeline_details/pipelines_list/tokens/pipeline_source_token_spec.js (renamed from spec/frontend/pipelines/tokens/pipeline_source_token_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/pipelines_list/tokens/pipeline_status_token_spec.js (renamed from spec/frontend/pipelines/tokens/pipeline_status_token_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/pipelines_list/tokens/pipeline_tag_name_token_spec.js (renamed from spec/frontend/pipelines/tokens/pipeline_tag_name_token_spec.js)2
-rw-r--r--spec/frontend/ci/pipeline_details/pipelines_list/tokens/pipeline_trigger_author_token_spec.js (renamed from spec/frontend/pipelines/tokens/pipeline_trigger_author_token_spec.js)2
-rw-r--r--spec/frontend/ci/pipeline_details/pipelines_store_spec.js (renamed from spec/frontend/pipelines/pipelines_store_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/tabs/pipeline_tabs_spec.js (renamed from spec/frontend/pipelines/components/pipeline_tabs_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/test_reports/empty_state_spec.js (renamed from spec/frontend/pipelines/test_reports/empty_state_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/test_reports/mock_data.js (renamed from spec/frontend/pipelines/test_reports/mock_data.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/test_reports/stores/actions_spec.js (renamed from spec/frontend/pipelines/test_reports/stores/actions_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/test_reports/stores/getters_spec.js (renamed from spec/frontend/pipelines/test_reports/stores/getters_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/test_reports/stores/mutations_spec.js (renamed from spec/frontend/pipelines/test_reports/stores/mutations_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/test_reports/stores/utils_spec.js (renamed from spec/frontend/pipelines/test_reports/stores/utils_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/test_reports/test_case_details_spec.js (renamed from spec/frontend/pipelines/test_reports/test_case_details_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/test_reports/test_reports_spec.js (renamed from spec/frontend/pipelines/test_reports/test_reports_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/test_reports/test_suite_table_spec.js (renamed from spec/frontend/pipelines/test_reports/test_suite_table_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/test_reports/test_summary_spec.js (renamed from spec/frontend/pipelines/test_reports/test_summary_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/test_reports/test_summary_table_spec.js (renamed from spec/frontend/pipelines/test_reports/test_summary_table_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/utils/index_spec.js (renamed from spec/frontend/pipelines/pipeline_graph/utils_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_details/utils/parsing_utils_spec.js (renamed from spec/frontend/pipelines/utils_spec.js)10
-rw-r--r--spec/frontend/ci/pipeline_details/utils/unwrapping_utils_spec.js (renamed from spec/frontend/pipelines/unwrapping_utils_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_editor/components/graph/mock_data.js (renamed from spec/frontend/pipelines/pipeline_graph/mock_data.js)0
-rw-r--r--spec/frontend/ci/pipeline_editor/components/graph/pipeline_graph_spec.js (renamed from spec/frontend/pipelines/pipeline_graph/pipeline_graph_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_mini_graph/job_item_spec.js (renamed from spec/frontend/pipelines/components/pipeline_mini_graph/job_item_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_mini_graph/legacy_pipeline_mini_graph_spec.js (renamed from spec/frontend/pipelines/components/pipeline_mini_graph/legacy_pipeline_mini_graph_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_mini_graph/legacy_pipeline_stage_spec.js (renamed from spec/frontend/pipelines/components/pipeline_mini_graph/legacy_pipeline_stage_spec.js)2
-rw-r--r--spec/frontend/ci/pipeline_mini_graph/linked_pipelines_mini_list_spec.js (renamed from spec/frontend/pipelines/components/pipeline_mini_graph/linked_pipelines_mini_list_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_mini_graph/linked_pipelines_mock_data.js (renamed from spec/frontend/pipelines/components/pipeline_mini_graph/linked_pipelines_mock_data.js)0
-rw-r--r--spec/frontend/ci/pipeline_mini_graph/mock_data.js (renamed from spec/frontend/pipelines/components/pipeline_mini_graph/mock_data.js)102
-rw-r--r--spec/frontend/ci/pipeline_mini_graph/pipeline_mini_graph_spec.js (renamed from spec/frontend/pipelines/components/pipeline_mini_graph/pipeline_mini_graph_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_mini_graph/pipeline_stage_spec.js (renamed from spec/frontend/pipelines/components/pipeline_mini_graph/pipeline_stage_spec.js)0
-rw-r--r--spec/frontend/ci/pipeline_mini_graph/pipeline_stages_spec.js (renamed from spec/frontend/pipelines/components/pipeline_mini_graph/pipeline_stages_spec.js)0
-rw-r--r--spec/frontend/pipelines/notification/mock_data.js33
-rw-r--r--spec/lib/gitlab/bitbucket_server_import/importer_spec.rb653
-rw-r--r--spec/lib/gitlab/import_sources_spec.rb38
-rw-r--r--spec/lib/sidebars/projects/menus/issues_menu_spec.rb1
146 files changed, 1248 insertions, 2268 deletions
diff --git a/app/assets/javascripts/ci/pipeline_details/dag/components/dag_graph.vue b/app/assets/javascripts/ci/pipeline_details/dag/components/dag_graph.vue
index 67e80145e83..6e975d55a7f 100644
--- a/app/assets/javascripts/ci/pipeline_details/dag/components/dag_graph.vue
+++ b/app/assets/javascripts/ci/pipeline_details/dag/components/dag_graph.vue
@@ -4,7 +4,7 @@ import { uniqueId } from 'lodash';
import { getMaxNodes, removeOrphanNodes } from '~/ci/pipeline_details/utils/parsing_utils';
import { PARSE_FAILURE } from '../../constants';
import { LINK_SELECTOR, NODE_SELECTOR, ADD_NOTE, REMOVE_NOTE, REPLACE_NOTES } from '../constants';
-import { calculateClip, createLinkPath, createSankey, labelPosition } from '../drawing_utils';
+import { calculateClip, createLinkPath, createSankey, labelPosition } from '../utils/drawing_utils';
import {
currentIsLive,
getLiveLinksAsDict,
@@ -12,7 +12,7 @@ import {
restoreLinks,
toggleLinkHighlight,
togglePathHighlights,
-} from '../interactions';
+} from '../utils/interactions';
export default {
viewOptions: {
diff --git a/app/assets/javascripts/ci/pipeline_details/dag/drawing_utils.js b/app/assets/javascripts/ci/pipeline_details/dag/utils/drawing_utils.js
index 3cd09d57ffb..3cd09d57ffb 100644
--- a/app/assets/javascripts/ci/pipeline_details/dag/drawing_utils.js
+++ b/app/assets/javascripts/ci/pipeline_details/dag/utils/drawing_utils.js
diff --git a/app/assets/javascripts/ci/pipeline_details/dag/interactions.js b/app/assets/javascripts/ci/pipeline_details/dag/utils/interactions.js
index 69f36feeee4..d2b7b7f9069 100644
--- a/app/assets/javascripts/ci/pipeline_details/dag/interactions.js
+++ b/app/assets/javascripts/ci/pipeline_details/dag/utils/interactions.js
@@ -1,5 +1,5 @@
import * as d3 from 'd3';
-import { LINK_SELECTOR, NODE_SELECTOR, IS_HIGHLIGHTED } from './constants';
+import { LINK_SELECTOR, NODE_SELECTOR, IS_HIGHLIGHTED } from '../constants';
export const highlightIn = 1;
export const highlightOut = 0.2;
diff --git a/app/assets/javascripts/ci/pipeline_details/pipelines_list/components/pipelines_table.vue b/app/assets/javascripts/ci/pipeline_details/pipelines_list/components/pipelines_table.vue
index 9784186ac67..f7a620c13a4 100644
--- a/app/assets/javascripts/ci/pipeline_details/pipelines_list/components/pipelines_table.vue
+++ b/app/assets/javascripts/ci/pipeline_details/pipelines_list/components/pipelines_table.vue
@@ -113,7 +113,7 @@ export default {
key: 'actions',
thClass: DEFAULT_TH_CLASSES,
tdClass: this.tdClasses,
- columnClass: 'gl-w-15p',
+ columnClass: 'gl-w-20p',
thAttr: { 'data-testid': 'actions-th' },
},
];
diff --git a/app/assets/javascripts/ci/pipeline_details/utils/parsing_utils.js b/app/assets/javascripts/ci/pipeline_details/utils/parsing_utils.js
index cfe488b7d14..0a2a6d16498 100644
--- a/app/assets/javascripts/ci/pipeline_details/utils/parsing_utils.js
+++ b/app/assets/javascripts/ci/pipeline_details/utils/parsing_utils.js
@@ -1,6 +1,6 @@
import { memoize } from 'lodash';
import { EXPLICIT_NEEDS_PROPERTY, NEEDS_PROPERTY } from '../constants';
-import { createSankey } from '../dag/drawing_utils';
+import { createSankey } from '../dag/utils/drawing_utils';
import { createNodeDict } from './index';
/*
diff --git a/app/assets/javascripts/commit/constants.js b/app/assets/javascripts/commit/constants.js
index 4f865e99e46..e28009ab996 100644
--- a/app/assets/javascripts/commit/constants.js
+++ b/app/assets/javascripts/commit/constants.js
@@ -80,14 +80,14 @@ export const typeConfig = {
keyNamespace: 'gpgKeyPrimaryKeyid',
helpLink: {
label: __('Learn about signing commits'),
- path: 'user/project/repository/gpg_signed_commits/index.md',
+ path: 'user/project/repository/signed_commits/index.md',
},
},
[signatureTypes.X509]: {
keyLabel: '',
helpLink: {
label: __('Learn more about X.509 signed commits'),
- path: '/user/project/repository/x509_signed_commits/index.md',
+ path: '/user/project/repository/signed_commits/x509.md',
},
subjectTitle: __('Certificate Subject'),
issuerTitle: __('Certificate Issuer'),
@@ -98,7 +98,7 @@ export const typeConfig = {
keyNamespace: 'keyFingerprintSha256',
helpLink: {
label: __('Learn about signing commits with SSH keys.'),
- path: '/user/project/repository/ssh_signed_commits/index.md',
+ path: '/user/project/repository/signed_commits/ssh.md',
},
},
};
diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb
index a96ee2215c2..036ea45cc78 100644
--- a/app/controllers/projects/pipelines_controller.rb
+++ b/app/controllers/projects/pipelines_controller.rb
@@ -3,7 +3,6 @@
class Projects::PipelinesController < Projects::ApplicationController
include ::Gitlab::Utils::StrongMemoize
include ProductAnalyticsTracking
- include ProductAnalyticsTracking
include ProjectStatsRefreshConflictsGuard
urgency :low, [
@@ -34,9 +33,9 @@ class Projects::PipelinesController < Projects::ApplicationController
label: 'redis_hll_counters.analytics.analytics_total_unique_counts_monthly',
destinations: %i[redis_hll snowplow]
- track_event :charts, name: 'p_analytics_ci_cd_pipelines', conditions: -> { should_track_ci_cd_pipelines? }
- track_event :charts, name: 'p_analytics_ci_cd_deployment_frequency', conditions: -> { should_track_ci_cd_deployment_frequency? }
- track_event :charts, name: 'p_analytics_ci_cd_lead_time', conditions: -> { should_track_ci_cd_lead_time? }
+ track_internal_event :charts, name: 'p_analytics_ci_cd_pipelines', conditions: -> { should_track_ci_cd_pipelines? }
+ track_internal_event :charts, name: 'p_analytics_ci_cd_deployment_frequency', conditions: -> { should_track_ci_cd_deployment_frequency? }
+ track_internal_event :charts, name: 'p_analytics_ci_cd_lead_time', conditions: -> { should_track_ci_cd_lead_time? }
track_event :charts, name: 'p_analytics_ci_cd_time_to_restore_service', conditions: -> { should_track_ci_cd_time_to_restore_service? }
track_event :charts, name: 'p_analytics_ci_cd_change_failure_rate', conditions: -> { should_track_ci_cd_change_failure_rate? }
diff --git a/app/models/integrations/telegram.rb b/app/models/integrations/telegram.rb
index aac9a36928b..ff3c0126c5b 100644
--- a/app/models/integrations/telegram.rb
+++ b/app/models/integrations/telegram.rb
@@ -2,6 +2,8 @@
module Integrations
class Telegram < BaseChatNotification
+ undef :notify_only_broken_pipelines
+
TELEGRAM_HOSTNAME = "https://api.telegram.org/bot%{token}/sendMessage"
field :token,
@@ -21,6 +23,11 @@ module Integrations
placeholder: '@channelusername',
required: true
+ field :notify_only_broken_pipelines,
+ type: :checkbox,
+ section: SECTION_TYPE_CONFIGURATION,
+ help: 'If selected, successful pipelines do not trigger a notification event.'
+
with_options if: :activated? do
validates :token, :room, presence: true
end
diff --git a/app/views/profiles/gpg_keys/index.html.haml b/app/views/profiles/gpg_keys/index.html.haml
index 2714193d1d1..982199d3d6f 100644
--- a/app/views/profiles/gpg_keys/index.html.haml
+++ b/app/views/profiles/gpg_keys/index.html.haml
@@ -28,7 +28,7 @@
%h4.gl-mt-0
= _('Add a GPG key')
%p
- - help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/project/repository/gpg_signed_commits/index.md') }
+ - help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/project/repository/signed_commits/gpg.md') }
= _('Add a GPG key for secure access to GitLab. %{help_link_start}Learn more%{help_link_end}.').html_safe % {help_link_start: help_link_start, help_link_end: '</a>'.html_safe }
= render 'form'
diff --git a/app/views/projects/commit/_signature_badge.html.haml b/app/views/projects/commit/_signature_badge.html.haml
index 5b99a88f29e..6aefc2eaa8b 100644
--- a/app/views/projects/commit/_signature_badge.html.haml
+++ b/app/views/projects/commit/_signature_badge.html.haml
@@ -17,17 +17,17 @@
- if signature.x509?
= render partial: "projects/commit/x509/certificate_details", locals: { signature: signature }
- = link_to(_('Learn more about X.509 signed commits'), help_page_path('user/project/repository/x509_signed_commits/index.md'), class: 'gl-link gl-display-block')
+ = link_to(_('Learn more about X.509 signed commits'), help_page_path('user/project/repository/signed_commits/x509.md'), class: 'gl-link gl-display-block')
- elsif signature.ssh?
= _('SSH key fingerprint:')
%span.gl-font-monospace= signature.key_fingerprint_sha256 || _('Unknown')
- = link_to(_('Learn about signing commits with SSH keys.'), help_page_path('user/project/repository/ssh_signed_commits/index.md'), class: 'gl-link gl-display-block gl-mt-3')
+ = link_to(_('Learn about signing commits with SSH keys.'), help_page_path('user/project/repository/signed_commits/ssh.md'), class: 'gl-link gl-display-block gl-mt-3')
- else
= _('GPG Key ID:')
%span.gl-font-monospace= signature.gpg_key_primary_keyid
- = link_to(_('Learn about signing commits'), help_page_path('user/project/repository/gpg_signed_commits/index.md'), class: 'gl-link gl-display-block gl-mt-3')
+ = link_to(_('Learn about signing commits'), help_page_path('user/project/repository/signed_commits/index.md'), class: 'gl-link gl-display-block gl-mt-3')
%a.signature-badge.gl-display-inline-block.gl-ml-4{ role: 'button', tabindex: 0, data: { toggle: 'popover', html: 'true', placement: 'top', title: title, content: content } }
= gl_badge_tag label, variant: variant
diff --git a/config/events/p_analytics_ci_cd_deployment_frequency.yml b/config/events/p_analytics_ci_cd_deployment_frequency.yml
new file mode 100644
index 00000000000..47b71758921
--- /dev/null
+++ b/config/events/p_analytics_ci_cd_deployment_frequency.yml
@@ -0,0 +1,24 @@
+---
+description: Project level CI CD Analytics deployment frequency tab has been visited
+category: InternalEventTracking
+action: p_analytics_ci_cd_deployment_frequency
+label_description:
+property_description:
+value_description:
+extra_properties:
+identifiers:
+- project
+- user
+- namespace
+product_section: dev
+product_stage: manage
+product_group: optimize
+milestone: "16.4"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/130854
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/p_analytics_ci_cd_lead_time.yml b/config/events/p_analytics_ci_cd_lead_time.yml
new file mode 100644
index 00000000000..d45b6bec225
--- /dev/null
+++ b/config/events/p_analytics_ci_cd_lead_time.yml
@@ -0,0 +1,24 @@
+---
+description: Project level CI CD Analytics lead time tab has been visited
+category: InternalEventTracking
+action: p_analytics_ci_cd_lead_time
+label_description:
+property_description:
+value_description:
+extra_properties:
+identifiers:
+- project
+- user
+- namespace
+product_section: dev
+product_stage: manage
+product_group: optimize
+milestone: "16.4"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/130854
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/p_analytics_ci_cd_pipelines.yml b/config/events/p_analytics_ci_cd_pipelines.yml
new file mode 100644
index 00000000000..2f14fcc0057
--- /dev/null
+++ b/config/events/p_analytics_ci_cd_pipelines.yml
@@ -0,0 +1,24 @@
+---
+description: Project level CI CD Analytics pipelines tab has been visited
+category: InternalEventTracking
+action: p_analytics_ci_cd_pipelines
+label_description:
+property_description:
+value_description:
+extra_properties:
+identifiers:
+- project
+- user
+- namespace
+product_section: dev
+product_stage: manage
+product_group: optimize
+milestone: "16.4"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/130854
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/feature_flags/development/bitbucket_server_parallel_importer.yml b/config/feature_flags/development/bitbucket_server_parallel_importer.yml
deleted file mode 100644
index be553a5e6da..00000000000
--- a/config/feature_flags/development/bitbucket_server_parallel_importer.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: bitbucket_server_parallel_importer
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/120931
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/411796
-milestone: '16.1'
-type: development
-group: group::import and integrate
-default_enabled: true
diff --git a/config/metrics/counts_28d/20211126084446_p_analytics_ci_cd_pipelines_monthly.yml b/config/metrics/counts_28d/20211126084446_p_analytics_ci_cd_pipelines_monthly.yml
index 845500bff73..f84d9c7483a 100644
--- a/config/metrics/counts_28d/20211126084446_p_analytics_ci_cd_pipelines_monthly.yml
+++ b/config/metrics/counts_28d/20211126084446_p_analytics_ci_cd_pipelines_monthly.yml
@@ -13,6 +13,9 @@ data_source: redis_hll
data_category: optional
instrumentation_class: RedisHLLMetric
performance_indicator_type: []
+events:
+ - name: p_analytics_ci_cd_pipelines
+ unique: user.id
distribution:
- ce
- ee
diff --git a/config/metrics/counts_28d/20211126090835_p_analytics_ci_cd_deployment_frequency_monthly.yml b/config/metrics/counts_28d/20211126090835_p_analytics_ci_cd_deployment_frequency_monthly.yml
index d719ac3e5d1..6569027515f 100644
--- a/config/metrics/counts_28d/20211126090835_p_analytics_ci_cd_deployment_frequency_monthly.yml
+++ b/config/metrics/counts_28d/20211126090835_p_analytics_ci_cd_deployment_frequency_monthly.yml
@@ -13,6 +13,9 @@ data_source: redis_hll
data_category: operational
instrumentation_class: RedisHLLMetric
performance_indicator_type: []
+events:
+ - name: p_analytics_ci_cd_deployment_frequency
+ unique: user.id
distribution:
- ce
- ee
diff --git a/config/metrics/counts_28d/20211126091206_p_analytics_ci_cd_lead_time_monthly.yml b/config/metrics/counts_28d/20211126091206_p_analytics_ci_cd_lead_time_monthly.yml
index d0640d97d37..63d1ed5d0c6 100644
--- a/config/metrics/counts_28d/20211126091206_p_analytics_ci_cd_lead_time_monthly.yml
+++ b/config/metrics/counts_28d/20211126091206_p_analytics_ci_cd_lead_time_monthly.yml
@@ -13,6 +13,9 @@ data_source: redis_hll
data_category: operational
instrumentation_class: RedisHLLMetric
performance_indicator_type: []
+events:
+ - name: p_analytics_ci_cd_lead_time
+ unique: user.id
distribution:
- ce
- ee
diff --git a/config/metrics/counts_7d/20211126084441_p_analytics_ci_cd_pipelines_weekly.yml b/config/metrics/counts_7d/20211126084441_p_analytics_ci_cd_pipelines_weekly.yml
index 24b2e2c7ca0..e86741aedb2 100644
--- a/config/metrics/counts_7d/20211126084441_p_analytics_ci_cd_pipelines_weekly.yml
+++ b/config/metrics/counts_7d/20211126084441_p_analytics_ci_cd_pipelines_weekly.yml
@@ -13,6 +13,9 @@ data_source: redis_hll
data_category: optional
instrumentation_class: RedisHLLMetric
performance_indicator_type: []
+events:
+ - name: p_analytics_ci_cd_pipelines
+ unique: user.id
distribution:
- ce
- ee
diff --git a/config/metrics/counts_7d/20211126090829_p_analytics_ci_cd_deployment_frequency_weekly.yml b/config/metrics/counts_7d/20211126090829_p_analytics_ci_cd_deployment_frequency_weekly.yml
index 1f7cd61e3cd..f0bbdcbda62 100644
--- a/config/metrics/counts_7d/20211126090829_p_analytics_ci_cd_deployment_frequency_weekly.yml
+++ b/config/metrics/counts_7d/20211126090829_p_analytics_ci_cd_deployment_frequency_weekly.yml
@@ -13,6 +13,9 @@ data_source: redis_hll
data_category: optional
instrumentation_class: RedisHLLMetric
performance_indicator_type: []
+events:
+ - name: p_analytics_ci_cd_deployment_frequency
+ unique: user.id
distribution:
- ce
- ee
diff --git a/config/metrics/counts_7d/20211126091200_p_analytics_ci_cd_lead_time_weekly.yml b/config/metrics/counts_7d/20211126091200_p_analytics_ci_cd_lead_time_weekly.yml
index 164ecf8134f..d95376e277a 100644
--- a/config/metrics/counts_7d/20211126091200_p_analytics_ci_cd_lead_time_weekly.yml
+++ b/config/metrics/counts_7d/20211126091200_p_analytics_ci_cd_lead_time_weekly.yml
@@ -13,6 +13,9 @@ data_source: redis_hll
data_category: optional
instrumentation_class: RedisHLLMetric
performance_indicator_type: []
+events:
+ - name: p_analytics_ci_cd_lead_time
+ unique: user.id
distribution:
- ce
- ee
diff --git a/data/deprecations/16-4-geo-legacy-component-routes-deprecation.yml b/data/deprecations/16-4-geo-legacy-component-routes-deprecation.yml
new file mode 100644
index 00000000000..83a9882c90f
--- /dev/null
+++ b/data/deprecations/16-4-geo-legacy-component-routes-deprecation.yml
@@ -0,0 +1,17 @@
+#
+# REQUIRED FIELDS
+#
+- title: "Geo: Legacy replication details routes for designs and projects deprecated" # (required) Clearly explain the change, or planned change. For example, "The `confidential` field for a `Note` is deprecated" or "CI/CD job names will be limited to 250 characters."
+ removal_milestone: "17.0" # (required) The milestone when this feature is planned to be removed
+ announcement_milestone: "16.4" # (required) The milestone when this feature was first announced as deprecated.
+ breaking_change: true # (required) Change to false if this is not a breaking change.
+ reporter: sranasinghe # (required) GitLab username of the person reporting the change
+ stage: enablement # (required) String value of the stage that the feature was created in. e.g., Growth
+ issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/424002 # (required) Link to the deprecation issue in GitLab
+ body: | # (required) Do not modify this line, instead modify the lines below.
+ As part of the migration of legacy data types to the [Geo self-service framework](https://docs.gitlab.com/ee/development/geo/framework.html), the following replication details routes are deprecated:
+
+ - Designs `/admin/geo/replication/designs` replaced by `/admin/geo/sites/<Geo Node/Site ID>/replication/design_management_repositories`
+ - Projects `/admin/geo/replication/projects` replaced by `/admin/geo/sites/<Geo Node/Site ID>/replication/projects`
+
+ From GitLab 16.4 to 17.0, lookups for the legacy routes will automatically be redirected to the new routes. We will remove the redirections in 17.0. Please update any bookmarks or scripts that may use the legacy routes.
diff --git a/data/whats_new/202212200001_15_07.yml b/data/whats_new/202212200001_15_07.yml
index ebfcc0f16ad..465de395fdb 100644
--- a/data/whats_new/202212200001_15_07.yml
+++ b/data/whats_new/202212200001_15_07.yml
@@ -64,7 +64,7 @@
release: 15.7
- name: "Sign commits with your SSH key"
description: | # Do not modify this line, instead modify the lines below.
- Signing commits just got a lot simpler. Use SSH keys [to sign commits](https://docs.gitlab.com/ee/user/project/repository/ssh_signed_commits/), and provide others with confidence that a **Verified** commit was authored by you.
+ Signing commits just got a lot simpler. Use SSH keys [to sign commits](https://docs.gitlab.com/ee/user/project/repository/signed_commits/ssh.html), and provide others with confidence that a **Verified** commit was authored by you.
Previous methods for signing commits required a GPG key or an X.509 certificate, neither of which can be used to sign in to GitLab. Adding support for commit signing with SSH keys now makes it possible to reuse your authentication key pair to also sign your commits. If you already authenticate into GitLab with an SSH key, add three lines of code to your local Git configuration and all your future commits will be signed.
@@ -73,7 +73,7 @@
self-managed: true
gitlab-com: true
available_in: [Free, Premium, Ultimate]
- documentation_link: https://docs.gitlab.com/ee/user/project/repository/ssh_signed_commits/
+ documentation_link: https://docs.gitlab.com/ee/user/project/repository/signed_commits/ssh.html
image_url: https://img.youtube.com/vi/IrK83nKi8HA/hqdefault.jpg
published_at: 2022-12-22
release: 15.7
diff --git a/doc/administration/clusters/kas.md b/doc/administration/clusters/kas.md
index b7247e2251f..e291a162fb9 100644
--- a/doc/administration/clusters/kas.md
+++ b/doc/administration/clusters/kas.md
@@ -9,40 +9,38 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3834) in GitLab 13.10, the GitLab agent server (KAS) became available on GitLab.com at `wss://kas.gitlab.com`.
> - [Moved](https://gitlab.com/groups/gitlab-org/-/epics/6290) from GitLab Premium to GitLab Free in 14.5.
-The agent server is a component you install together with GitLab. It is required to
+The agent server is a component installed together with GitLab. It is required to
manage the [GitLab agent for Kubernetes](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent).
The KAS acronym refers to the former name, `Kubernetes agent server`.
The agent server for Kubernetes is installed and available on GitLab.com at `wss://kas.gitlab.com`.
-If you use self-managed GitLab, you must install an agent server or specify an external installation.
+If you use self-managed GitLab, by default the agent server is installed and available.
## Installation options
-As a GitLab administrator, you can install the agent server:
+As a GitLab administrator, you can control the agent server installation:
- For [Linux package installations](#for-linux-package-installations).
- For [GitLab Helm chart installations](#for-gitlab-helm-chart).
### For Linux package installations
-You can enable the agent server for Linux package installations on a single node, or on multiple nodes at once.
+The agent server for Linux package installations can be enabled on a single node, or on multiple nodes at once.
+By default, the agent server is enabled and available at `ws://gitlab.example.com/-/kubernetes-agent/`.
-#### Enable on a single node
+#### Disable on a single node
-To enable the agent server on a single node:
+To disable the agent server on a single node:
1. Edit `/etc/gitlab/gitlab.rb`:
```ruby
- gitlab_kas['enable'] = true
+ gitlab_kas['enable'] = false
```
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation).
-For additional configuration options, see the **Enable GitLab KAS** section of the
-[`gitlab.rb.template`](https://gitlab.com/gitlab-org/omnibus-gitlab/-/blob/be52c36c243a3422ec38b7d45d459682a07e195f/files/gitlab-config-template/gitlab.rb.template#L1951).
-
##### Configure KAS to listen on a UNIX socket
If you use GitLab behind a proxy, KAS might not work correctly. You can resolve this issue on a single-node installation, you can configure KAS to listen on a UNIX socket.
@@ -70,6 +68,9 @@ To configure KAS to listen on a UNIX socket:
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation).
+For additional configuration options, see the **GitLab Kubernetes Agent Server** section of the
+[`gitlab.rb.template`](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/files/gitlab-config-template/gitlab.rb.template).
+
#### Enable on multiple nodes
To enable the agent server on multiple nodes:
@@ -79,7 +80,6 @@ To enable the agent server on multiple nodes:
```ruby
gitlab_kas_external_url 'wss://kas.gitlab.example.com/'
- gitlab_kas['enable'] = true
gitlab_kas['api_secret_key'] = '<32_bytes_long_base64_encoded_value>'
gitlab_kas['private_api_secret_key'] = '<32_bytes_long_base64_encoded_value>'
gitlab_kas['private_api_listen_address'] = '0.0.0.0:8155'
@@ -88,7 +88,6 @@ To enable the agent server on multiple nodes:
'OWN_PRIVATE_API_URL' => 'grpc://<ip_or_hostname_of_this_host>:8155'
}
- gitlab_rails['gitlab_kas_enabled'] = true
gitlab_rails['gitlab_kas_external_url'] = 'wss://gitlab.example.com/-/kubernetes-agent/'
gitlab_rails['gitlab_kas_internal_url'] = 'grpc://kas.internal.gitlab.example.com'
gitlab_rails['gitlab_kas_external_k8s_proxy_url'] = 'https://gitlab.example.com/-/kubernetes-agent/k8s-proxy/'
@@ -114,31 +113,7 @@ To enable the agent server on multiple nodes:
### For GitLab Helm Chart
-For GitLab [Helm Chart](https://docs.gitlab.com/charts/) installations:
-
-1. Set `global.kas.enabled` to `true`. For example, in a shell with `helm` and `kubectl`
- installed, run:
-
- ```shell
- helm repo add gitlab https://charts.gitlab.io/
- helm repo update
- helm upgrade --install gitlab gitlab/gitlab \
- --timeout 600s \
- --set global.hosts.domain=<YOUR_DOMAIN> \
- --set global.hosts.externalIP=<YOUR_IP> \
- --set certmanager-issuer.email=<YOUR_EMAIL> \
- --set global.kas.enabled=true # <-- without this setting, the agent server will not be installed
- ```
-
-1. To configure the agent server, use a `gitlab.kas` sub-section in your `values.yaml` file:
-
- ```yaml
- gitlab:
- kas:
- # put your custom options here
- ```
-
-For details, see [how to use the GitLab-KAS chart](https://docs.gitlab.com/charts/charts/gitlab/kas/).
+See [how to use the GitLab-KAS chart](https://docs.gitlab.com/charts/charts/gitlab/kas/).
## Kubernetes API proxy cookie
diff --git a/doc/administration/credentials_inventory.md b/doc/administration/credentials_inventory.md
index 221ab8360ea..39cbf4e0dc8 100644
--- a/doc/administration/credentials_inventory.md
+++ b/doc/administration/credentials_inventory.md
@@ -92,6 +92,6 @@ credentials inventory GPG Keys tab, as well as the following properties:
- Who the GPG key belongs to.
- The ID of the GPG key.
-- Whether the GPG key is [verified or unverified](../user/project/repository/gpg_signed_commits/index.md).
+- Whether the GPG key is [verified or unverified](../user/project/repository/signed_commits/gpg.md).
![Credentials inventory page - GPG keys](img/credentials_inventory_gpg_keys_v14_9.png)
diff --git a/doc/administration/gitaly/configure_gitaly.md b/doc/administration/gitaly/configure_gitaly.md
index 2b94bfd299d..dbcdd183080 100644
--- a/doc/administration/gitaly/configure_gitaly.md
+++ b/doc/administration/gitaly/configure_gitaly.md
@@ -1552,7 +1552,7 @@ Configure Gitaly to sign commits made with the GitLab UI in one of two ways:
:::TabTitle Linux package (Omnibus)
-1. [Create a GPG key](../../user/project/repository/gpg_signed_commits/index.md#create-a-gpg-key)
+1. [Create a GPG key](../../user/project/repository/signed_commits/gpg.md#create-a-gpg-key)
and export it, or [create an SSH key](../../user/ssh.md#generate-an-ssh-key-pair). For optimal performance, use an EdDSA key.
Export GPG key:
@@ -1584,7 +1584,7 @@ Configure Gitaly to sign commits made with the GitLab UI in one of two ways:
:::TabTitle Self-compiled (source)
-1. [Create a GPG key](../../user/project/repository/gpg_signed_commits/index.md#create-a-gpg-key)
+1. [Create a GPG key](../../user/project/repository/signed_commits/gpg.md#create-a-gpg-key)
and export it, or [create an SSH key](../../user/ssh.md#generate-an-ssh-key-pair). For optimal performance, use an EdDSA key.
Export GPG key:
diff --git a/doc/api/commits.md b/doc/api/commits.md
index 68f8df2a3f8..22c11a40541 100644
--- a/doc/api/commits.md
+++ b/doc/api/commits.md
@@ -830,7 +830,7 @@ Example response:
## Get GPG signature of a commit
-Get the [GPG signature from a commit](../user/project/repository/gpg_signed_commits/index.md),
+Get the [GPG signature from a commit](../user/project/repository/signed_commits/gpg.md),
if it is signed. For unsigned commits, it results in a 404 response.
```plaintext
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 555cf559f0b..47fc3e940aa 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -12869,6 +12869,7 @@ Represents a HTTP header key/value that belongs to an audit streaming destinatio
| Name | Type | Description |
| ---- | ---- | ----------- |
+| <a id="auditeventstreamingheaderactive"></a>`active` | [`Boolean!`](#boolean) | Header is active or not. |
| <a id="auditeventstreamingheaderid"></a>`id` | [`ID!`](#id) | ID of the header. |
| <a id="auditeventstreamingheaderkey"></a>`key` | [`String!`](#string) | Key of the header. |
| <a id="auditeventstreamingheadervalue"></a>`value` | [`String!`](#string) | Value of the header. |
@@ -12881,6 +12882,7 @@ Represents a HTTP header key/value that belongs to an instance level audit strea
| Name | Type | Description |
| ---- | ---- | ----------- |
+| <a id="auditeventsstreaminginstanceheaderactive"></a>`active` | [`Boolean!`](#boolean) | Header is active or not. |
| <a id="auditeventsstreaminginstanceheaderid"></a>`id` | [`ID!`](#id) | ID of the header. |
| <a id="auditeventsstreaminginstanceheaderkey"></a>`key` | [`String!`](#string) | Key of the header. |
| <a id="auditeventsstreaminginstanceheadervalue"></a>`value` | [`String!`](#string) | Value of the header. |
@@ -15032,6 +15034,7 @@ A software dependency used by a project.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="dependencyid"></a>`id` | [`GlobalID!`](#globalid) | ID of the dependency. |
+| <a id="dependencylicenses"></a>`licenses` | [`[License!]`](#license) | Licenses associated to the dependency. |
| <a id="dependencylocation"></a>`location` | [`Location`](#location) | Information about where the dependency is located. |
| <a id="dependencyname"></a>`name` | [`String!`](#string) | Name of the dependency. |
| <a id="dependencypackager"></a>`packager` | [`PackageManager`](#packagemanager) | Description of the tool used to manage the dependency. |
@@ -18628,6 +18631,15 @@ Represents the Geo sync and verification state of an LFS object.
| <a id="lfsobjectregistryverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Verification state of the LfsObjectRegistry. |
| <a id="lfsobjectregistryverifiedat"></a>`verifiedAt` | [`Time`](#time) | Timestamp of the most recent successful verification of the LfsObjectRegistry. |
+### `License`
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="licensename"></a>`name` | [`String!`](#string) | Name of the license. |
+| <a id="licenseurl"></a>`url` | [`String!`](#string) | License URL in relation to SPDX. |
+
### `LicenseHistoryEntry`
Represents an entry from the Cloud License history.
@@ -29468,6 +29480,7 @@ Implementations:
| Name | Type | Description |
| ---- | ---- | ----------- |
+| <a id="baseheaderinterfaceactive"></a>`active` | [`Boolean!`](#boolean) | Header is active or not. |
| <a id="baseheaderinterfaceid"></a>`id` | [`ID!`](#id) | ID of the header. |
| <a id="baseheaderinterfacekey"></a>`key` | [`String!`](#string) | Key of the header. |
| <a id="baseheaderinterfacevalue"></a>`value` | [`String!`](#string) | Value of the header. |
diff --git a/doc/api/integrations.md b/doc/api/integrations.md
index 530506c9bed..a1619ae1f43 100644
--- a/doc/api/integrations.md
+++ b/doc/api/integrations.md
@@ -434,6 +434,7 @@ Parameters:
| --------- | ---- | -------- | ----------- |
| `token` | string | true | The Telegram bot token. For example, `123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11`. |
| `room` | string | true | Unique identifier for the target chat or the username of the target channel (in the format `@channelusername`) |
+| `notify_only_broken_pipelines` | boolean | false | Send notifications for broken pipelines |
| `push_events` | boolean | true | Enable notifications for push events |
| `issues_events` | boolean | true | Enable notifications for issue events |
| `confidential_issues_events` | boolean | true | Enable notifications for confidential issue events |
diff --git a/doc/api/tags.md b/doc/api/tags.md
index 4b85c70f901..808510bbb1c 100644
--- a/doc/api/tags.md
+++ b/doc/api/tags.md
@@ -181,7 +181,7 @@ Parameters:
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106578) in GitLab 15.7.
-Get the [X.509 signature from a tag](../user/project/repository/x509_signed_commits/index.md),
+Get the [X.509 signature from a tag](../user/project/repository/signed_commits/x509.md),
if it is signed. Unsigned tags return a `404 Not Found` response.
```plaintext
diff --git a/doc/development/database/avoiding_downtime_in_migrations.md b/doc/development/database/avoiding_downtime_in_migrations.md
index 4cd737a4538..5a2343e883c 100644
--- a/doc/development/database/avoiding_downtime_in_migrations.md
+++ b/doc/development/database/avoiding_downtime_in_migrations.md
@@ -14,7 +14,7 @@ requiring downtime.
## Dropping columns
-Removing columns is tricky because running GitLab processes expects these columns to exist, as ActiveRecord caches the tables schema, even if the columns are not referenced. This happens if the columns are not explicitly marked as ignored. To work around this safely, you need three steps in three releases:
+Removing columns is tricky because running GitLab processes expect these columns to exist, as ActiveRecord caches the tables schema, even if the columns are not referenced. This happens if the columns are not explicitly marked as ignored. To work around this safely, you need three steps in three releases:
1. [Ignoring the column](#ignoring-the-column-release-m) (release M)
1. [Dropping the column](#dropping-the-column-release-m1) (release M+1)
diff --git a/doc/development/fe_guide/guides.md b/doc/development/fe_guide/guides.md
new file mode 100644
index 00000000000..dc2fffcf10a
--- /dev/null
+++ b/doc/development/fe_guide/guides.md
@@ -0,0 +1,13 @@
+---
+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
+---
+
+# Guides
+
+This section contains guides to help our developers.
+For example, you can find information about how to accomplish a specific task,
+or how get proficient with a tool.
+
+Guidelines related to one specific technology, like Vue, should not be added to this section. Instead, add them to the `Tech Stack` section.
diff --git a/doc/raketasks/x509_signatures.md b/doc/raketasks/x509_signatures.md
index ab35f432fc2..ec85c400d49 100644
--- a/doc/raketasks/x509_signatures.md
+++ b/doc/raketasks/x509_signatures.md
@@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# X.509 signatures Rake task **(FREE SELF)**
-When [signing commits with X.509](../user/project/repository/x509_signed_commits/index.md),
+When [signing commits with X.509](../user/project/repository/signed_commits/x509.md),
the trust anchor might change and the signatures stored within the database must be updated.
## Update all X.509 signatures
diff --git a/doc/topics/git/index.md b/doc/topics/git/index.md
index 06bfd2051f5..e349cf0bb92 100644
--- a/doc/topics/git/index.md
+++ b/doc/topics/git/index.md
@@ -52,7 +52,7 @@ A typical Git user encounters these concepts soon after starting to use Git:
[Git history](../../user/project/repository/git_history.md).
- View a line-by-line editing history of a file with
[`git blame`](../../user/project/repository/git_blame.md).
-- [Sign commits](../../user/project/repository/gpg_signed_commits/index.md)
+- [Sign commits](../../user/project/repository/signed_commits/gpg.md)
for increased accountability and trust.
## Learn more complex commands
@@ -97,7 +97,7 @@ Git and GitLab, combined together, provide advanced features for repository mana
- When working with extremely large repositories, you can use a [partial clone](partial_clone.md)
of a repository instead of a complete clone.
- GitLab APIs for [`.gitignore` files](../../api/templates/gitignores.md),
- [commits](../../api/commits.md), [tags](../../api/tags.md),
+ [commits](../../api/commits.md), [tags](../../api/tags.md),
and [repositories](../../api/repositories.md).
### Git Large File Storage (LFS)
diff --git a/doc/update/deprecations.md b/doc/update/deprecations.md
index a141ccb98a5..d18cde272a2 100644
--- a/doc/update/deprecations.md
+++ b/doc/update/deprecations.md
@@ -375,6 +375,25 @@ To avoid any disruptions, you should replace `filepath` with `direct_asset_path`
<div class="deprecation breaking-change" data-milestone="17.0">
+### Geo: Legacy replication details routes for designs and projects deprecated
+
+<div class="deprecation-notes">
+- Announced in GitLab <span class="milestone">16.4</span>
+- Removal in GitLab <span class="milestone">17.0</span> ([breaking change](https://docs.gitlab.com/ee/update/terminology.html#breaking-change))
+- To discuss this change or learn more, see the [deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/424002).
+</div>
+
+As part of the migration of legacy data types to the [Geo self-service framework](https://docs.gitlab.com/ee/development/geo/framework.html), the following replication details routes are deprecated:
+
+- Designs `/admin/geo/replication/designs` replaced by `/admin/geo/sites/<Geo Node/Site ID>/replication/design_management_repositories`
+- Projects `/admin/geo/replication/projects` replaced by `/admin/geo/sites/<Geo Node/Site ID>/replication/projects`
+
+From GitLab 16.4 to 17.0, lookups for the legacy routes will automatically be redirected to the new routes. We will remove the redirections in 17.0. Please update any bookmarks or scripts that may use the legacy routes.
+
+</div>
+
+<div class="deprecation breaking-change" data-milestone="17.0">
+
### GitLab Helm chart values `gitlab.kas.privateApi.*` are deprecated
<div class="deprecation-notes">
diff --git a/doc/user/packages/package_registry/index.md b/doc/user/packages/package_registry/index.md
index 267cb46336a..59184b811d4 100644
--- a/doc/user/packages/package_registry/index.md
+++ b/doc/user/packages/package_registry/index.md
@@ -104,14 +104,9 @@ You can view which pipeline published the package, and the commit and user who t
### To import packages
If you already have packages built in a different registry, you can import them
-into your GitLab package registry with the [Packages Importer](https://gitlab.com/gitlab-org/ci-cd/package-stage/pkgs_importer).
+into your GitLab package registry with the [package importer](https://gitlab.com/gitlab-org/ci-cd/package-stage/pkgs_importer).
-The Packages Importer runs a CI/CD pipeline that [can import these package types](https://gitlab.com/gitlab-org/ci-cd/package-stage/pkgs_importer#formats-supported):
-
-- Maven
-- NPM
-- NuGet
-- PyPI
+For a list of supported packages, see [Importing packages from other repositories](supported_functionality.md#importing-packages-from-other-repositories).
## Reduce storage usage
diff --git a/doc/user/project/import/cvs.md b/doc/user/project/import/cvs.md
index f5f924ef603..90ed6cfdb2c 100644
--- a/doc/user/project/import/cvs.md
+++ b/doc/user/project/import/cvs.md
@@ -39,10 +39,10 @@ The following list illustrates the main differences between CVS and Git:
your state in version control, then you merge the other developer's changes.
You can also ask the other developer to do the merge and resolve any conflicts
themselves.
-- **Signed commits.** Git supports signing your commits with GPG for additional
+- **Signed commits.** Git supports
+ [signing your commits](../repository/signed_commits/index.md) for additional
security and verification that the commit indeed came from its original author.
- GitLab can [integrate with GPG](../repository/gpg_signed_commits/index.md)
- and show whether a signed commit is correctly verified.
+ GitLab shows whether a signed commit is correctly verified.
_Some of the items above were taken from this great
[Stack Overflow post](https://stackoverflow.com/a/824241/974710). For a more
diff --git a/doc/user/project/repository/gpg_signed_commits/index.md b/doc/user/project/repository/gpg_signed_commits/index.md
index 88f6917d4b6..592041ef4e2 100644
--- a/doc/user/project/repository/gpg_signed_commits/index.md
+++ b/doc/user/project/repository/gpg_signed_commits/index.md
@@ -1,284 +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: '../signed_commits/gpg.md'
+remove_date: '2023-12-01'
---
-# Sign commits with GPG **(FREE ALL)**
+This document was moved to [another location](../signed_commits/gpg.md).
-You can sign the commits you make in a GitLab repository with a
-GPG ([GNU Privacy Guard](https://gnupg.org/)) key.
-
-NOTE:
-GitLab uses the term GPG for all OpenPGP, PGP, and GPG-related material and
-implementations.
-
-For GitLab to consider a commit verified:
-
-- The committer must have a GPG public/private key pair.
-- The committer's public key must be uploaded to their GitLab account.
-- One of the email addresses in the GPG public key must match a **verified** email address
- used by the committer in GitLab. To keep this address private, use the automatically generated
- [private commit email address](../../../profile/index.md#use-an-automatically-generated-private-commit-email)
- GitLab provides in your profile.
-- The committer's email address must match the verified email address from the
- GPG key.
-
-GitLab uses its own keyring to verify the GPG signature. It does not access any
-public key server.
-
-GPG verified tags are not supported.
-
-For more details about GPG, refer to the [related topics list](#related-topics).
-
-## View a user's public GPG key
-
-To view a user's public GPG key, you can either:
-
-- Go to `https://gitlab.example.com/<USERNAME>.gpg`. GitLab displays the GPG key,
- if the user has configured one, or a blank page for users without a configured GPG key.
-- Go to the user's profile (such as `https://gitlab.example.com/<USERNAME>`). In the upper-right corner
- of the user's profile, select **View public GPG keys** (**{key}**).
-
-## Configure commit signing
-
-To sign commits, you must configure both your local machine and your GitLab account:
-
-1. [Create a GPG key](#create-a-gpg-key).
-1. [Add a GPG key to your account](#add-a-gpg-key-to-your-account).
-1. [Associate your GPG key with Git](#associate-your-gpg-key-with-git).
-1. [Sign your Git commits](#sign-your-git-commits).
-
-### Create a GPG key
-
-If you don't already have a GPG key, create one:
-
-1. [Install GPG](https://www.gnupg.org/download/) for your operating system.
- If your operating system has `gpg2` installed, replace `gpg` with `gpg2` in
- the commands on this page.
-1. To generate your key pair, run the command appropriate for your version of `gpg`:
-
- ```shell
- # Use this command for the default version of GPG, including
- # Gpg4win on Windows, and most macOS versions:
- gpg --gen-key
-
- # Use this command for versions of GPG later than 2.1.17:
- gpg --full-gen-key
- ```
-
-1. Select the algorithm your key should use, or press <kbd>Enter</kbd> to select
- the default option, `RSA and RSA`.
-1. Select the key length, in bits. GitLab recommends 4096-bit keys.
-1. Specify the validity period of your key. This value is subjective, and the
- default value is no expiration.
-1. To confirm your answers, enter `y`.
-1. Enter your name.
-1. Enter your email address. It must match a
- [verified email address](../../../profile/index.md#change-the-email-displayed-on-your-commits)
- in your GitLab account.
-1. Optional. Enter a comment to display in parentheses after your name.
-1. GPG displays the information you've entered so far. Edit the information or press
- <kbd>O</kbd> (for `Okay`) to continue.
-1. Enter a strong password, then enter it again to confirm it.
-1. To list your private GPG key, run this command, replacing
- `<EMAIL>` with the email address you used when you generated the key:
-
- ```shell
- gpg --list-secret-keys --keyid-format LONG <EMAIL>
- ```
-
-1. In the output, identify the `sec` line, and copy the GPG key ID. It begins after
- the `/` character. In this example, the key ID is `30F2B65B9246B6CA`:
-
- ```plaintext
- sec rsa4096/30F2B65B9246B6CA 2017-08-18 [SC]
- D5E4F29F3275DC0CDA8FFC8730F2B65B9246B6CA
- uid [ultimate] Mr. Robot <your_email>
- ssb rsa4096/B7ABC0813E4028C0 2017-08-18 [E]
- ```
-
-1. To show the associated public key, run this command, replacing `<ID>` with the
- GPG key ID from the previous step:
-
- ```shell
- gpg --armor --export <ID>
- ```
-
-1. Copy the public key, including the `BEGIN PGP PUBLIC KEY BLOCK` and
- `END PGP PUBLIC KEY BLOCK` lines. You need this key in the next step.
-
-### Add a GPG key to your account
-
-To add a GPG key to your user settings:
-
-1. Sign in to GitLab.
-1. On the left sidebar, select your avatar.
-1. Select **Edit profile**.
-1. Select **GPG Keys** (**{key}**).
-1. Select **Add new key**.
-1. In **Key**, paste your _public_ key.
-1. To add the key to your account, select **Add key**. GitLab shows the key's
- fingerprint, email address, and creation date:
-
- ![GPG key single page](img/profile_settings_gpg_keys_single_key.png)
-
-After you add a key, you cannot edit it. Instead, remove the offending key and re-add it.
-
-### Associate your GPG key with Git
-
-After you [create your GPG key](#create-a-gpg-key) and
-[add it to your account](#add-a-gpg-key-to-your-account), you must configure Git
-to use this key:
-
-1. Run this command to list the private GPG key you just created,
- replacing `<EMAIL>` with the email address for your key:
-
- ```shell
- gpg --list-secret-keys --keyid-format LONG <EMAIL>
- ```
-
-1. Copy the GPG private key ID that starts with `sec`. In this example, the private key ID is
- `30F2B65B9246B6CA`:
-
- ```plaintext
- sec rsa4096/30F2B65B9246B6CA 2017-08-18 [SC]
- D5E4F29F3275DC0CDA8FFC8730F2B65B9246B6CA
- uid [ultimate] Mr. Robot <your_email>
- ssb rsa4096/B7ABC0813E4028C0 2017-08-18 [E]
- ```
-
-1. Run this command to configure Git to sign your commits with your key,
- replacing `<KEY ID>` with your GPG key ID:
-
- ```shell
- git config --global user.signingkey <KEY ID>
- ```
-
-### Sign your Git commits
-
-After you [add your public key to your account](#add-a-gpg-key-to-your-account),
-you can sign individual commits manually, or configure Git to default to signed commits:
-
-- Sign individual Git commits manually:
- 1. Add `-S` flag to any commit you want to sign:
-
- ```shell
- git commit -S -m "My commit message"
- ```
-
- 1. Enter the passphrase of your GPG key when asked.
- 1. Push to GitLab and check that your commits [are verified](../signed_commits/index.md#verify-commits).
-- Sign all Git commits by default by running this command:
-
- ```shell
- git config --global commit.gpgsign true
- ```
-
-#### Set signing key conditionally
-
-If you maintain signing keys for separate purposes, such as work and personal
-use, use an `IncludeIf` statement in your `.gitconfig` file to set which key
-you sign commits with.
-
-Prerequisites:
-
-- Requires Git version 2.13 or later.
-
-1. In the same directory as your main `~/.gitconfig` file, create a second file,
- such as `.gitconfig-gitlab`.
-1. In your main `~/.gitconfig` file, add your Git settings for work in non-GitLab projects.
-1. Append this information to the end of your main `~/.gitconfig` file:
-
- ```ini
- # The contents of this file are included only for GitLab.com URLs
- [includeIf "hasconfig:remote.*.url:https://gitlab.com/**"]
-
- # Edit this line to point to your alternate configuration file
- path = ~/.gitconfig-gitlab
- ```
-
-1. In your alternate `.gitconfig-gitlab` file, add the configuration overrides to
- use when you're committing to a GitLab repository. All settings from your
- main `~/.gitconfig` file are retained unless you explicitly override them.
- In this example,
-
- ```ini
- # Alternate ~/.gitconfig-gitlab file
- # These values are used for repositories matching the string 'gitlab.com',
- # and override their corresponding values in ~/.gitconfig
-
- [user]
- email = you@example.com
- signingkey = <KEY ID>
-
- [commit]
- gpgsign = true
- ```
-
-## Revoke a GPG key
-
-If a GPG key becomes compromised, revoke it. Revoking a key changes both future and past commits:
-
-- Past commits signed by this key are marked as unverified.
-- Future commits signed by this key are marked as unverified.
-
-To revoke a GPG key:
-
-1. On the left sidebar, select your avatar.
-1. Select **Edit profile**.
-1. Select **GPG Keys** (**{key}**).
-1. Select **Revoke** next to the GPG key you want to delete.
-
-## Remove a GPG key
-
-When you remove a GPG key from your GitLab account:
-
-- Previous commits signed with this key remain verified.
-- Future commits (including any commits created but not yet pushed) that attempt
- to use this key are unverified.
-
-To remove a GPG key from your account:
-
-1. On the left sidebar, select your avatar.
-1. Select **Edit profile**.
-1. Select **GPG Keys** (**{key}**).
-1. Select **Remove** (**{remove}**) next to the GPG key you want to delete.
-
-If you must unverify both future and past commits,
-[revoke the associated GPG key](#revoke-a-gpg-key) instead.
-
-## Related topics
-
-- GPG resources:
- - [Git Tools - Signing Your Work](https://git-scm.com/book/en/v2/Git-Tools-Signing-Your-Work)
- - [Managing OpenPGP Keys](https://riseup.net/en/security/message-security/openpgp/gpg-keys)
- - [OpenPGP Best Practices](https://riseup.net/en/security/message-security/openpgp/best-practices)
- - [Creating a new GPG key with subkeys](https://www.void.gr/kargig/blog/2013/12/02/creating-a-new-gpg-key-with-subkeys/) (advanced)
- - [Review existing GPG keys in your instance](../../../../administration/credentials_inventory.md#review-existing-gpg-keys)
-
-## Troubleshooting
-
-### Secret key not available
-
-If you receive the errors `secret key not available`
-or `gpg: signing failed: secret key not available`, try using `gpg2` instead of `gpg`:
-
-```shell
-git config --global gpg.program gpg2
-```
-
-If your GPG key is password protected and the password entry prompt does not appear,
-add `export GPG_TTY=$(tty)` to your shell's `rc` file (commonly `~/.bashrc` or `~/.zshrc`)
-
-### GPG failed to sign the data
-
-If your GPG key is password protected and you receive the error:
-
-```shell
-error: gpg failed to sign the data
-fatal: failed to write commit object
-```
-
-If the password entry prompt does not appear, add `export GPG_TTY=$(tty)` to your shell's `rc` file
-(commonly `~/.bashrc` or `~/.zshrc`) and restart your terminal.
+<!-- This redirect file can be deleted after <2023-12-01>. -->
+<!-- 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/project/repository/index.md b/doc/user/project/repository/index.md
index e42004de376..a5a4214cc69 100644
--- a/doc/user/project/repository/index.md
+++ b/doc/user/project/repository/index.md
@@ -55,7 +55,7 @@ to a branch in the repository. When you use the command line, you can commit mul
[Revert a commit](../merge_requests/revert_changes.md#revert-a-commit)
from the UI to a selected branch.
- **Sign a commit:**
- Use GPG to [sign your commits](gpg_signed_commits/index.md).
+ Add extra security by [signing your commits](signed_commits/index.md).
## Clone a repository
diff --git a/doc/user/project/repository/push_rules.md b/doc/user/project/repository/push_rules.md
index 7176cf84dd0..d61d09301a5 100644
--- a/doc/user/project/repository/push_rules.md
+++ b/doc/user/project/repository/push_rules.md
@@ -126,7 +126,7 @@ Some validation examples:
Use these rules to prevent unintended consequences.
-- **Reject unsigned commits**: Commit must be signed through [GPG](gpg_signed_commits/index.md). This rule
+- **Reject unsigned commits**: Commit must be signed through [GPG](signed_commits/gpg.md). This rule
can block some legitimate commits [created in the Web IDE](#reject-unsigned-commits-push-rule-disables-web-ide),
and allow [unsigned commits created in the GitLab UI](#unsigned-commits-created-in-the-gitlab-ui).
- **Do not allow users to remove Git tags with `git push`**: Users cannot use `git push` to remove Git tags.
@@ -274,7 +274,7 @@ to use them as standard characters in a match condition.
## Related topics
- [Git server hooks](../../../administration/server_hooks.md) (previously called server hooks), to create complex custom push rules
-- [Signing commits with GPG](gpg_signed_commits/index.md)
+- [Signing commits with GPG](signed_commits/gpg.md)
- [Protected branches](../protected_branches.md)
## Troubleshooting
diff --git a/doc/user/project/repository/signed_commits/gpg.md b/doc/user/project/repository/signed_commits/gpg.md
new file mode 100644
index 00000000000..88f6917d4b6
--- /dev/null
+++ b/doc/user/project/repository/signed_commits/gpg.md
@@ -0,0 +1,284 @@
+---
+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
+---
+
+# Sign commits with GPG **(FREE ALL)**
+
+You can sign the commits you make in a GitLab repository with a
+GPG ([GNU Privacy Guard](https://gnupg.org/)) key.
+
+NOTE:
+GitLab uses the term GPG for all OpenPGP, PGP, and GPG-related material and
+implementations.
+
+For GitLab to consider a commit verified:
+
+- The committer must have a GPG public/private key pair.
+- The committer's public key must be uploaded to their GitLab account.
+- One of the email addresses in the GPG public key must match a **verified** email address
+ used by the committer in GitLab. To keep this address private, use the automatically generated
+ [private commit email address](../../../profile/index.md#use-an-automatically-generated-private-commit-email)
+ GitLab provides in your profile.
+- The committer's email address must match the verified email address from the
+ GPG key.
+
+GitLab uses its own keyring to verify the GPG signature. It does not access any
+public key server.
+
+GPG verified tags are not supported.
+
+For more details about GPG, refer to the [related topics list](#related-topics).
+
+## View a user's public GPG key
+
+To view a user's public GPG key, you can either:
+
+- Go to `https://gitlab.example.com/<USERNAME>.gpg`. GitLab displays the GPG key,
+ if the user has configured one, or a blank page for users without a configured GPG key.
+- Go to the user's profile (such as `https://gitlab.example.com/<USERNAME>`). In the upper-right corner
+ of the user's profile, select **View public GPG keys** (**{key}**).
+
+## Configure commit signing
+
+To sign commits, you must configure both your local machine and your GitLab account:
+
+1. [Create a GPG key](#create-a-gpg-key).
+1. [Add a GPG key to your account](#add-a-gpg-key-to-your-account).
+1. [Associate your GPG key with Git](#associate-your-gpg-key-with-git).
+1. [Sign your Git commits](#sign-your-git-commits).
+
+### Create a GPG key
+
+If you don't already have a GPG key, create one:
+
+1. [Install GPG](https://www.gnupg.org/download/) for your operating system.
+ If your operating system has `gpg2` installed, replace `gpg` with `gpg2` in
+ the commands on this page.
+1. To generate your key pair, run the command appropriate for your version of `gpg`:
+
+ ```shell
+ # Use this command for the default version of GPG, including
+ # Gpg4win on Windows, and most macOS versions:
+ gpg --gen-key
+
+ # Use this command for versions of GPG later than 2.1.17:
+ gpg --full-gen-key
+ ```
+
+1. Select the algorithm your key should use, or press <kbd>Enter</kbd> to select
+ the default option, `RSA and RSA`.
+1. Select the key length, in bits. GitLab recommends 4096-bit keys.
+1. Specify the validity period of your key. This value is subjective, and the
+ default value is no expiration.
+1. To confirm your answers, enter `y`.
+1. Enter your name.
+1. Enter your email address. It must match a
+ [verified email address](../../../profile/index.md#change-the-email-displayed-on-your-commits)
+ in your GitLab account.
+1. Optional. Enter a comment to display in parentheses after your name.
+1. GPG displays the information you've entered so far. Edit the information or press
+ <kbd>O</kbd> (for `Okay`) to continue.
+1. Enter a strong password, then enter it again to confirm it.
+1. To list your private GPG key, run this command, replacing
+ `<EMAIL>` with the email address you used when you generated the key:
+
+ ```shell
+ gpg --list-secret-keys --keyid-format LONG <EMAIL>
+ ```
+
+1. In the output, identify the `sec` line, and copy the GPG key ID. It begins after
+ the `/` character. In this example, the key ID is `30F2B65B9246B6CA`:
+
+ ```plaintext
+ sec rsa4096/30F2B65B9246B6CA 2017-08-18 [SC]
+ D5E4F29F3275DC0CDA8FFC8730F2B65B9246B6CA
+ uid [ultimate] Mr. Robot <your_email>
+ ssb rsa4096/B7ABC0813E4028C0 2017-08-18 [E]
+ ```
+
+1. To show the associated public key, run this command, replacing `<ID>` with the
+ GPG key ID from the previous step:
+
+ ```shell
+ gpg --armor --export <ID>
+ ```
+
+1. Copy the public key, including the `BEGIN PGP PUBLIC KEY BLOCK` and
+ `END PGP PUBLIC KEY BLOCK` lines. You need this key in the next step.
+
+### Add a GPG key to your account
+
+To add a GPG key to your user settings:
+
+1. Sign in to GitLab.
+1. On the left sidebar, select your avatar.
+1. Select **Edit profile**.
+1. Select **GPG Keys** (**{key}**).
+1. Select **Add new key**.
+1. In **Key**, paste your _public_ key.
+1. To add the key to your account, select **Add key**. GitLab shows the key's
+ fingerprint, email address, and creation date:
+
+ ![GPG key single page](img/profile_settings_gpg_keys_single_key.png)
+
+After you add a key, you cannot edit it. Instead, remove the offending key and re-add it.
+
+### Associate your GPG key with Git
+
+After you [create your GPG key](#create-a-gpg-key) and
+[add it to your account](#add-a-gpg-key-to-your-account), you must configure Git
+to use this key:
+
+1. Run this command to list the private GPG key you just created,
+ replacing `<EMAIL>` with the email address for your key:
+
+ ```shell
+ gpg --list-secret-keys --keyid-format LONG <EMAIL>
+ ```
+
+1. Copy the GPG private key ID that starts with `sec`. In this example, the private key ID is
+ `30F2B65B9246B6CA`:
+
+ ```plaintext
+ sec rsa4096/30F2B65B9246B6CA 2017-08-18 [SC]
+ D5E4F29F3275DC0CDA8FFC8730F2B65B9246B6CA
+ uid [ultimate] Mr. Robot <your_email>
+ ssb rsa4096/B7ABC0813E4028C0 2017-08-18 [E]
+ ```
+
+1. Run this command to configure Git to sign your commits with your key,
+ replacing `<KEY ID>` with your GPG key ID:
+
+ ```shell
+ git config --global user.signingkey <KEY ID>
+ ```
+
+### Sign your Git commits
+
+After you [add your public key to your account](#add-a-gpg-key-to-your-account),
+you can sign individual commits manually, or configure Git to default to signed commits:
+
+- Sign individual Git commits manually:
+ 1. Add `-S` flag to any commit you want to sign:
+
+ ```shell
+ git commit -S -m "My commit message"
+ ```
+
+ 1. Enter the passphrase of your GPG key when asked.
+ 1. Push to GitLab and check that your commits [are verified](../signed_commits/index.md#verify-commits).
+- Sign all Git commits by default by running this command:
+
+ ```shell
+ git config --global commit.gpgsign true
+ ```
+
+#### Set signing key conditionally
+
+If you maintain signing keys for separate purposes, such as work and personal
+use, use an `IncludeIf` statement in your `.gitconfig` file to set which key
+you sign commits with.
+
+Prerequisites:
+
+- Requires Git version 2.13 or later.
+
+1. In the same directory as your main `~/.gitconfig` file, create a second file,
+ such as `.gitconfig-gitlab`.
+1. In your main `~/.gitconfig` file, add your Git settings for work in non-GitLab projects.
+1. Append this information to the end of your main `~/.gitconfig` file:
+
+ ```ini
+ # The contents of this file are included only for GitLab.com URLs
+ [includeIf "hasconfig:remote.*.url:https://gitlab.com/**"]
+
+ # Edit this line to point to your alternate configuration file
+ path = ~/.gitconfig-gitlab
+ ```
+
+1. In your alternate `.gitconfig-gitlab` file, add the configuration overrides to
+ use when you're committing to a GitLab repository. All settings from your
+ main `~/.gitconfig` file are retained unless you explicitly override them.
+ In this example,
+
+ ```ini
+ # Alternate ~/.gitconfig-gitlab file
+ # These values are used for repositories matching the string 'gitlab.com',
+ # and override their corresponding values in ~/.gitconfig
+
+ [user]
+ email = you@example.com
+ signingkey = <KEY ID>
+
+ [commit]
+ gpgsign = true
+ ```
+
+## Revoke a GPG key
+
+If a GPG key becomes compromised, revoke it. Revoking a key changes both future and past commits:
+
+- Past commits signed by this key are marked as unverified.
+- Future commits signed by this key are marked as unverified.
+
+To revoke a GPG key:
+
+1. On the left sidebar, select your avatar.
+1. Select **Edit profile**.
+1. Select **GPG Keys** (**{key}**).
+1. Select **Revoke** next to the GPG key you want to delete.
+
+## Remove a GPG key
+
+When you remove a GPG key from your GitLab account:
+
+- Previous commits signed with this key remain verified.
+- Future commits (including any commits created but not yet pushed) that attempt
+ to use this key are unverified.
+
+To remove a GPG key from your account:
+
+1. On the left sidebar, select your avatar.
+1. Select **Edit profile**.
+1. Select **GPG Keys** (**{key}**).
+1. Select **Remove** (**{remove}**) next to the GPG key you want to delete.
+
+If you must unverify both future and past commits,
+[revoke the associated GPG key](#revoke-a-gpg-key) instead.
+
+## Related topics
+
+- GPG resources:
+ - [Git Tools - Signing Your Work](https://git-scm.com/book/en/v2/Git-Tools-Signing-Your-Work)
+ - [Managing OpenPGP Keys](https://riseup.net/en/security/message-security/openpgp/gpg-keys)
+ - [OpenPGP Best Practices](https://riseup.net/en/security/message-security/openpgp/best-practices)
+ - [Creating a new GPG key with subkeys](https://www.void.gr/kargig/blog/2013/12/02/creating-a-new-gpg-key-with-subkeys/) (advanced)
+ - [Review existing GPG keys in your instance](../../../../administration/credentials_inventory.md#review-existing-gpg-keys)
+
+## Troubleshooting
+
+### Secret key not available
+
+If you receive the errors `secret key not available`
+or `gpg: signing failed: secret key not available`, try using `gpg2` instead of `gpg`:
+
+```shell
+git config --global gpg.program gpg2
+```
+
+If your GPG key is password protected and the password entry prompt does not appear,
+add `export GPG_TTY=$(tty)` to your shell's `rc` file (commonly `~/.bashrc` or `~/.zshrc`)
+
+### GPG failed to sign the data
+
+If your GPG key is password protected and you receive the error:
+
+```shell
+error: gpg failed to sign the data
+fatal: failed to write commit object
+```
+
+If the password entry prompt does not appear, add `export GPG_TTY=$(tty)` to your shell's `rc` file
+(commonly `~/.bashrc` or `~/.zshrc`) and restart your terminal.
diff --git a/doc/user/project/repository/gpg_signed_commits/img/profile_settings_gpg_keys_single_key.png b/doc/user/project/repository/signed_commits/img/profile_settings_gpg_keys_single_key.png
index ae0a8696c6c..ae0a8696c6c 100644
--- a/doc/user/project/repository/gpg_signed_commits/img/profile_settings_gpg_keys_single_key.png
+++ b/doc/user/project/repository/signed_commits/img/profile_settings_gpg_keys_single_key.png
Binary files differ
diff --git a/doc/user/project/repository/gpg_signed_commits/img/project_signed_and_unsigned_commits.png b/doc/user/project/repository/signed_commits/img/project_signed_and_unsigned_commits.png
index e1d44f15f3f..e1d44f15f3f 100644
--- a/doc/user/project/repository/gpg_signed_commits/img/project_signed_and_unsigned_commits.png
+++ b/doc/user/project/repository/signed_commits/img/project_signed_and_unsigned_commits.png
Binary files differ
diff --git a/doc/user/project/repository/gpg_signed_commits/img/project_signed_commit_unverified_signature.png b/doc/user/project/repository/signed_commits/img/project_signed_commit_unverified_signature.png
index 763a677f94a..763a677f94a 100644
--- a/doc/user/project/repository/gpg_signed_commits/img/project_signed_commit_unverified_signature.png
+++ b/doc/user/project/repository/signed_commits/img/project_signed_commit_unverified_signature.png
Binary files differ
diff --git a/doc/user/project/repository/gpg_signed_commits/img/project_signed_commit_verified_signature.png b/doc/user/project/repository/signed_commits/img/project_signed_commit_verified_signature.png
index 1b6fa3fc2e2..1b6fa3fc2e2 100644
--- a/doc/user/project/repository/gpg_signed_commits/img/project_signed_commit_verified_signature.png
+++ b/doc/user/project/repository/signed_commits/img/project_signed_commit_verified_signature.png
Binary files differ
diff --git a/doc/user/project/repository/signed_commits/index.md b/doc/user/project/repository/signed_commits/index.md
index 148e775f161..e6632ecb81a 100644
--- a/doc/user/project/repository/signed_commits/index.md
+++ b/doc/user/project/repository/signed_commits/index.md
@@ -15,9 +15,9 @@ commits from unverified users.
Sign commits with your:
-- [SSH key](../ssh_signed_commits/index.md).
-- [GPG key](../gpg_signed_commits/index.md).
-- [Personal x.509 certificate](../x509_signed_commits/index.md).
+- [SSH key](ssh.md).
+- [GPG key](gpg.md).
+- [Personal x.509 certificate](x509.md).
## Verify commits
@@ -35,14 +35,14 @@ they are signed:
or **Unverified** badge, depending on the verification status of the signature.
Unsigned commits do not display a badge:
- ![Signed and unsigned commits](../gpg_signed_commits/img/project_signed_and_unsigned_commits.png)
+ ![Signed and unsigned commits](img/project_signed_and_unsigned_commits.png)
1. To display the signature details for a commit, select **Verified** to see
the fingerprint or key ID:
- ![Signed commit with verified signature](../gpg_signed_commits/img/project_signed_commit_verified_signature.png)
+ ![Signed commit with verified signature](img/project_signed_commit_verified_signature.png)
- ![Signed commit with unverified signature](../gpg_signed_commits/img/project_signed_commit_unverified_signature.png)
+ ![Signed commit with unverified signature](img/project_signed_commit_unverified_signature.png)
You can also [use the Commits API](../../../../api/commits.md#get-gpg-signature-of-a-commit)
to check a commit's signature.
@@ -60,5 +60,5 @@ can fail for multiple reasons:
| `SAME_USER_DIFFERENT_EMAIL` | The GPG key used to sign the commit does not contain the committer email, but does contain a different valid email for the committer. | Amend the commit to use an email address that matches the GPG key, or update the GPG key [to include the email address](https://security.stackexchange.com/a/261468). |
| `OTHER_USER` | The signature and GPG key are valid, but the key belongs to a different user than the committer. | Amend the commit to use the correct email address, or amend the commit to use a GPG key associated with your user. |
| `UNVERIFIED_KEY` | The key associated with the GPG signature has no verified email address associated with the committer. | Add and verify the email to your GitLab profile, [update the GPG key to include the email address](https://security.stackexchange.com/a/261468), or amend the commit to use a different committer email address. |
-| `UNKNOWN_KEY` | The GPG key associated with the GPG signature for this commit is unknown to GitLab. | [Add the GPG key](../gpg_signed_commits/index.md#add-a-gpg-key-to-your-account) to your GitLab profile. |
+| `UNKNOWN_KEY` | The GPG key associated with the GPG signature for this commit is unknown to GitLab. | [Add the GPG key](gpg.md#add-a-gpg-key-to-your-account) to your GitLab profile. |
| `MULTIPLE_SIGNATURES` | Multiple GPG or X.509 signatures have been found for the commit. | Amend the commit to use only one GPG or X.509 signature. |
diff --git a/doc/user/project/repository/signed_commits/ssh.md b/doc/user/project/repository/signed_commits/ssh.md
new file mode 100644
index 00000000000..3572e56da84
--- /dev/null
+++ b/doc/user/project/repository/signed_commits/ssh.md
@@ -0,0 +1,167 @@
+---
+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/engineering/ux/technical-writing/#assignments
+---
+
+# Sign commits with SSH keys **(FREE ALL)**
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/343879) in GitLab 15.7 [with a flag](../../../../administration/feature_flags.md) named `ssh_commit_signatures`. Enabled by default.
+> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/384202) in GitLab 15.8. Feature flag `ssh_commit_signatures` removed.
+
+When you sign commits with SSH keys, GitLab uses the SSH public keys associated
+with your GitLab account to cryptographically verify the commit signature.
+If successful, GitLab displays a **Verified** label on the commit.
+
+You may use the same SSH keys for `git+ssh` authentication to GitLab
+and signing commit signatures as long as their usage type is **Authentication & Signing**.
+It can be verified on the page for [adding an SSH key to your GitLab account](../../../ssh.md#add-an-ssh-key-to-your-gitlab-account).
+
+For more information about managing the SSH keys associated with your GitLab account, see
+[Use SSH keys to communicate with GitLab](../../../ssh.md).
+
+## Configure Git to sign commits with your SSH key
+
+After you [create an SSH key](../../../ssh.md#generate-an-ssh-key-pair) and
+[add it to your GitLab account](../../../ssh.md#add-an-ssh-key-to-your-gitlab-account)
+or [generate it using a password manager](../../../ssh.md#generate-an-ssh-key-pair-with-a-password-manager),
+configure Git to begin using the key.
+
+Prerequisites:
+
+- Git 2.34.0 or newer.
+- OpenSSH 8.0 or newer.
+
+ NOTE:
+ OpenSSH 8.7 has broken signing functionality. If you are on OpenSSH 8.7, upgrade to OpenSSH 8.8.
+
+- A SSH key with the usage type of either **Authentication & Signing** or **Signing**.
+ The SSH key must be one of these types:
+ - [ED25519](../../../ssh.md#ed25519-ssh-keys) (recommended)
+ - [RSA](../../../ssh.md#rsa-ssh-keys)
+
+To configure Git to use your key:
+
+1. Configure Git to use SSH for commit signing:
+
+ ```shell
+ git config --global gpg.format ssh
+ ```
+
+1. Specify which SSH key should be used as the signing key, changing the filename
+ (here, `~/.ssh/examplekey`) to the location of your key. The filename may
+ differ, depending on how you generated your key:
+
+ ```shell
+ git config --global user.signingkey ~/.ssh/examplekey
+ ```
+
+## Sign commits with your SSH key
+
+Prerequisites:
+
+- You've [created an SSH key](../../../ssh.md#generate-an-ssh-key-pair).
+- You've [added the key](../../../ssh.md#add-an-ssh-key-to-your-gitlab-account) to your GitLab account.
+- You've [configured Git to sign commits](#configure-git-to-sign-commits-with-your-ssh-key) with your SSH key.
+
+To sign a commit:
+
+1. Use the `-S` flag when signing your commits:
+
+ ```shell
+ git commit -S -m "My commit msg"
+ ```
+
+1. Optional. If you don't want to type the `-S` flag every time you commit, tell
+ Git to sign your commits automatically:
+
+ ```shell
+ git config --global commit.gpgsign true
+ ```
+
+1. If your SSH key is protected, Git prompts you to enter your passphrase.
+1. Push to GitLab.
+1. Check that your commits [are verified](#verify-commits).
+ Signature verification uses the `allowed_signers` file to associate emails and SSH keys.
+ For help configuring this file, read [Verify commits locally](#verify-commits-locally).
+
+## Verify commits
+
+You can verify all types of signed commits
+[in the GitLab UI](../signed_commits/index.md#verify-commits). Commits signed
+with an SSH key can also be verified locally.
+
+### Verify commits locally
+
+To verify commits locally, create an
+[allowed signers file](https://man7.org/linux/man-pages/man1/ssh-keygen.1.html#ALLOWED_SIGNERS)
+for Git to associate SSH public keys with users:
+
+1. Create an allowed signers file:
+
+ ```shell
+ touch allowed_signers
+ ```
+
+1. Configure the `allowed_signers` file in Git:
+
+ ```shell
+ git config gpg.ssh.allowedSignersFile "$(pwd)/allowed_signers"
+ ```
+
+1. Add your entry to the allowed signers file. Use this command to add your
+ email address and public SSH key to the `allowed_signers` file. Replace `<MY_KEY>`
+ with the name of your key, and `~/.ssh/allowed_signers`
+ with the location of your project's `allowed_signers` file:
+
+ ```shell
+ # Modify this line to meet your needs.
+ # Declaring the `git` namespace helps prevent cross-protocol attacks.
+ echo "$(git config --get user.email) namespaces=\"git\" $(cat ~/.ssh/<MY_KEY>.pub)" >> ~/.ssh/allowed_signers
+ ```
+
+ The resulting entry in the `allowed_signers` file contains your email address, key type,
+ and key contents, like this:
+
+ ```plaintext
+ example@gitlab.com namespaces="git" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAmaTS47vRmsKyLyK1jlIFJn/i8wdGQ3J49LYyIYJ2hv
+ ```
+
+1. Repeat the previous step for each user who you want to verify signatures for.
+ Consider checking this file in to your Git repository if you want to locally
+ verify signatures for many different contributors.
+
+1. Use `git log --show-signature` to view the signature status for the commits:
+
+ ```shell
+ $ git log --show-signature
+
+ commit e2406b6cd8ebe146835ceab67ff4a5a116e09154 (HEAD -> main, origin/main, origin/HEAD)
+ Good "git" signature for johndoe@example.com with ED25519 key SHA256:Ar44iySGgxic+U6Dph4Z9Rp+KDaix5SFGFawovZLAcc
+ Author: John Doe <johndoe@example.com>
+ Date: Tue Nov 29 06:54:15 2022 -0600
+
+ SSH signed commit
+ ```
+
+## Revoke an SSH key for signing commits
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/108344) in GitLab 15.9.
+
+If an SSH key becomes compromised, revoke it. Revoking a key changes both future and past commits:
+
+- Past commits signed by this key are marked as unverified.
+- Future commits signed by this key are marked as unverified.
+
+To revoke an SSH key:
+
+1. On the left sidebar, select your avatar.
+1. Select **Edit profile**.
+1. On the left sidebar, select (**{key}**) **SSH Keys**.
+1. Select **Revoke** next to the SSH key you want to delete.
+
+## Related topics
+
+- [Sign commits and tags with X.509 certificates](../signed_commits/x509.md)
+- [Sign commits with GPG](gpg.md)
+- [Commits API](../../../../api/commits.md)
diff --git a/doc/user/project/repository/signed_commits/x509.md b/doc/user/project/repository/signed_commits/x509.md
new file mode 100644
index 00000000000..2d97925faa3
--- /dev/null
+++ b/doc/user/project/repository/signed_commits/x509.md
@@ -0,0 +1,362 @@
+---
+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
+---
+
+# Sign commits and tags with X.509 certificates **(FREE ALL)**
+
+[X.509](https://en.wikipedia.org/wiki/X.509) is a standard format for public key
+certificates issued by a public or private Public Key Infrastructure (PKI).
+Personal X.509 certificates are used for authentication or signing purposes
+such as S/MIME (Secure/Multipurpose Internet Mail Extensions).
+However, Git also supports signing of commits and tags with X.509 certificates in a
+similar way as with [GPG (GnuPG, or GNU Privacy Guard)](gpg.md).
+The main difference is the way GitLab determines whether or not the developer's signature is trusted:
+
+- For X.509, a root certificate authority is added to the GitLab trust store.
+ (A trust store is a repository of trusted security certificates.) Combined with
+ any required intermediate certificates in the signature, the developer's certificate
+ can be chained back to a trusted root certificate.
+- For GPG, developers [add their GPG key](gpg.md#add-a-gpg-key-to-your-account)
+ to their account.
+
+GitLab uses its own certificate store and therefore defines the
+[trust chain](https://www.ssl.com/faqs/what-is-a-certificate-authority/).
+For a commit or tag to be *verified* by GitLab:
+
+- The signing certificate email must match a verified email address in GitLab.
+- The GitLab instance must be able to establish a full trust chain
+ from the certificate in the signature to a trusted certificate in the GitLab certificate store.
+ This chain may include intermediate certificates supplied in the signature. You may
+ need to add certificates, such as Certificate Authority root certificates,
+ [to the GitLab certificate store](https://docs.gitlab.com/omnibus/settings/ssl/index.html#install-custom-public-certificates).
+- The signing time must be in the time range of the
+ [certificate validity](https://www.rfc-editor.org/rfc/rfc5280.html#section-4.1.2.5),
+ which is usually up to three years.
+- The signing time is equal to, or later than, the commit time.
+
+If a commit's status has already been determined and stored in the database,
+use the Rake task [to re-check the status](../../../../raketasks/x509_signatures.md).
+Refer to the [Troubleshooting section](#troubleshooting).
+GitLab checks certificate revocation lists on a daily basis with a background worker.
+
+## Limitations
+
+- Self-signed certificates without `authorityKeyIdentifier`,
+ `subjectKeyIdentifier`, and `crlDistributionPoints` are not supported. We
+ recommend using certificates from a PKI that are in line with
+ [RFC 5280](https://www.rfc-editor.org/rfc/rfc5280).
+- If you have more than one email in the Subject Alternative Name list in
+ your signing certificate,
+ [only the first one is used to verify commits](https://gitlab.com/gitlab-org/gitlab/-/issues/336677).
+- The `X509v3 Subject Key Identifier` (SKI) in the issuer certificate and the
+ signing certificate
+ [must be 40 characters long](https://gitlab.com/gitlab-org/gitlab/-/issues/332503).
+ If your SKI is shorter, commits don't show as verified in GitLab, and
+ short subject key identifiers may also
+ [cause errors when accessing the project](https://gitlab.com/gitlab-org/gitlab/-/issues/332464),
+ such as 'An error occurred while loading commit signatures' and
+ `HTTP 422 Unprocessable Entity` errors.
+
+## Configure for signed commits
+
+To sign your commits, tags, or both, you must:
+
+1. [Obtain an X.509 key pair](#obtain-an-x509-key-pair).
+1. [Associate your X.509 certificate with Git](#associate-your-x509-certificate-with-git).
+1. [Sign and verify commits](#sign-and-verify-commits).
+1. [Sign and verify tags](#sign-and-verify-tags).
+
+### Obtain an X.509 key pair
+
+If your organization has Public Key Infrastructure (PKI), that PKI provides
+an S/MIME key. If you do not have an S/MIME key pair from a PKI, you can either
+create your own self-signed pair, or purchase a pair.
+
+### Associate your X.509 certificate with Git
+
+To take advantage of X.509 signing, you need Git 2.19.0 or later. You can
+check your Git version with the command `git --version`.
+
+If you have the correct version, you can proceed to configure Git.
+
+### Linux
+
+Configure Git to use your key for signing:
+
+```shell
+signingkey=$( gpgsm --list-secret-keys | egrep '(key usage|ID)' | grep -B 1 digitalSignature | awk '/ID/ {print $2}' )
+git config --global user.signingkey $signingkey
+git config --global gpg.format x509
+```
+
+#### Windows and macOS
+
+To configure Windows or macOS:
+
+1. Install [S/MIME Sign](https://github.com/github/smimesign) by either:
+ - Downloading the installer.
+ - Running `brew install smimesign` on macOS.
+1. Get the ID of your certificate by running `smimesign --list-keys`.
+1. Set your signing key by running `git config --global user.signingkey <ID>`, replacing `<ID>` with the certificate ID.
+1. Configure X.509 with this command:
+
+ ```shell
+ git config --global gpg.x509.program smimesign
+ git config --global gpg.format x509
+ ```
+
+### Sign and verify commits
+
+After you have [associated your X.509 certificate with Git](#associate-your-x509-certificate-with-git) you
+can sign your commits:
+
+1. When you create a Git commit, add the `-S` flag:
+
+ ```shell
+ git commit -S -m "feat: x509 signed commits"
+ ```
+
+1. Push to GitLab, and check that your commits are verified with the `--show-signature` flag:
+
+ ```shell
+ git log --show-signature
+ ```
+
+1. *If you don't want to type the `-S` flag every time you commit,* run this command
+ for Git to sign your commits every time:
+
+ ```shell
+ git config --global commit.gpgsign true
+ ```
+
+### Sign and verify tags
+
+After you have [associated your X.509 certificate with Git](#associate-your-x509-certificate-with-git) you
+can start signing your tags:
+
+1. When you create a Git tag, add the `-s` flag:
+
+ ```shell
+ git tag -s v1.1.1 -m "My signed tag"
+ ```
+
+1. Push to GitLab and verify your tags are signed with this command:
+
+ ```shell
+ git tag --verify v1.1.1
+ ```
+
+1. *If you don't want to type the `-s` flag every time you tag,* run this command
+ for Git to sign your tags each time:
+
+ ```shell
+ git config --global tag.gpgsign true
+ ```
+
+## Related topics
+
+- [Rake task for X.509 signatures](../../../../raketasks/x509_signatures.md)
+
+## Troubleshooting
+
+For committers without administrator access, review the list of
+[verification problems with signed commits](../signed_commits/index.md#fix-verification-problems-with-signed-commits)
+for possible fixes. The other troubleshooting suggestions on this page require
+administrator access.
+
+### Re-verify commits
+
+GitLab stores the status of any checked commits in the database. You can use a
+Rake task to [check the status of any previously checked commits](../../../../raketasks/x509_signatures.md).
+
+After you make any changes, run this command:
+
+```shell
+sudo gitlab-rake gitlab:x509:update_signatures
+```
+
+### Main verification checks
+
+The code performs
+[these key checks](https://gitlab.com/gitlab-org/gitlab/-/blob/v14.1.0-ee/lib/gitlab/x509/signature.rb#L33),
+which all must return `verified`:
+
+- `x509_certificate.nil?` should be false.
+- `x509_certificate.revoked?` should be false.
+- `verified_signature` should be true.
+- `user.nil?` should be false.
+- `user.verified_emails.include?(@email)` should be true.
+- `certificate_email == @email` should be true.
+
+To investigate why a commit shows as `Unverified`:
+
+1. [Start a Rails console](../../../../administration/operations/rails_console.md#starting-a-rails-console-session):
+
+ ```shell
+ sudo gitlab-rails console
+ ```
+
+1. Identify the project (either by path or ID) and full commit SHA that you're investigating.
+ Use this information to create `signature` to run other checks against:
+
+ ```ruby
+ project = Project.find_by_full_path('group/subgroup/project')
+ project = Project.find_by_id('121')
+ commit = project.repository.commit_by(oid: '87fdbd0f9382781442053b0b76da729344e37653')
+ signedcommit=Gitlab::X509::Commit.new(commit)
+ signature=Gitlab::X509::Signature.new(signedcommit.signature_text, signedcommit.signed_text, commit.committer_email, commit.created_at)
+ ```
+
+ If you make changes to address issues identified running through the checks, restart the
+ Rails console and run though the checks again from the start.
+
+1. Check the certificate on the commit:
+
+ ```ruby
+ signature.x509_certificate.nil?
+ signature.x509_certificate.revoked?
+ ```
+
+ Both checks should return `false`:
+
+ ```ruby
+ > signature.x509_certificate.nil?
+ => false
+ > signature.x509_certificate.revoked?
+ => false
+ ```
+
+ A [known issue](https://gitlab.com/gitlab-org/gitlab/-/issues/332503) causes
+ these checks to fail with `Validation failed: Subject key identifier is invalid`.
+
+1. Run a cryptographic check on the signature. The code must return `true`:
+
+ ```ruby
+ signature.verified_signature
+ ```
+
+ If it returns `false` then [investigate this check further](#cryptographic-verification-checks).
+
+1. Confirm the email addresses match on the commit and the signature:
+
+ - The Rails console displays the email addresses being compared.
+ - The final command must return `true`:
+
+ ```ruby
+ sigemail=signature.__send__:certificate_email
+ commitemail=commit.committer_email
+ sigemail == commitemail
+ ```
+
+ A [known issue](https://gitlab.com/gitlab-org/gitlab/-/issues/336677) exists:
+ only the first email in the `Subject Alternative Name` list is compared. To
+ display the `Subject Alternative Name` list, run:
+
+ ```ruby
+ signature.__send__ :get_certificate_extension,'subjectAltName'
+ ```
+
+ If the developer's email address is not the first one in the list, this check
+ fails, and the commit is marked `unverified`.
+
+1. The email address on the commit must be associated with an account in GitLab.
+ This check should return `false`:
+
+ ```ruby
+ signature.user.nil?
+ ```
+
+1. Check the email address is associated with a user in GitLab. This check should
+ return a user, such as `#<User id:1234 @user_handle>`:
+
+ ```ruby
+ User.find_by_any_email(commit.committer_email)
+ ```
+
+ If it returns `nil`, the email address is not associated with a user, and the check fails.
+
+1. Confirm the developer's email address is verified. This check must return true:
+
+ ```ruby
+ signature.user.verified_emails.include?(commit.committer_email)
+ ```
+
+ If the previous check returned `nil`, this command displays an error:
+
+ ```plaintext
+ NoMethodError (undefined method `verified_emails' for nil:NilClass)
+ ```
+
+1. The verification status is stored in the database. To display the database record:
+
+ ```ruby
+ pp CommitSignatures::X509CommitSignature.by_commit_sha(commit.sha);nil
+ ```
+
+ If all the previous checks returned the correct values:
+
+ - `verification_status: "unverified"` indicates the database record needs
+ updating. [Use the Rake task](#re-verify-commits).
+
+ - `[]` indicates the database doesn't have a record yet. Locate the commit
+ in GitLab to check the signature and store the result.
+
+#### Cryptographic verification checks
+
+If GitLab determines that `verified_signature` is `false`, investigate the reason
+in the Rails console. These checks require `signature` to exist. Refer to the `signature`
+step of the previous [main verification checks](#main-verification-checks).
+
+1. Check the signature, without checking the issuer, returns `true`:
+
+ ```ruby
+ signature.__send__ :valid_signature?
+ ```
+
+1. Check the signing time and date. This check must return `true`:
+
+ ```ruby
+ signature.__send__ :valid_signing_time?
+ ```
+
+ - The code allows for code signing certificates to expire.
+ - A commit must be signed during the validity period of the certificate,
+ and at or after the commit's datestamp. Display the commit time and
+ certificate details including `not_before`, `not_after` with:
+
+ ```ruby
+ commit.created_at
+ pp signature.__send__ :cert; nil
+ ```
+
+1. Check the signature, including that TLS trust can be established. This check must return `true`:
+
+ ```ruby
+ signature.__send__(:p7).verify([], signature.__send__(:cert_store), signature.__send__(:signed_text))
+ ```
+
+ 1. If this fails, add the missing certificates required to establish trust
+ [to the GitLab certificate store](https://docs.gitlab.com/omnibus/settings/ssl/index.html#install-custom-public-certificates).
+
+ 1. After adding more certificates, (if these troubleshooting steps then pass)
+ run the Rake task to [re-verify commits](#re-verify-commits).
+
+ 1. Display the certificates, including in the signature:
+
+ ```ruby
+ pp signature.__send__(:p7).certificates ; nil
+ ```
+
+Ensure any additional intermediate certificates and the root certificate are added
+to the certificate store. For consistency with how certificate chains are built on
+web servers:
+
+- Git clients that are signing commits should include the certificate
+ and all intermediate certificates in the signature.
+- The GitLab certificate store should only contain the root.
+
+If you remove a root certificate from the GitLab
+trust store, such as when it expires, commit signatures which chain back to that
+root display as `unverified`.
diff --git a/doc/user/project/repository/ssh_signed_commits/index.md b/doc/user/project/repository/ssh_signed_commits/index.md
index 0e16bead064..89e3d811dba 100644
--- a/doc/user/project/repository/ssh_signed_commits/index.md
+++ b/doc/user/project/repository/ssh_signed_commits/index.md
@@ -1,167 +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/engineering/ux/technical-writing/#assignments
+redirect_to: '../signed_commits/ssh.md'
+remove_date: '2023-12-01'
---
-# Sign commits with SSH keys **(FREE ALL)**
+This document was moved to [another location](../signed_commits/ssh.md).
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/343879) in GitLab 15.7 [with a flag](../../../../administration/feature_flags.md) named `ssh_commit_signatures`. Enabled by default.
-> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/384202) in GitLab 15.8. Feature flag `ssh_commit_signatures` removed.
-
-When you sign commits with SSH keys, GitLab uses the SSH public keys associated
-with your GitLab account to cryptographically verify the commit signature.
-If successful, GitLab displays a **Verified** label on the commit.
-
-You may use the same SSH keys for `git+ssh` authentication to GitLab
-and signing commit signatures as long as their usage type is **Authentication & Signing**.
-It can be verified on the page for [adding an SSH key to your GitLab account](../../../ssh.md#add-an-ssh-key-to-your-gitlab-account).
-
-For more information about managing the SSH keys associated with your GitLab account, see
-[Use SSH keys to communicate with GitLab](../../../ssh.md).
-
-## Configure Git to sign commits with your SSH key
-
-After you [create an SSH key](../../../ssh.md#generate-an-ssh-key-pair) and
-[add it to your GitLab account](../../../ssh.md#add-an-ssh-key-to-your-gitlab-account)
-or [generate it using a password manager](../../../ssh.md#generate-an-ssh-key-pair-with-a-password-manager),
-configure Git to begin using the key.
-
-Prerequisites:
-
-- Git 2.34.0 or newer.
-- OpenSSH 8.0 or newer.
-
- NOTE:
- OpenSSH 8.7 has broken signing functionality. If you are on OpenSSH 8.7, upgrade to OpenSSH 8.8.
-
-- A SSH key with the usage type of either **Authentication & Signing** or **Signing**.
- The SSH key must be one of these types:
- - [ED25519](../../../ssh.md#ed25519-ssh-keys) (recommended)
- - [RSA](../../../ssh.md#rsa-ssh-keys)
-
-To configure Git to use your key:
-
-1. Configure Git to use SSH for commit signing:
-
- ```shell
- git config --global gpg.format ssh
- ```
-
-1. Specify which SSH key should be used as the signing key, changing the filename
- (here, `~/.ssh/examplekey`) to the location of your key. The filename may
- differ, depending on how you generated your key:
-
- ```shell
- git config --global user.signingkey ~/.ssh/examplekey
- ```
-
-## Sign commits with your SSH key
-
-Prerequisites:
-
-- You've [created an SSH key](../../../ssh.md#generate-an-ssh-key-pair).
-- You've [added the key](../../../ssh.md#add-an-ssh-key-to-your-gitlab-account) to your GitLab account.
-- You've [configured Git to sign commits](#configure-git-to-sign-commits-with-your-ssh-key) with your SSH key.
-
-To sign a commit:
-
-1. Use the `-S` flag when signing your commits:
-
- ```shell
- git commit -S -m "My commit msg"
- ```
-
-1. Optional. If you don't want to type the `-S` flag every time you commit, tell
- Git to sign your commits automatically:
-
- ```shell
- git config --global commit.gpgsign true
- ```
-
-1. If your SSH key is protected, Git prompts you to enter your passphrase.
-1. Push to GitLab.
-1. Check that your commits [are verified](#verify-commits).
- Signature verification uses the `allowed_signers` file to associate emails and SSH keys.
- For help configuring this file, read [Verify commits locally](#verify-commits-locally).
-
-## Verify commits
-
-You can verify all types of signed commits
-[in the GitLab UI](../signed_commits/index.md#verify-commits). Commits signed
-with an SSH key can also be verified locally.
-
-### Verify commits locally
-
-To verify commits locally, create an
-[allowed signers file](https://man7.org/linux/man-pages/man1/ssh-keygen.1.html#ALLOWED_SIGNERS)
-for Git to associate SSH public keys with users:
-
-1. Create an allowed signers file:
-
- ```shell
- touch allowed_signers
- ```
-
-1. Configure the `allowed_signers` file in Git:
-
- ```shell
- git config gpg.ssh.allowedSignersFile "$(pwd)/allowed_signers"
- ```
-
-1. Add your entry to the allowed signers file. Use this command to add your
- email address and public SSH key to the `allowed_signers` file. Replace `<MY_KEY>`
- with the name of your key, and `~/.ssh/allowed_signers`
- with the location of your project's `allowed_signers` file:
-
- ```shell
- # Modify this line to meet your needs.
- # Declaring the `git` namespace helps prevent cross-protocol attacks.
- echo "$(git config --get user.email) namespaces=\"git\" $(cat ~/.ssh/<MY_KEY>.pub)" >> ~/.ssh/allowed_signers
- ```
-
- The resulting entry in the `allowed_signers` file contains your email address, key type,
- and key contents, like this:
-
- ```plaintext
- example@gitlab.com namespaces="git" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAmaTS47vRmsKyLyK1jlIFJn/i8wdGQ3J49LYyIYJ2hv
- ```
-
-1. Repeat the previous step for each user who you want to verify signatures for.
- Consider checking this file in to your Git repository if you want to locally
- verify signatures for many different contributors.
-
-1. Use `git log --show-signature` to view the signature status for the commits:
-
- ```shell
- $ git log --show-signature
-
- commit e2406b6cd8ebe146835ceab67ff4a5a116e09154 (HEAD -> main, origin/main, origin/HEAD)
- Good "git" signature for johndoe@example.com with ED25519 key SHA256:Ar44iySGgxic+U6Dph4Z9Rp+KDaix5SFGFawovZLAcc
- Author: John Doe <johndoe@example.com>
- Date: Tue Nov 29 06:54:15 2022 -0600
-
- SSH signed commit
- ```
-
-## Revoke an SSH key for signing commits
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/108344) in GitLab 15.9.
-
-If an SSH key becomes compromised, revoke it. Revoking a key changes both future and past commits:
-
-- Past commits signed by this key are marked as unverified.
-- Future commits signed by this key are marked as unverified.
-
-To revoke an SSH key:
-
-1. On the left sidebar, select your avatar.
-1. Select **Edit profile**.
-1. On the left sidebar, select (**{key}**) **SSH Keys**.
-1. Select **Revoke** next to the SSH key you want to delete.
-
-## Related topics
-
-- [Sign commits and tags with X.509 certificates](../x509_signed_commits/index.md)
-- [Sign commits with GPG](../gpg_signed_commits/index.md)
-- [Commits API](../../../../api/commits.md)
+<!-- This redirect file can be deleted after <2023-12-01>. -->
+<!-- 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/project/repository/x509_signed_commits/index.md b/doc/user/project/repository/x509_signed_commits/index.md
index 5bd2e590b52..ae418581820 100644
--- a/doc/user/project/repository/x509_signed_commits/index.md
+++ b/doc/user/project/repository/x509_signed_commits/index.md
@@ -1,362 +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: '../signed_commits/x509.md'
+remove_date: '2023-12-01'
---
-# Sign commits and tags with X.509 certificates **(FREE ALL)**
+This document was moved to [another location](../signed_commits/x509.md).
-[X.509](https://en.wikipedia.org/wiki/X.509) is a standard format for public key
-certificates issued by a public or private Public Key Infrastructure (PKI).
-Personal X.509 certificates are used for authentication or signing purposes
-such as S/MIME (Secure/Multipurpose Internet Mail Extensions).
-However, Git also supports signing of commits and tags with X.509 certificates in a
-similar way as with [GPG (GnuPG, or GNU Privacy Guard)](../gpg_signed_commits/index.md).
-The main difference is the way GitLab determines whether or not the developer's signature is trusted:
-
-- For X.509, a root certificate authority is added to the GitLab trust store.
- (A trust store is a repository of trusted security certificates.) Combined with
- any required intermediate certificates in the signature, the developer's certificate
- can be chained back to a trusted root certificate.
-- For GPG, developers [add their GPG key](../gpg_signed_commits/index.md#add-a-gpg-key-to-your-account)
- to their account.
-
-GitLab uses its own certificate store and therefore defines the
-[trust chain](https://www.ssl.com/faqs/what-is-a-certificate-authority/).
-For a commit or tag to be *verified* by GitLab:
-
-- The signing certificate email must match a verified email address in GitLab.
-- The GitLab instance must be able to establish a full trust chain
- from the certificate in the signature to a trusted certificate in the GitLab certificate store.
- This chain may include intermediate certificates supplied in the signature. You may
- need to add certificates, such as Certificate Authority root certificates,
- [to the GitLab certificate store](https://docs.gitlab.com/omnibus/settings/ssl/index.html#install-custom-public-certificates).
-- The signing time must be in the time range of the
- [certificate validity](https://www.rfc-editor.org/rfc/rfc5280.html#section-4.1.2.5),
- which is usually up to three years.
-- The signing time is equal to, or later than, the commit time.
-
-If a commit's status has already been determined and stored in the database,
-use the Rake task [to re-check the status](../../../../raketasks/x509_signatures.md).
-Refer to the [Troubleshooting section](#troubleshooting).
-GitLab checks certificate revocation lists on a daily basis with a background worker.
-
-## Limitations
-
-- Self-signed certificates without `authorityKeyIdentifier`,
- `subjectKeyIdentifier`, and `crlDistributionPoints` are not supported. We
- recommend using certificates from a PKI that are in line with
- [RFC 5280](https://www.rfc-editor.org/rfc/rfc5280).
-- If you have more than one email in the Subject Alternative Name list in
- your signing certificate,
- [only the first one is used to verify commits](https://gitlab.com/gitlab-org/gitlab/-/issues/336677).
-- The `X509v3 Subject Key Identifier` (SKI) in the issuer certificate and the
- signing certificate
- [must be 40 characters long](https://gitlab.com/gitlab-org/gitlab/-/issues/332503).
- If your SKI is shorter, commits don't show as verified in GitLab, and
- short subject key identifiers may also
- [cause errors when accessing the project](https://gitlab.com/gitlab-org/gitlab/-/issues/332464),
- such as 'An error occurred while loading commit signatures' and
- `HTTP 422 Unprocessable Entity` errors.
-
-## Configure for signed commits
-
-To sign your commits, tags, or both, you must:
-
-1. [Obtain an X.509 key pair](#obtain-an-x509-key-pair).
-1. [Associate your X.509 certificate with Git](#associate-your-x509-certificate-with-git).
-1. [Sign and verify commits](#sign-and-verify-commits).
-1. [Sign and verify tags](#sign-and-verify-tags).
-
-### Obtain an X.509 key pair
-
-If your organization has Public Key Infrastructure (PKI), that PKI provides
-an S/MIME key. If you do not have an S/MIME key pair from a PKI, you can either
-create your own self-signed pair, or purchase a pair.
-
-### Associate your X.509 certificate with Git
-
-To take advantage of X.509 signing, you need Git 2.19.0 or later. You can
-check your Git version with the command `git --version`.
-
-If you have the correct version, you can proceed to configure Git.
-
-### Linux
-
-Configure Git to use your key for signing:
-
-```shell
-signingkey=$( gpgsm --list-secret-keys | egrep '(key usage|ID)' | grep -B 1 digitalSignature | awk '/ID/ {print $2}' )
-git config --global user.signingkey $signingkey
-git config --global gpg.format x509
-```
-
-#### Windows and macOS
-
-To configure Windows or macOS:
-
-1. Install [S/MIME Sign](https://github.com/github/smimesign) by either:
- - Downloading the installer.
- - Running `brew install smimesign` on macOS.
-1. Get the ID of your certificate by running `smimesign --list-keys`.
-1. Set your signing key by running `git config --global user.signingkey <ID>`, replacing `<ID>` with the certificate ID.
-1. Configure X.509 with this command:
-
- ```shell
- git config --global gpg.x509.program smimesign
- git config --global gpg.format x509
- ```
-
-### Sign and verify commits
-
-After you have [associated your X.509 certificate with Git](#associate-your-x509-certificate-with-git) you
-can sign your commits:
-
-1. When you create a Git commit, add the `-S` flag:
-
- ```shell
- git commit -S -m "feat: x509 signed commits"
- ```
-
-1. Push to GitLab, and check that your commits are verified with the `--show-signature` flag:
-
- ```shell
- git log --show-signature
- ```
-
-1. *If you don't want to type the `-S` flag every time you commit,* run this command
- for Git to sign your commits every time:
-
- ```shell
- git config --global commit.gpgsign true
- ```
-
-### Sign and verify tags
-
-After you have [associated your X.509 certificate with Git](#associate-your-x509-certificate-with-git) you
-can start signing your tags:
-
-1. When you create a Git tag, add the `-s` flag:
-
- ```shell
- git tag -s v1.1.1 -m "My signed tag"
- ```
-
-1. Push to GitLab and verify your tags are signed with this command:
-
- ```shell
- git tag --verify v1.1.1
- ```
-
-1. *If you don't want to type the `-s` flag every time you tag,* run this command
- for Git to sign your tags each time:
-
- ```shell
- git config --global tag.gpgsign true
- ```
-
-## Related topics
-
-- [Rake task for X.509 signatures](../../../../raketasks/x509_signatures.md)
-
-## Troubleshooting
-
-For committers without administrator access, review the list of
-[verification problems with signed commits](../signed_commits/index.md#fix-verification-problems-with-signed-commits)
-for possible fixes. The other troubleshooting suggestions on this page require
-administrator access.
-
-### Re-verify commits
-
-GitLab stores the status of any checked commits in the database. You can use a
-Rake task to [check the status of any previously checked commits](../../../../raketasks/x509_signatures.md).
-
-After you make any changes, run this command:
-
-```shell
-sudo gitlab-rake gitlab:x509:update_signatures
-```
-
-### Main verification checks
-
-The code performs
-[these key checks](https://gitlab.com/gitlab-org/gitlab/-/blob/v14.1.0-ee/lib/gitlab/x509/signature.rb#L33),
-which all must return `verified`:
-
-- `x509_certificate.nil?` should be false.
-- `x509_certificate.revoked?` should be false.
-- `verified_signature` should be true.
-- `user.nil?` should be false.
-- `user.verified_emails.include?(@email)` should be true.
-- `certificate_email == @email` should be true.
-
-To investigate why a commit shows as `Unverified`:
-
-1. [Start a Rails console](../../../../administration/operations/rails_console.md#starting-a-rails-console-session):
-
- ```shell
- sudo gitlab-rails console
- ```
-
-1. Identify the project (either by path or ID) and full commit SHA that you're investigating.
- Use this information to create `signature` to run other checks against:
-
- ```ruby
- project = Project.find_by_full_path('group/subgroup/project')
- project = Project.find_by_id('121')
- commit = project.repository.commit_by(oid: '87fdbd0f9382781442053b0b76da729344e37653')
- signedcommit=Gitlab::X509::Commit.new(commit)
- signature=Gitlab::X509::Signature.new(signedcommit.signature_text, signedcommit.signed_text, commit.committer_email, commit.created_at)
- ```
-
- If you make changes to address issues identified running through the checks, restart the
- Rails console and run though the checks again from the start.
-
-1. Check the certificate on the commit:
-
- ```ruby
- signature.x509_certificate.nil?
- signature.x509_certificate.revoked?
- ```
-
- Both checks should return `false`:
-
- ```ruby
- > signature.x509_certificate.nil?
- => false
- > signature.x509_certificate.revoked?
- => false
- ```
-
- A [known issue](https://gitlab.com/gitlab-org/gitlab/-/issues/332503) causes
- these checks to fail with `Validation failed: Subject key identifier is invalid`.
-
-1. Run a cryptographic check on the signature. The code must return `true`:
-
- ```ruby
- signature.verified_signature
- ```
-
- If it returns `false` then [investigate this check further](#cryptographic-verification-checks).
-
-1. Confirm the email addresses match on the commit and the signature:
-
- - The Rails console displays the email addresses being compared.
- - The final command must return `true`:
-
- ```ruby
- sigemail=signature.__send__:certificate_email
- commitemail=commit.committer_email
- sigemail == commitemail
- ```
-
- A [known issue](https://gitlab.com/gitlab-org/gitlab/-/issues/336677) exists:
- only the first email in the `Subject Alternative Name` list is compared. To
- display the `Subject Alternative Name` list, run:
-
- ```ruby
- signature.__send__ :get_certificate_extension,'subjectAltName'
- ```
-
- If the developer's email address is not the first one in the list, this check
- fails, and the commit is marked `unverified`.
-
-1. The email address on the commit must be associated with an account in GitLab.
- This check should return `false`:
-
- ```ruby
- signature.user.nil?
- ```
-
-1. Check the email address is associated with a user in GitLab. This check should
- return a user, such as `#<User id:1234 @user_handle>`:
-
- ```ruby
- User.find_by_any_email(commit.committer_email)
- ```
-
- If it returns `nil`, the email address is not associated with a user, and the check fails.
-
-1. Confirm the developer's email address is verified. This check must return true:
-
- ```ruby
- signature.user.verified_emails.include?(commit.committer_email)
- ```
-
- If the previous check returned `nil`, this command displays an error:
-
- ```plaintext
- NoMethodError (undefined method `verified_emails' for nil:NilClass)
- ```
-
-1. The verification status is stored in the database. To display the database record:
-
- ```ruby
- pp CommitSignatures::X509CommitSignature.by_commit_sha(commit.sha);nil
- ```
-
- If all the previous checks returned the correct values:
-
- - `verification_status: "unverified"` indicates the database record needs
- updating. [Use the Rake task](#re-verify-commits).
-
- - `[]` indicates the database doesn't have a record yet. Locate the commit
- in GitLab to check the signature and store the result.
-
-#### Cryptographic verification checks
-
-If GitLab determines that `verified_signature` is `false`, investigate the reason
-in the Rails console. These checks require `signature` to exist. Refer to the `signature`
-step of the previous [main verification checks](#main-verification-checks).
-
-1. Check the signature, without checking the issuer, returns `true`:
-
- ```ruby
- signature.__send__ :valid_signature?
- ```
-
-1. Check the signing time and date. This check must return `true`:
-
- ```ruby
- signature.__send__ :valid_signing_time?
- ```
-
- - The code allows for code signing certificates to expire.
- - A commit must be signed during the validity period of the certificate,
- and at or after the commit's datestamp. Display the commit time and
- certificate details including `not_before`, `not_after` with:
-
- ```ruby
- commit.created_at
- pp signature.__send__ :cert; nil
- ```
-
-1. Check the signature, including that TLS trust can be established. This check must return `true`:
-
- ```ruby
- signature.__send__(:p7).verify([], signature.__send__(:cert_store), signature.__send__(:signed_text))
- ```
-
- 1. If this fails, add the missing certificates required to establish trust
- [to the GitLab certificate store](https://docs.gitlab.com/omnibus/settings/ssl/index.html#install-custom-public-certificates).
-
- 1. After adding more certificates, (if these troubleshooting steps then pass)
- run the Rake task to [re-verify commits](#re-verify-commits).
-
- 1. Display the certificates, including in the signature:
-
- ```ruby
- pp signature.__send__(:p7).certificates ; nil
- ```
-
-Ensure any additional intermediate certificates and the root certificate are added
-to the certificate store. For consistency with how certificate chains are built on
-web servers:
-
-- Git clients that are signing commits should include the certificate
- and all intermediate certificates in the signature.
-- The GitLab certificate store should only contain the root.
-
-If you remove a root certificate from the GitLab
-trust store, such as when it expires, commit signatures which chain back to that
-root display as `unverified`.
+<!-- This redirect file can be deleted after <2023-12-01>. -->
+<!-- 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/ssh.md b/doc/user/ssh.md
index a322c3ce3db..0e10fea18ad 100644
--- a/doc/user/ssh.md
+++ b/doc/user/ssh.md
@@ -22,7 +22,7 @@ SSH uses two keys, a public key and a private key.
It is not possible to reveal confidential data by uploading your public key. When you need to copy or upload your SSH public key, make sure you do not accidentally copy or upload your private key instead.
-You can use your private key to [sign commits](project/repository/ssh_signed_commits/index.md),
+You can use your private key to [sign commits](project/repository/signed_commits/ssh.md),
which makes your use of GitLab and your data even more secure.
This signature then can be verified by anyone using your public key.
diff --git a/lib/api/helpers/integrations_helpers.rb b/lib/api/helpers/integrations_helpers.rb
index 53117af8648..c1290c1e293 100644
--- a/lib/api/helpers/integrations_helpers.rb
+++ b/lib/api/helpers/integrations_helpers.rb
@@ -988,6 +988,7 @@ module API
type: String,
desc: 'Unique identifier for the target chat or username of the target channel (in the format @channelusername)'
},
+ chat_notification_flags,
chat_notification_events
].flatten,
'unify-circuit' => [
diff --git a/lib/generators/gitlab/analytics/internal_events_generator.rb b/lib/generators/gitlab/analytics/internal_events_generator.rb
index 8bbfebf6842..083d5c31c9b 100644
--- a/lib/generators/gitlab/analytics/internal_events_generator.rb
+++ b/lib/generators/gitlab/analytics/internal_events_generator.rb
@@ -108,12 +108,6 @@ module Gitlab
private
- def known_event_entry
- <<~YML
- - name: #{event}
- YML
- end
-
def event_identifiers
return unless include_default_event_properties?
diff --git a/lib/gitlab/bitbucket_server_import/importer.rb b/lib/gitlab/bitbucket_server_import/importer.rb
deleted file mode 100644
index 1871dd3a89d..00000000000
--- a/lib/gitlab/bitbucket_server_import/importer.rb
+++ /dev/null
@@ -1,468 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module BitbucketServerImport
- class Importer
- include Loggable
-
- attr_reader :recover_missing_commits
- attr_reader :project, :project_key, :repository_slug, :client, :errors, :users, :already_imported_cache_key
-
- BATCH_SIZE = 100
- # The base cache key to use for tracking already imported objects.
- ALREADY_IMPORTED_CACHE_KEY =
- 'bitbucket_server-importer/already-imported/%{project}/%{collection}'
-
- TempBranch = Struct.new(:name, :sha)
-
- def self.imports_repository?
- true
- end
-
- def self.refmap
- # We omit :heads and :tags since these are fetched in the import_repository
- ['+refs/pull-requests/*/to:refs/merge-requests/*/head']
- end
-
- # Unlike GitHub, you can't grab the commit SHAs for pull requests that
- # have been closed but not merged even though Bitbucket has these
- # commits internally. We can recover these pull requests by creating a
- # branch with the Bitbucket REST API, but by default we turn this
- # behavior off.
- def initialize(project, recover_missing_commits: false)
- @project = project
- @recover_missing_commits = recover_missing_commits
- @project_key = project.import_data.data['project_key']
- @repository_slug = project.import_data.data['repo_slug']
- @client = BitbucketServer::Client.new(project.import_data.credentials)
- @formatter = Gitlab::ImportFormatter.new
- @errors = []
- @users = {}
- @temp_branches = []
- @already_imported_cache_key = ALREADY_IMPORTED_CACHE_KEY %
- { project: project.id, collection: collection_method }
- end
-
- def collection_method
- :pull_requests
- end
-
- def execute
- import_repository
- import_pull_requests
- download_lfs_objects
- delete_temp_branches
- handle_errors
- metrics.track_finished_import
-
- log_info(import_stage: "complete")
-
- Gitlab::Cache::Import::Caching.expire(already_imported_cache_key, Gitlab::Cache::Import::Caching::SHORTER_TIMEOUT)
- true
- end
-
- private
-
- def handle_errors
- return unless errors.any?
-
- project.import_state.update_column(:last_error, {
- message: 'The remote data could not be fully imported.',
- errors: errors
- }.to_json)
- end
-
- def find_user_id(by:, value:)
- return unless value
-
- return users[value] if users.key?(value)
-
- user = if by == :email
- User.find_by_any_email(value, confirmed: true)
- else
- User.find_by_username(value)
- end
-
- users[value] = user&.id
-
- user&.id
- end
-
- def repo
- @repo ||= client.repo(project_key, repository_slug)
- end
-
- def sha_exists?(sha)
- project.repository.commit(sha)
- end
-
- def temp_branch_name(pull_request, suffix)
- "gitlab/import/pull-request/#{pull_request.iid}/#{suffix}"
- end
-
- # This method restores required SHAs that GitLab needs to create diffs
- # into branch names as the following:
- #
- # gitlab/import/pull-request/N/{to,from}
- def restore_branches(pull_requests)
- shas_to_restore = []
-
- pull_requests.each do |pull_request|
- shas_to_restore << TempBranch.new(temp_branch_name(pull_request, :from),
- pull_request.source_branch_sha)
- shas_to_restore << TempBranch.new(temp_branch_name(pull_request, :to),
- pull_request.target_branch_sha)
- end
-
- # Create the branches on the Bitbucket Server first
- created_branches = restore_branch_shas(shas_to_restore)
-
- @temp_branches += created_branches
- # Now sync the repository so we get the new branches
- import_repository unless created_branches.empty?
- end
-
- def restore_branch_shas(shas_to_restore)
- shas_to_restore.each_with_object([]) do |temp_branch, branches_created|
- branch_name = temp_branch.name
- sha = temp_branch.sha
-
- next if sha_exists?(sha)
-
- begin
- client.create_branch(project_key, repository_slug, branch_name, sha)
- branches_created << temp_branch
- rescue BitbucketServer::Connection::ConnectionError => e
- log_warn(message: "Unable to recreate branch", sha: sha, error: e.message)
- end
- end
- end
-
- def import_repository
- log_info(import_stage: 'import_repository', message: 'starting import')
-
- project.repository.import_repository(project.import_url)
- project.repository.fetch_as_mirror(project.import_url, refmap: self.class.refmap)
-
- log_info(import_stage: 'import_repository', message: 'finished import')
- rescue ::Gitlab::Git::CommandError => e
- Gitlab::ErrorTracking.log_exception(
- e,
- import_stage: 'import_repository', message: 'failed import', error: e.message
- )
-
- # Expire cache to prevent scenarios such as:
- # 1. First import failed, but the repo was imported successfully, so +exists?+ returns true
- # 2. Retried import, repo is broken or not imported but +exists?+ still returns true
- project.repository.expire_content_cache if project.repository_exists?
-
- raise
- end
-
- def download_lfs_objects
- result = Projects::LfsPointers::LfsImportService.new(project).execute
-
- if result[:status] == :error
- errors << { type: :lfs_objects, errors: "The Lfs import process failed. #{result[:message]}" }
- end
- end
-
- # Bitbucket Server keeps tracks of references for open pull requests in
- # refs/heads/pull-requests, but closed and merged requests get moved
- # into hidden internal refs under stash-refs/pull-requests. Unless the
- # SHAs involved are at the tip of a branch or tag, there is no way to
- # retrieve the server for those commits.
- #
- # To avoid losing history, we use the Bitbucket API to re-create the branch
- # on the remote server. Then we have to issue a `git fetch` to download these
- # branches.
- def import_pull_requests
- page = 0
-
- log_info(import_stage: 'import_pull_requests', message: "starting")
-
- loop do
- log_debug(import_stage: 'import_pull_requests', message: "importing page #{page} and batch-size #{BATCH_SIZE} from #{page * BATCH_SIZE} to #{(page + 1) * BATCH_SIZE}")
-
- pull_requests = client.pull_requests(project_key, repository_slug, page_offset: page, limit: BATCH_SIZE).to_a
-
- break if pull_requests.empty?
-
- # Creating branches on the server and fetching the newly-created branches
- # may take a number of network round-trips. This used to be done in batches to
- # avoid doing a git fetch for every new branch, as the whole process is now
- # batched, we do not need to separately do this in batches.
- restore_branches(pull_requests) if recover_missing_commits
-
- pull_requests.each do |pull_request|
- if already_imported?(pull_request)
- log_info(import_stage: 'import_pull_requests', message: 'already imported', iid: pull_request.iid)
- else
- import_bitbucket_pull_request(pull_request)
- end
- rescue StandardError => e
- Gitlab::ErrorTracking.log_exception(
- e,
- import_stage: 'import_pull_requests', iid: pull_request.iid, error: e.message
- )
-
- backtrace = Gitlab::BacktraceCleaner.clean_backtrace(e.backtrace)
- errors << { type: :pull_request, iid: pull_request.iid, errors: e.message, backtrace: backtrace.join("\n"), raw_response: pull_request.raw }
- end
-
- log_debug(import_stage: 'import_pull_requests', message: "finished page #{page} and batch-size #{BATCH_SIZE}")
- page += 1
- end
- end
-
- # Returns true if the given object has already been imported, false
- # otherwise.
- #
- # object - The object to check.
- def already_imported?(pull_request)
- Gitlab::Cache::Import::Caching.set_includes?(already_imported_cache_key, pull_request.iid)
- end
-
- # Marks the given object as "already imported".
- def mark_as_imported(pull_request)
- Gitlab::Cache::Import::Caching.set_add(already_imported_cache_key, pull_request.iid)
- end
-
- def delete_temp_branches
- @temp_branches.each do |branch|
- client.delete_branch(project_key, repository_slug, branch.name, branch.sha)
- project.repository.delete_branch(branch.name)
- rescue BitbucketServer::Connection::ConnectionError => e
- Gitlab::ErrorTracking.log_exception(
- e,
- import_stage: 'delete_temp_branches', branch: branch.name, error: e.message
- )
-
- @errors << { type: :delete_temp_branches, branch_name: branch.name, errors: e.message }
- end
- end
-
- def import_bitbucket_pull_request(pull_request)
- log_info(import_stage: 'import_bitbucket_pull_requests', message: 'starting', iid: pull_request.iid)
-
- description = ''
- description += author_line(pull_request)
- description += pull_request.description if pull_request.description
-
- attributes = {
- iid: pull_request.iid,
- title: pull_request.title,
- description: description,
- reviewer_ids: reviewers(pull_request.reviewers),
- source_project_id: project.id,
- source_branch: Gitlab::Git.ref_name(pull_request.source_branch_name),
- source_branch_sha: pull_request.source_branch_sha,
- target_project_id: project.id,
- target_branch: Gitlab::Git.ref_name(pull_request.target_branch_name),
- target_branch_sha: pull_request.target_branch_sha,
- state_id: MergeRequest.available_states[pull_request.state],
- author_id: author_id(pull_request),
- created_at: pull_request.created_at,
- updated_at: pull_request.updated_at
- }
-
- creator = Gitlab::Import::MergeRequestCreator.new(project)
- merge_request = creator.execute(attributes)
-
- if merge_request.persisted?
- import_pull_request_comments(pull_request, merge_request)
-
- metrics.merge_requests_counter.increment
- end
-
- log_info(import_stage: 'import_bitbucket_pull_requests', message: 'finished', iid: pull_request.iid)
- mark_as_imported(pull_request)
- end
-
- def import_pull_request_comments(pull_request, merge_request)
- log_info(import_stage: 'import_pull_request_comments', message: 'starting', iid: merge_request.iid)
-
- comments, other_activities = client.activities(project_key, repository_slug, pull_request.iid).partition(&:comment?)
-
- merge_event = other_activities.find(&:merge_event?)
- import_merge_event(merge_request, merge_event) if merge_event
-
- inline_comments, pr_comments = comments.partition(&:inline_comment?)
-
- import_inline_comments(inline_comments.map(&:comment), merge_request)
- import_standalone_pr_comments(pr_comments.map(&:comment), merge_request)
-
- log_info(import_stage: 'import_pull_request_comments', message: 'finished', iid: merge_request.iid,
- merge_event_found: merge_event.present?,
- inline_comments_count: inline_comments.count,
- standalone_pr_comments: pr_comments.count)
- end
-
- # rubocop: disable CodeReuse/ActiveRecord
- def import_merge_event(merge_request, merge_event)
- log_info(import_stage: 'import_merge_event', message: 'starting', iid: merge_request.iid)
-
- committer = merge_event.committer_email
-
- user_id = find_user_id(by: :email, value: committer) || project.creator_id
- timestamp = merge_event.merge_timestamp
- merge_request.update({ merge_commit_sha: merge_event.merge_commit })
- metric = MergeRequest::Metrics.find_or_initialize_by(merge_request: merge_request)
- metric.update(merged_by_id: user_id, merged_at: timestamp)
-
- log_info(import_stage: 'import_merge_event', message: 'finished', iid: merge_request.iid)
- end
- # rubocop: enable CodeReuse/ActiveRecord
-
- def import_inline_comments(inline_comments, merge_request)
- log_info(import_stage: 'import_inline_comments', message: 'starting', iid: merge_request.iid)
-
- inline_comments.each do |comment|
- position = build_position(merge_request, comment)
- parent = create_diff_note(merge_request, comment, position)
-
- next unless parent&.persisted?
-
- discussion_id = parent.discussion_id
-
- comment.comments.each do |reply|
- create_diff_note(merge_request, reply, position, discussion_id)
- end
- end
-
- log_info(import_stage: 'import_inline_comments', message: 'finished', iid: merge_request.iid)
- end
-
- def create_diff_note(merge_request, comment, position, discussion_id = nil)
- attributes = pull_request_comment_attributes(comment)
- attributes.merge!(position: position, type: 'DiffNote')
- attributes[:discussion_id] = discussion_id if discussion_id
-
- note = merge_request.notes.build(attributes)
-
- if note.valid?
- note.save
- return note
- end
-
- log_info(import_stage: 'create_diff_note', message: 'creating fallback DiffNote', iid: merge_request.iid)
-
- # Bitbucket Server supports the ability to comment on any line, not just the
- # line in the diff. If we can't add the note as a DiffNote, fallback to creating
- # a regular note.
- create_fallback_diff_note(merge_request, comment, position)
- rescue StandardError => e
- Gitlab::ErrorTracking.log_exception(
- e,
- import_stage: 'create_diff_note', comment_id: comment.id, error: e.message
- )
-
- errors << { type: :pull_request, id: comment.id, errors: e.message }
- nil
- end
-
- def create_fallback_diff_note(merge_request, comment, position)
- attributes = pull_request_comment_attributes(comment)
- note = "*Comment on"
-
- note += " #{position.old_path}:#{position.old_line} -->" if position.old_line
- note += " #{position.new_path}:#{position.new_line}" if position.new_line
- note += "*\n\n#{comment.note}"
-
- attributes[:note] = note
- merge_request.notes.create!(attributes)
- end
-
- def build_position(merge_request, pr_comment)
- params = {
- diff_refs: merge_request.diff_refs,
- old_path: pr_comment.file_path,
- new_path: pr_comment.file_path,
- old_line: pr_comment.old_pos,
- new_line: pr_comment.new_pos
- }
-
- Gitlab::Diff::Position.new(params)
- end
-
- def import_standalone_pr_comments(pr_comments, merge_request)
- pr_comments.each do |comment|
- merge_request.notes.create!(pull_request_comment_attributes(comment))
-
- comment.comments.each do |replies|
- merge_request.notes.create!(pull_request_comment_attributes(replies))
- end
- rescue StandardError => e
- Gitlab::ErrorTracking.log_exception(
- e,
- import_stage: 'import_standalone_pr_comments', merge_request_id: merge_request.id, comment_id: comment.id, error: e.message
- )
-
- errors << { type: :pull_request, comment_id: comment.id, errors: e.message }
- end
- end
-
- def pull_request_comment_attributes(comment)
- author = uid(comment)
- note = ''
-
- unless author
- author = project.creator_id
- note = "*By #{comment.author_username} (#{comment.author_email})*\n\n"
- end
-
- note +=
- # Provide some context for replying
- if comment.parent_comment
- "> #{comment.parent_comment.note.truncate(80)}\n\n#{comment.note}"
- else
- comment.note
- end
-
- {
- project: project,
- note: note,
- author_id: author,
- created_at: comment.created_at,
- updated_at: comment.updated_at
- }
- end
-
- def metrics
- @metrics ||= Gitlab::Import::Metrics.new(:bitbucket_server_importer, @project)
- end
-
- def author_line(rep_object)
- return '' if uid(rep_object)
-
- @formatter.author_line(rep_object.author)
- end
-
- def author_id(rep_object)
- uid(rep_object) || project.creator_id
- end
-
- def uid(rep_object)
- # We want this to only match either username or email depending on the flag state.
- # There should be no fall-through.
- if Feature.enabled?(:bitbucket_server_user_mapping_by_username, type: :ops)
- find_user_id(by: :username, value: rep_object.author_username)
- else
- find_user_id(by: :email, value: rep_object.author_email)
- end
- end
-
- def reviewers(reviewers)
- return [] unless reviewers.present?
-
- reviewers.filter_map do |reviewer|
- if Feature.enabled?(:bitbucket_server_user_mapping_by_username, type: :ops)
- find_user_id(by: :username, value: reviewer.dig('user', 'slug'))
- else
- find_user_id(by: :email, value: reviewer.dig('user', 'emailAddress'))
- end
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/import_sources.rb b/lib/gitlab/import_sources.rb
index 5823fafa2aa..fec8b3a7708 100644
--- a/lib/gitlab/import_sources.rb
+++ b/lib/gitlab/import_sources.rb
@@ -12,7 +12,7 @@ module Gitlab
IMPORT_TABLE = [
ImportSource.new('github', 'GitHub', Gitlab::GithubImport::ParallelImporter),
ImportSource.new('bitbucket', 'Bitbucket Cloud', Gitlab::BitbucketImport::Importer),
- ImportSource.new('bitbucket_server', 'Bitbucket Server', Gitlab::BitbucketServerImport::Importer),
+ ImportSource.new('bitbucket_server', 'Bitbucket Server', Gitlab::BitbucketServerImport::ParallelImporter),
ImportSource.new('fogbugz', 'FogBugz', Gitlab::FogbugzImport::Importer),
ImportSource.new('git', 'Repository by URL', nil),
ImportSource.new('gitlab_project', 'GitLab export', Gitlab::ImportExport::Importer),
@@ -45,14 +45,12 @@ module Gitlab
def import_table
bitbucket_parallel_enabled = Feature.enabled?(:bitbucket_parallel_importer)
- bitbucket_server_parallel_enabled = Feature.enabled?(:bitbucket_server_parallel_importer)
- return IMPORT_TABLE unless bitbucket_parallel_enabled || bitbucket_server_parallel_enabled
+ return IMPORT_TABLE unless bitbucket_parallel_enabled
import_table = IMPORT_TABLE.deep_dup
import_table[1].importer = Gitlab::BitbucketImport::ParallelImporter if bitbucket_parallel_enabled
- import_table[2].importer = Gitlab::BitbucketServerImport::ParallelImporter if bitbucket_server_parallel_enabled
import_table
end
diff --git a/lib/sidebars/projects/menus/issues_menu.rb b/lib/sidebars/projects/menus/issues_menu.rb
index dc40b84529f..e599b764ed9 100644
--- a/lib/sidebars/projects/menus/issues_menu.rb
+++ b/lib/sidebars/projects/menus/issues_menu.rb
@@ -44,7 +44,7 @@ module Sidebars
override :active_routes
def active_routes
- { controller: 'projects/issues' }
+ { path: %w[projects/issues#index projects/issues#show projects/issues#new] }
end
override :has_pill?
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 5c5bd0f917e..45e817d9a0f 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -25938,10 +25938,13 @@ msgstr ""
msgid "Issues, merge requests, pushes, and comments."
msgstr ""
-msgid "IssuesAnalytics|After you begin creating issues for your projects, we can start tracking and displaying metrics for them."
+msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Avg/Month:"
+msgid "IssuesAnalytics|Create issues for projects in your group to track and see metrics for them."
+msgstr ""
+
+msgid "IssuesAnalytics|Get started with issue analytics"
msgstr ""
msgid "IssuesAnalytics|Issues created"
@@ -25956,9 +25959,6 @@ msgstr ""
msgid "IssuesAnalytics|Sorry, your filter produced no results"
msgstr ""
-msgid "IssuesAnalytics|There are no issues for the projects in your group"
-msgstr ""
-
msgid "IssuesAnalytics|To widen your search, change or remove filters in the filter bar above."
msgstr ""
@@ -42775,7 +42775,7 @@ msgstr ""
msgid "SecurityReports|Submit vulnerability"
msgstr ""
-msgid "SecurityReports|The Vulnerability Report shows results of successful scans on your project's default branch, manually added vulnerability records, and vulnerabilities found from scanning operational environments. %{linkStart}Learn more.%{linkEnd}"
+msgid "SecurityReports|The Vulnerability Report shows results of successful scans on your project's default branch, manually added vulnerability records, and vulnerabilities found from scanning operational environments. %{linkStart}Learn more%{linkEnd}."
msgstr ""
msgid "SecurityReports|The following security reports contain one or more vulnerability findings that could not be parsed and were not recorded. To investigate a report, download the artifacts in the job output. Ensure the security report conforms to the relevant %{helpPageLinkStart}JSON schema%{helpPageLinkEnd}."
@@ -48434,7 +48434,7 @@ msgstr ""
msgid "This variable value does not meet the masking requirements."
msgstr ""
-msgid "This vulnerability was automatically resolved because its vulnerability type was disabled in this project or removed from GitLab's default ruleset."
+msgid "This vulnerability was automatically resolved because its vulnerability type was disabled in this project or removed from GitLab's default ruleset. For details about SAST rule changes, see https://docs.gitlab.com/ee/user/application_security/sast/rules#important-rule-changes."
msgstr ""
msgid "This will invalidate your registered applications and WebAuthn devices."
diff --git a/qa/qa/service/docker_run/smocker.rb b/qa/qa/service/docker_run/smocker.rb
index 9f832bfe359..1f205440f4b 100644
--- a/qa/qa/service/docker_run/smocker.rb
+++ b/qa/qa/service/docker_run/smocker.rb
@@ -38,10 +38,6 @@ module QA
@api = nil
end
- def self.logs
- @container&.logs
- end
-
attr_reader :public_port, :admin_port
def host_name
diff --git a/qa/qa/specs/features/shared_examples/audit_event_streaming_shared_examples.rb b/qa/qa/specs/features/shared_examples/audit_event_streaming_shared_examples.rb
new file mode 100644
index 00000000000..67a4fd12b96
--- /dev/null
+++ b/qa/qa/specs/features/shared_examples/audit_event_streaming_shared_examples.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+module QA
+ RSpec.shared_examples 'streamed events' do |event_type, entity_type, testcase|
+ it 'the external server receives the event', testcase: testcase do
+ entity_path # Call to trigger the event before we can check it was received
+ event_record = @mock_service.wait_for_event(event_type, entity_type, entity_path)
+ verify_response = @mock_service.verify
+
+ # Most of the verification is done via `wait_for_event` above
+ # The other two are checks for data that couldn't be added to a mock in advance
+ aggregate_failures do
+ # Smocker treats header values as arrays
+ # Verification tokens are created for us if we don't provide one
+ # https://docs.gitlab.com/ee/administration/audit_event_streaming/#verify-event-authenticity
+ expect(event_record[:headers]).to include(
+ headers.transform_values { |v| [v] }
+ .merge("X-Gitlab-Event-Streaming-Token": [@stream_destination.verification_token])
+ )
+ expect(event_record[:body]).to include(details: a_hash_including(target_details: target_details))
+ expect(verify_response).to be_success,
+ "Failures when verifying events received:\n#{JSON.pretty_generate(verify_response.failures)}"
+ end
+ end
+ end
+end
diff --git a/qa/qa/support/audit_event_streaming_service.rb b/qa/qa/support/audit_event_streaming_service.rb
index b1e1fc578f9..03f27f7f3bb 100644
--- a/qa/qa/support/audit_event_streaming_service.rb
+++ b/qa/qa/support/audit_event_streaming_service.rb
@@ -80,7 +80,7 @@ module QA
end
rescue Repeater::WaitExceededError
# If there is a failure this will output the logs from the smocker container (at the debug log level)
- Service::DockerRun::Smocker.logs
+ logs
raise
end
@@ -91,22 +91,7 @@ module QA
#
# @return [String]
def mocks
- <<~YAML
- - request:
- path: /logs
- method: POST
- body:
- event_type:
- matcher: ShouldMatch
- value: .*
- headers:
- Content-Type: application/x-www-form-urlencoded
- X-Gitlab-Audit-Event-Type:
- matcher: ShouldMatch
- value: .*
- response:
- status: 200
- YAML
+ @mocks ||= File.read(EE::Runtime::Path.fixture('audit_event_streaming', 'mocks.yml'))
end
end
end
diff --git a/spec/controllers/projects/pipelines_controller_spec.rb b/spec/controllers/projects/pipelines_controller_spec.rb
index a5542a2b825..43e7bafc206 100644
--- a/spec/controllers/projects/pipelines_controller_spec.rb
+++ b/spec/controllers/projects/pipelines_controller_spec.rb
@@ -769,6 +769,33 @@ RSpec.describe Projects::PipelinesController, feature_category: :continuous_inte
[
{
+ chart_param: 'time-to-restore-service',
+ event: 'p_analytics_ci_cd_time_to_restore_service'
+ },
+ {
+ chart_param: 'change-failure-rate',
+ event: 'p_analytics_ci_cd_change_failure_rate'
+ }
+ ].each do |tab|
+ it_behaves_like 'tracking unique visits', :charts do
+ let(:request_params) { { namespace_id: project.namespace, project_id: project, id: pipeline.id, chart: tab[:chart_param] } }
+ let(:target_id) { ['p_analytics_pipelines', tab[:event]] }
+ end
+
+ it_behaves_like 'Snowplow event tracking with RedisHLL context' do
+ subject { get :charts, params: request_params, format: :html }
+
+ let(:request_params) { { namespace_id: project.namespace, project_id: project, id: pipeline.id, chart: tab[:chart_param] } }
+ let(:category) { described_class.name }
+ let(:action) { 'perform_analytics_usage_action' }
+ let(:namespace) { project.namespace }
+ let(:label) { 'redis_hll_counters.analytics.analytics_total_unique_counts_monthly' }
+ let(:property) { 'p_analytics_pipelines' }
+ end
+ end
+
+ [
+ {
chart_param: '',
event: 'p_analytics_ci_cd_pipelines'
},
@@ -783,14 +810,6 @@ RSpec.describe Projects::PipelinesController, feature_category: :continuous_inte
{
chart_param: 'lead-time',
event: 'p_analytics_ci_cd_lead_time'
- },
- {
- chart_param: 'time-to-restore-service',
- event: 'p_analytics_ci_cd_time_to_restore_service'
- },
- {
- chart_param: 'change-failure-rate',
- event: 'p_analytics_ci_cd_change_failure_rate'
}
].each do |tab|
it_behaves_like 'tracking unique visits', :charts do
@@ -798,15 +817,12 @@ RSpec.describe Projects::PipelinesController, feature_category: :continuous_inte
let(:target_id) { ['p_analytics_pipelines', tab[:event]] }
end
- it_behaves_like 'Snowplow event tracking with RedisHLL context' do
+ it_behaves_like 'internal event tracking' do
subject { get :charts, params: request_params, format: :html }
let(:request_params) { { namespace_id: project.namespace, project_id: project, id: pipeline.id, chart: tab[:chart_param] } }
- let(:category) { described_class.name }
- let(:action) { 'perform_analytics_usage_action' }
+ let(:action) { tab[:event] }
let(:namespace) { project.namespace }
- let(:label) { 'redis_hll_counters.analytics.analytics_total_unique_counts_monthly' }
- let(:property) { 'p_analytics_pipelines' }
end
end
end
diff --git a/spec/frontend/pipelines/graph_shared/links_layer_spec.js b/spec/frontend/ci/common/private/job_links_layer_spec.js
index ccda2b8078d..c2defc8d770 100644
--- a/spec/frontend/pipelines/graph_shared/links_layer_spec.js
+++ b/spec/frontend/ci/common/private/job_links_layer_spec.js
@@ -3,7 +3,7 @@ import mockPipelineResponse from 'test_fixtures/pipelines/pipeline_details.json'
import LinksInner from '~/ci/pipeline_details/graph/components/links_inner.vue';
import LinksLayer from '~/ci/common/private/job_links_layer.vue';
-import { generateResponse } from '../graph/mock_data';
+import { generateResponse } from 'jest/ci/pipeline_details/graph/mock_data';
describe('links layer component', () => {
let wrapper;
diff --git a/spec/frontend/pipelines/components/dag/__snapshots__/dag_graph_spec.js.snap b/spec/frontend/ci/pipeline_details/dag/components/__snapshots__/dag_graph_spec.js.snap
index 624c89a237c..624c89a237c 100644
--- a/spec/frontend/pipelines/components/dag/__snapshots__/dag_graph_spec.js.snap
+++ b/spec/frontend/ci/pipeline_details/dag/components/__snapshots__/dag_graph_spec.js.snap
diff --git a/spec/frontend/pipelines/components/dag/dag_annotations_spec.js b/spec/frontend/ci/pipeline_details/dag/components/dag_annotations_spec.js
index be9d7a8b714..d1c338e50c6 100644
--- a/spec/frontend/pipelines/components/dag/dag_annotations_spec.js
+++ b/spec/frontend/ci/pipeline_details/dag/components/dag_annotations_spec.js
@@ -2,7 +2,7 @@ import { GlButton } from '@gitlab/ui';
import { shallowMount, mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import DagAnnotations from '~/ci/pipeline_details/dag/components/dag_annotations.vue';
-import { singleNote, multiNote } from './mock_data';
+import { singleNote, multiNote } from '../mock_data';
describe('The DAG annotations', () => {
let wrapper;
diff --git a/spec/frontend/pipelines/components/dag/dag_graph_spec.js b/spec/frontend/ci/pipeline_details/dag/components/dag_graph_spec.js
index 23f62ab9d93..aff83c00e79 100644
--- a/spec/frontend/pipelines/components/dag/dag_graph_spec.js
+++ b/spec/frontend/ci/pipeline_details/dag/components/dag_graph_spec.js
@@ -1,10 +1,10 @@
import { shallowMount } from '@vue/test-utils';
import { IS_HIGHLIGHTED, LINK_SELECTOR, NODE_SELECTOR } from '~/ci/pipeline_details/dag/constants';
import DagGraph from '~/ci/pipeline_details/dag/components/dag_graph.vue';
-import { createSankey } from '~/ci/pipeline_details/dag/drawing_utils';
-import { highlightIn, highlightOut } from '~/ci/pipeline_details/dag/interactions';
+import { createSankey } from '~/ci/pipeline_details/dag/utils/drawing_utils';
+import { highlightIn, highlightOut } from '~/ci/pipeline_details/dag/utils/interactions';
import { removeOrphanNodes } from '~/ci/pipeline_details/utils/parsing_utils';
-import { parsedData } from './mock_data';
+import { parsedData } from '../mock_data';
describe('The DAG graph', () => {
let wrapper;
diff --git a/spec/frontend/pipelines/components/dag/dag_spec.js b/spec/frontend/ci/pipeline_details/dag/dag_spec.js
index de9490be607..de9490be607 100644
--- a/spec/frontend/pipelines/components/dag/dag_spec.js
+++ b/spec/frontend/ci/pipeline_details/dag/dag_spec.js
diff --git a/spec/frontend/pipelines/components/dag/mock_data.js b/spec/frontend/ci/pipeline_details/dag/mock_data.js
index f27e7cf3d6b..f27e7cf3d6b 100644
--- a/spec/frontend/pipelines/components/dag/mock_data.js
+++ b/spec/frontend/ci/pipeline_details/dag/mock_data.js
diff --git a/spec/frontend/pipelines/components/dag/drawing_utils_spec.js b/spec/frontend/ci/pipeline_details/dag/utils/drawing_utils_spec.js
index 6f3fd05ae4b..aea8e894bd4 100644
--- a/spec/frontend/pipelines/components/dag/drawing_utils_spec.js
+++ b/spec/frontend/ci/pipeline_details/dag/utils/drawing_utils_spec.js
@@ -1,6 +1,6 @@
-import { createSankey } from '~/ci/pipeline_details/dag/drawing_utils';
+import { createSankey } from '~/ci/pipeline_details/dag/utils/drawing_utils';
import { parseData } from '~/ci/pipeline_details/utils/parsing_utils';
-import { mockParsedGraphQLNodes } from './mock_data';
+import { mockParsedGraphQLNodes } from '../mock_data';
describe('DAG visualization drawing utilities', () => {
const parsed = parseData(mockParsedGraphQLNodes);
diff --git a/spec/frontend/pipelines/graph_shared/__snapshots__/links_inner_spec.js.snap b/spec/frontend/ci/pipeline_details/graph/components/__snapshots__/links_inner_spec.js.snap
index b31c0e59a33..b31c0e59a33 100644
--- a/spec/frontend/pipelines/graph_shared/__snapshots__/links_inner_spec.js.snap
+++ b/spec/frontend/ci/pipeline_details/graph/components/__snapshots__/links_inner_spec.js.snap
diff --git a/spec/frontend/pipelines/graph/action_component_spec.js b/spec/frontend/ci/pipeline_details/graph/components/action_component_spec.js
index 9e177156d0e..9e177156d0e 100644
--- a/spec/frontend/pipelines/graph/action_component_spec.js
+++ b/spec/frontend/ci/pipeline_details/graph/components/action_component_spec.js
diff --git a/spec/frontend/pipelines/graph/graph_component_spec.js b/spec/frontend/ci/pipeline_details/graph/components/graph_component_spec.js
index e468adada0f..a98e79c69fe 100644
--- a/spec/frontend/pipelines/graph/graph_component_spec.js
+++ b/spec/frontend/ci/pipeline_details/graph/components/graph_component_spec.js
@@ -9,7 +9,7 @@ import StageColumnComponent from '~/ci/pipeline_details/graph/components/stage_c
import { calculatePipelineLayersInfo } from '~/ci/pipeline_details/graph/utils';
import LinksLayer from '~/ci/common/private/job_links_layer.vue';
-import { generateResponse, pipelineWithUpstreamDownstream } from './mock_data';
+import { generateResponse, pipelineWithUpstreamDownstream } from '../mock_data';
describe('graph component', () => {
let wrapper;
diff --git a/spec/frontend/pipelines/graph/graph_view_selector_spec.js b/spec/frontend/ci/pipeline_details/graph/components/graph_view_selector_spec.js
index bf98995de9c..bf98995de9c 100644
--- a/spec/frontend/pipelines/graph/graph_view_selector_spec.js
+++ b/spec/frontend/ci/pipeline_details/graph/components/graph_view_selector_spec.js
diff --git a/spec/frontend/pipelines/graph/job_group_dropdown_spec.js b/spec/frontend/ci/pipeline_details/graph/components/job_group_dropdown_spec.js
index d5a1cfffe68..d5a1cfffe68 100644
--- a/spec/frontend/pipelines/graph/job_group_dropdown_spec.js
+++ b/spec/frontend/ci/pipeline_details/graph/components/job_group_dropdown_spec.js
diff --git a/spec/frontend/pipelines/graph/job_item_spec.js b/spec/frontend/ci/pipeline_details/graph/components/job_item_spec.js
index fd45dc7193f..107f0df5c02 100644
--- a/spec/frontend/pipelines/graph/job_item_spec.js
+++ b/spec/frontend/ci/pipeline_details/graph/components/job_item_spec.js
@@ -15,7 +15,7 @@ import {
mockFailedJob,
triggerJob,
triggerJobWithRetryAction,
-} from './mock_data';
+} from '../mock_data';
describe('pipeline graph job item', () => {
useLocalStorageSpy();
diff --git a/spec/frontend/pipelines/graph/job_name_component_spec.js b/spec/frontend/ci/pipeline_details/graph/components/job_name_component_spec.js
index ca201aee648..ca201aee648 100644
--- a/spec/frontend/pipelines/graph/job_name_component_spec.js
+++ b/spec/frontend/ci/pipeline_details/graph/components/job_name_component_spec.js
diff --git a/spec/frontend/pipelines/graph/linked_pipeline_spec.js b/spec/frontend/ci/pipeline_details/graph/components/linked_pipeline_spec.js
index 5541b0db54a..5541b0db54a 100644
--- a/spec/frontend/pipelines/graph/linked_pipeline_spec.js
+++ b/spec/frontend/ci/pipeline_details/graph/components/linked_pipeline_spec.js
diff --git a/spec/frontend/pipelines/graph/linked_pipelines_column_spec.js b/spec/frontend/ci/pipeline_details/graph/components/linked_pipelines_column_spec.js
index cc4e4172657..30f05baceab 100644
--- a/spec/frontend/pipelines/graph/linked_pipelines_column_spec.js
+++ b/spec/frontend/ci/pipeline_details/graph/components/linked_pipelines_column_spec.js
@@ -17,7 +17,7 @@ import LinkedPipelinesColumn from '~/ci/pipeline_details/graph/components/linked
import * as parsingUtils from '~/ci/pipeline_details/utils/parsing_utils';
import { LOAD_FAILURE } from '~/ci/pipeline_details/constants';
-import { pipelineWithUpstreamDownstream, wrappedPipelineReturn } from './mock_data';
+import { pipelineWithUpstreamDownstream, wrappedPipelineReturn } from '../mock_data';
const processedPipeline = pipelineWithUpstreamDownstream(mockPipelineResponse);
diff --git a/spec/frontend/pipelines/graph/linked_pipelines_mock_data.js b/spec/frontend/ci/pipeline_details/graph/components/linked_pipelines_mock_data.js
index f7f5738e46d..f7f5738e46d 100644
--- a/spec/frontend/pipelines/graph/linked_pipelines_mock_data.js
+++ b/spec/frontend/ci/pipeline_details/graph/components/linked_pipelines_mock_data.js
diff --git a/spec/frontend/pipelines/graph_shared/links_inner_spec.js b/spec/frontend/ci/pipeline_details/graph/components/links_inner_spec.js
index 8d1964726e4..655b2ac74ac 100644
--- a/spec/frontend/pipelines/graph_shared/links_inner_spec.js
+++ b/spec/frontend/ci/pipeline_details/graph/components/links_inner_spec.js
@@ -11,7 +11,7 @@ import {
pipelineDataWithNoNeeds,
rootRect,
sameStageNeeds,
-} from '../pipeline_graph/mock_data';
+} from 'jest/ci/pipeline_editor/components/graph/mock_data';
describe('Links Inner component', () => {
const containerId = 'pipeline-graph-container';
diff --git a/spec/frontend/pipelines/graph/stage_column_component_spec.js b/spec/frontend/ci/pipeline_details/graph/components/stage_column_component_spec.js
index cc79205ec41..cc79205ec41 100644
--- a/spec/frontend/pipelines/graph/stage_column_component_spec.js
+++ b/spec/frontend/ci/pipeline_details/graph/components/stage_column_component_spec.js
diff --git a/spec/frontend/pipelines/graph/graph_component_wrapper_spec.js b/spec/frontend/ci/pipeline_details/graph/graph_component_wrapper_spec.js
index 372ed2a4e1c..372ed2a4e1c 100644
--- a/spec/frontend/pipelines/graph/graph_component_wrapper_spec.js
+++ b/spec/frontend/ci/pipeline_details/graph/graph_component_wrapper_spec.js
diff --git a/spec/frontend/pipelines/graph/mock_data.js b/spec/frontend/ci/pipeline_details/graph/mock_data.js
index a880a9cf4b0..a880a9cf4b0 100644
--- a/spec/frontend/pipelines/graph/mock_data.js
+++ b/spec/frontend/ci/pipeline_details/graph/mock_data.js
diff --git a/spec/frontend/pipelines/pipeline_details_header_spec.js b/spec/frontend/ci/pipeline_details/header/pipeline_details_header_spec.js
index 81a8914f013..f48340153a1 100644
--- a/spec/frontend/pipelines/pipeline_details_header_spec.js
+++ b/spec/frontend/ci/pipeline_details/header/pipeline_details_header_spec.js
@@ -23,7 +23,7 @@ import {
pipelineRetryMutationResponseFailed,
pipelineCancelMutationResponseFailed,
pipelineDeleteMutationResponseFailed,
-} from './mock_data';
+} from '../mock_data';
Vue.use(VueApollo);
diff --git a/spec/frontend/pipelines/components/jobs/failed_jobs_table_spec.js b/spec/frontend/ci/pipeline_details/jobs/components/failed_jobs_table_spec.js
index cb2d8ad85d5..cb2d8ad85d5 100644
--- a/spec/frontend/pipelines/components/jobs/failed_jobs_table_spec.js
+++ b/spec/frontend/ci/pipeline_details/jobs/components/failed_jobs_table_spec.js
diff --git a/spec/frontend/pipelines/components/jobs/failed_jobs_app_spec.js b/spec/frontend/ci/pipeline_details/jobs/failed_jobs_app_spec.js
index b2d443c18ca..17b43aa422b 100644
--- a/spec/frontend/pipelines/components/jobs/failed_jobs_app_spec.js
+++ b/spec/frontend/ci/pipeline_details/jobs/failed_jobs_app_spec.js
@@ -8,7 +8,7 @@ import { createAlert } from '~/alert';
import FailedJobsApp from '~/ci/pipeline_details/jobs/failed_jobs_app.vue';
import FailedJobsTable from '~/ci/pipeline_details/jobs/components/failed_jobs_table.vue';
import GetFailedJobsQuery from '~/ci/pipeline_details/jobs/graphql/queries/get_failed_jobs.query.graphql';
-import { mockFailedJobsQueryResponse } from '../../mock_data';
+import { mockFailedJobsQueryResponse } from 'jest/ci/pipeline_details/mock_data';
Vue.use(VueApollo);
diff --git a/spec/frontend/pipelines/components/jobs/jobs_app_spec.js b/spec/frontend/ci/pipeline_details/jobs/jobs_app_spec.js
index bdbbec15e1e..f27aa02c1cc 100644
--- a/spec/frontend/pipelines/components/jobs/jobs_app_spec.js
+++ b/spec/frontend/ci/pipeline_details/jobs/jobs_app_spec.js
@@ -8,7 +8,7 @@ import { createAlert } from '~/alert';
import JobsApp from '~/ci/pipeline_details/jobs/jobs_app.vue';
import JobsTable from '~/jobs/components/table/jobs_table.vue';
import getPipelineJobsQuery from '~/ci/pipeline_details/jobs/graphql/queries/get_pipeline_jobs.query.graphql';
-import { mockPipelineJobsQueryResponse } from '../../mock_data';
+import { mockPipelineJobsQueryResponse } from '../mock_data';
Vue.use(VueApollo);
diff --git a/spec/frontend/pipelines/linked_pipelines_mock.json b/spec/frontend/ci/pipeline_details/linked_pipelines_mock.json
index a68283032d2..a68283032d2 100644
--- a/spec/frontend/pipelines/linked_pipelines_mock.json
+++ b/spec/frontend/ci/pipeline_details/linked_pipelines_mock.json
diff --git a/spec/frontend/pipelines/mock_data.js b/spec/frontend/ci/pipeline_details/mock_data.js
index 673db3b5178..e32d0a0df47 100644
--- a/spec/frontend/pipelines/mock_data.js
+++ b/spec/frontend/ci/pipeline_details/mock_data.js
@@ -197,108 +197,6 @@ export const mockRunningPipelineHeaderData = {
},
};
-export const stageReply = {
- name: 'deploy',
- title: 'deploy: running',
- latest_statuses: [
- {
- id: 928,
- name: 'stop staging',
- started: false,
- build_path: '/twitter/flight/-/jobs/928',
- cancel_path: '/twitter/flight/-/jobs/928/cancel',
- playable: false,
- created_at: '2018-04-04T20:02:02.728Z',
- updated_at: '2018-04-04T20:02:02.766Z',
- status: {
- icon: 'status_pending',
- text: 'pending',
- label: 'pending',
- group: 'pending',
- tooltip: 'pending',
- has_details: true,
- details_path: '/twitter/flight/-/jobs/928',
- favicon:
- '/assets/ci_favicons/dev/favicon_status_pending-db32e1faf94b9f89530ac519790920d1f18ea8f6af6cd2e0a26cd6840cacf101.ico',
- action: {
- icon: 'cancel',
- title: 'Cancel',
- path: '/twitter/flight/-/jobs/928/cancel',
- method: 'post',
- },
- },
- },
- {
- id: 926,
- name: 'production',
- started: false,
- build_path: '/twitter/flight/-/jobs/926',
- retry_path: '/twitter/flight/-/jobs/926/retry',
- play_path: '/twitter/flight/-/jobs/926/play',
- playable: true,
- created_at: '2018-04-04T20:00:57.202Z',
- updated_at: '2018-04-04T20:11:13.110Z',
- status: {
- icon: 'status_canceled',
- text: 'canceled',
- label: 'manual play action',
- group: 'canceled',
- tooltip: 'canceled',
- has_details: true,
- details_path: '/twitter/flight/-/jobs/926',
- favicon:
- '/assets/ci_favicons/dev/favicon_status_canceled-5491840b9b6feafba0bc599cbd49ee9580321dc809683856cf1b0d51532b1af6.ico',
- action: {
- icon: 'play',
- title: 'Play',
- path: '/twitter/flight/-/jobs/926/play',
- method: 'post',
- },
- },
- },
- {
- id: 217,
- name: 'staging',
- started: '2018-03-07T08:41:46.234Z',
- build_path: '/twitter/flight/-/jobs/217',
- retry_path: '/twitter/flight/-/jobs/217/retry',
- playable: false,
- created_at: '2018-03-07T14:41:58.093Z',
- updated_at: '2018-03-07T14:41:58.093Z',
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- tooltip: 'passed',
- has_details: true,
- details_path: '/twitter/flight/-/jobs/217',
- favicon:
- '/assets/ci_favicons/dev/favicon_status_success-308b4fc054cdd1b68d0865e6cfb7b02e92e3472f201507418f8eddb74ac11a59.ico',
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/twitter/flight/-/jobs/217/retry',
- method: 'post',
- },
- },
- },
- ],
- status: {
- icon: 'status_running',
- text: 'running',
- label: 'running',
- group: 'running',
- tooltip: 'running',
- has_details: true,
- details_path: '/twitter/flight/pipelines/13#deploy',
- favicon:
- '/assets/ci_favicons/dev/favicon_status_running-c3ad2fc53ea6079c174e5b6c1351ff349e99ec3af5a5622fb77b0fe53ea279c1.ico',
- },
- path: '/twitter/flight/pipelines/13#deploy',
- dropdown_path: '/twitter/flight/pipelines/13/stage.json?stage=deploy',
-};
-
export const users = [
{
id: 1,
diff --git a/spec/frontend/pipelines/pipeline_tabs_spec.js b/spec/frontend/ci/pipeline_details/pipeline_tabs_spec.js
index 8d67cdef05c..8d67cdef05c 100644
--- a/spec/frontend/pipelines/pipeline_tabs_spec.js
+++ b/spec/frontend/ci/pipeline_details/pipeline_tabs_spec.js
diff --git a/spec/frontend/pipelines/nav_controls_spec.js b/spec/frontend/ci/pipeline_details/pipelines_list/components/nav_controls_spec.js
index cefe0c9f0a3..cefe0c9f0a3 100644
--- a/spec/frontend/pipelines/nav_controls_spec.js
+++ b/spec/frontend/ci/pipeline_details/pipelines_list/components/nav_controls_spec.js
diff --git a/spec/frontend/pipelines/pipeline_labels_spec.js b/spec/frontend/ci/pipeline_details/pipelines_list/components/pipeline_labels_spec.js
index b90f7d035e0..87c2867b5d8 100644
--- a/spec/frontend/pipelines/pipeline_labels_spec.js
+++ b/spec/frontend/ci/pipeline_details/pipelines_list/components/pipeline_labels_spec.js
@@ -1,7 +1,7 @@
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { trimText } from 'helpers/text_helper';
import PipelineLabelsComponent from '~/ci/pipeline_details/pipelines_list/components/pipeline_labels.vue';
-import { mockPipeline } from './mock_data';
+import { mockPipeline } from '../../mock_data';
const projectPath = 'test/test';
diff --git a/spec/frontend/pipelines/pipeline_multi_actions_spec.js b/spec/frontend/ci/pipeline_details/pipelines_list/components/pipeline_multi_actions_spec.js
index 6827aea7b1c..6827aea7b1c 100644
--- a/spec/frontend/pipelines/pipeline_multi_actions_spec.js
+++ b/spec/frontend/ci/pipeline_details/pipelines_list/components/pipeline_multi_actions_spec.js
diff --git a/spec/frontend/pipelines/pipeline_operations_spec.js b/spec/frontend/ci/pipeline_details/pipelines_list/components/pipeline_operations_spec.js
index 3e2005236bb..3e2005236bb 100644
--- a/spec/frontend/pipelines/pipeline_operations_spec.js
+++ b/spec/frontend/ci/pipeline_details/pipelines_list/components/pipeline_operations_spec.js
diff --git a/spec/frontend/pipelines/components/pipelines_list/pipeline_stop_modal_spec.js b/spec/frontend/ci/pipeline_details/pipelines_list/components/pipeline_stop_modal_spec.js
index 15a202424d0..81fed11875d 100644
--- a/spec/frontend/pipelines/components/pipelines_list/pipeline_stop_modal_spec.js
+++ b/spec/frontend/ci/pipeline_details/pipelines_list/components/pipeline_stop_modal_spec.js
@@ -1,7 +1,7 @@
import { shallowMount } from '@vue/test-utils';
import { GlSprintf } from '@gitlab/ui';
+import { mockPipelineHeader } from 'jest/ci/pipeline_details/mock_data';
import PipelineStopModal from '~/ci/pipeline_details/pipelines_list/components/pipeline_stop_modal.vue';
-import { mockPipelineHeader } from '../../mock_data';
describe('PipelineStopModal', () => {
let wrapper;
diff --git a/spec/frontend/pipelines/pipeline_triggerer_spec.js b/spec/frontend/ci/pipeline_details/pipelines_list/components/pipeline_triggerer_spec.js
index 4c8a43598ad..4c8a43598ad 100644
--- a/spec/frontend/pipelines/pipeline_triggerer_spec.js
+++ b/spec/frontend/ci/pipeline_details/pipelines_list/components/pipeline_triggerer_spec.js
diff --git a/spec/frontend/pipelines/pipeline_url_spec.js b/spec/frontend/ci/pipeline_details/pipelines_list/components/pipeline_url_spec.js
index c1be2b096f6..78097edecd3 100644
--- a/spec/frontend/pipelines/pipeline_url_spec.js
+++ b/spec/frontend/ci/pipeline_details/pipelines_list/components/pipeline_url_spec.js
@@ -4,7 +4,7 @@ import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import PipelineUrlComponent from '~/ci/pipeline_details/pipelines_list/components/pipeline_url.vue';
import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
import { TRACKING_CATEGORIES } from '~/ci/pipeline_details/constants';
-import { mockPipeline, mockPipelineBranch, mockPipelineTag } from './mock_data';
+import { mockPipeline, mockPipelineBranch, mockPipelineTag } from '../../mock_data';
const projectPath = 'test/test';
diff --git a/spec/frontend/pipelines/pipelines_artifacts_spec.js b/spec/frontend/ci/pipeline_details/pipelines_list/components/pipelines_artifacts_spec.js
index 7ef3513cbce..7ef3513cbce 100644
--- a/spec/frontend/pipelines/pipelines_artifacts_spec.js
+++ b/spec/frontend/ci/pipeline_details/pipelines_list/components/pipelines_artifacts_spec.js
diff --git a/spec/frontend/pipelines/components/pipelines_filtered_search_spec.js b/spec/frontend/ci/pipeline_details/pipelines_list/components/pipelines_filtered_search_spec.js
index 431f32ce24f..0b62920e01b 100644
--- a/spec/frontend/pipelines/components/pipelines_filtered_search_spec.js
+++ b/spec/frontend/ci/pipeline_details/pipelines_list/components/pipelines_filtered_search_spec.js
@@ -11,7 +11,7 @@ import {
OPERATORS_IS,
} from '~/vue_shared/components/filtered_search_bar/constants';
import { TRACKING_CATEGORIES } from '~/ci/pipeline_details/constants';
-import { users, mockSearch, branches, tags } from '../mock_data';
+import { users, mockSearch, branches, tags } from '../../mock_data';
describe('Pipelines filtered search', () => {
let wrapper;
diff --git a/spec/frontend/pipelines/pipelines_manual_actions_spec.js b/spec/frontend/ci/pipeline_details/pipelines_list/components/pipelines_manual_actions_spec.js
index c0ea0fda4df..c0ea0fda4df 100644
--- a/spec/frontend/pipelines/pipelines_manual_actions_spec.js
+++ b/spec/frontend/ci/pipeline_details/pipelines_list/components/pipelines_manual_actions_spec.js
diff --git a/spec/frontend/pipelines/pipelines_table_spec.js b/spec/frontend/ci/pipeline_details/pipelines_list/components/pipelines_table_spec.js
index 2ae8475f38d..2ae8475f38d 100644
--- a/spec/frontend/pipelines/pipelines_table_spec.js
+++ b/spec/frontend/ci/pipeline_details/pipelines_list/components/pipelines_table_spec.js
diff --git a/spec/frontend/pipelines/time_ago_spec.js b/spec/frontend/ci/pipeline_details/pipelines_list/components/time_ago_spec.js
index e651427fb78..e651427fb78 100644
--- a/spec/frontend/pipelines/time_ago_spec.js
+++ b/spec/frontend/ci/pipeline_details/pipelines_list/components/time_ago_spec.js
diff --git a/spec/frontend/pipelines/components/pipelines_list/empty_state/ci_templates_spec.js b/spec/frontend/ci/pipeline_details/pipelines_list/empty_state/ci_templates_spec.js
index 558063ecba5..558063ecba5 100644
--- a/spec/frontend/pipelines/components/pipelines_list/empty_state/ci_templates_spec.js
+++ b/spec/frontend/ci/pipeline_details/pipelines_list/empty_state/ci_templates_spec.js
diff --git a/spec/frontend/pipelines/components/pipelines_list/empty_state/ios_templates_spec.js b/spec/frontend/ci/pipeline_details/pipelines_list/empty_state/ios_templates_spec.js
index cdd3053d66a..cdd3053d66a 100644
--- a/spec/frontend/pipelines/components/pipelines_list/empty_state/ios_templates_spec.js
+++ b/spec/frontend/ci/pipeline_details/pipelines_list/empty_state/ios_templates_spec.js
diff --git a/spec/frontend/pipelines/empty_state_spec.js b/spec/frontend/ci/pipeline_details/pipelines_list/empty_state/no_ci_empty_state_spec.js
index 6ef37f59f66..6ef37f59f66 100644
--- a/spec/frontend/pipelines/empty_state_spec.js
+++ b/spec/frontend/ci/pipeline_details/pipelines_list/empty_state/no_ci_empty_state_spec.js
diff --git a/spec/frontend/pipelines/components/pipelines_list/empty_state/pipelines_ci_templates_spec.js b/spec/frontend/ci/pipeline_details/pipelines_list/empty_state/pipelines_ci_templates_spec.js
index 76b4cc163b2..76b4cc163b2 100644
--- a/spec/frontend/pipelines/components/pipelines_list/empty_state/pipelines_ci_templates_spec.js
+++ b/spec/frontend/ci/pipeline_details/pipelines_list/empty_state/pipelines_ci_templates_spec.js
diff --git a/spec/frontend/pipelines/components/pipelines_list/failure_widget/failed_job_details_spec.js b/spec/frontend/ci/pipeline_details/pipelines_list/failure_widget/failed_job_details_spec.js
index cc68af4f7f3..cc68af4f7f3 100644
--- a/spec/frontend/pipelines/components/pipelines_list/failure_widget/failed_job_details_spec.js
+++ b/spec/frontend/ci/pipeline_details/pipelines_list/failure_widget/failed_job_details_spec.js
diff --git a/spec/frontend/pipelines/components/pipelines_list/failure_widget/failed_jobs_list_spec.js b/spec/frontend/ci/pipeline_details/pipelines_list/failure_widget/failed_jobs_list_spec.js
index 6c1c5f9c223..6c1c5f9c223 100644
--- a/spec/frontend/pipelines/components/pipelines_list/failure_widget/failed_jobs_list_spec.js
+++ b/spec/frontend/ci/pipeline_details/pipelines_list/failure_widget/failed_jobs_list_spec.js
diff --git a/spec/frontend/pipelines/components/pipelines_list/failure_widget/mock.js b/spec/frontend/ci/pipeline_details/pipelines_list/failure_widget/mock.js
index 318d787a984..318d787a984 100644
--- a/spec/frontend/pipelines/components/pipelines_list/failure_widget/mock.js
+++ b/spec/frontend/ci/pipeline_details/pipelines_list/failure_widget/mock.js
diff --git a/spec/frontend/pipelines/components/pipelines_list/failure_widget/pipeline_failed_jobs_widget_spec.js b/spec/frontend/ci/pipeline_details/pipelines_list/failure_widget/pipeline_failed_jobs_widget_spec.js
index 5135bf57b22..5135bf57b22 100644
--- a/spec/frontend/pipelines/components/pipelines_list/failure_widget/pipeline_failed_jobs_widget_spec.js
+++ b/spec/frontend/ci/pipeline_details/pipelines_list/failure_widget/pipeline_failed_jobs_widget_spec.js
diff --git a/spec/frontend/pipelines/components/pipelines_list/failure_widget/utils_spec.js b/spec/frontend/ci/pipeline_details/pipelines_list/failure_widget/utils_spec.js
index 16a0da4e054..16a0da4e054 100644
--- a/spec/frontend/pipelines/components/pipelines_list/failure_widget/utils_spec.js
+++ b/spec/frontend/ci/pipeline_details/pipelines_list/failure_widget/utils_spec.js
diff --git a/spec/frontend/pipelines/pipelines_spec.js b/spec/frontend/ci/pipeline_details/pipelines_list/pipelines_spec.js
index dd12286f71c..5790b753706 100644
--- a/spec/frontend/pipelines/pipelines_spec.js
+++ b/spec/frontend/ci/pipeline_details/pipelines_list/pipelines_spec.js
@@ -37,7 +37,8 @@ import {
setIdTypePreferenceMutationResponseWithErrors,
} from 'jest/issues/list/mock_data';
-import { stageReply, users, mockSearch, branches } from './mock_data';
+import { stageReply } from 'jest/ci/pipeline_mini_graph/mock_data';
+import { users, mockSearch, branches } from '../mock_data';
jest.mock('@sentry/browser');
jest.mock('~/alert');
diff --git a/spec/frontend/pipelines/tokens/pipeline_branch_name_token_spec.js b/spec/frontend/ci/pipeline_details/pipelines_list/tokens/pipeline_branch_name_token_spec.js
index bf58e337a79..effcb533ffa 100644
--- a/spec/frontend/pipelines/tokens/pipeline_branch_name_token_spec.js
+++ b/spec/frontend/ci/pipeline_details/pipelines_list/tokens/pipeline_branch_name_token_spec.js
@@ -4,7 +4,7 @@ import { shallowMount } from '@vue/test-utils';
import waitForPromises from 'helpers/wait_for_promises';
import Api from '~/api';
import PipelineBranchNameToken from '~/ci/pipeline_details/pipelines_list/tokens/pipeline_branch_name_token.vue';
-import { branches, mockBranchesAfterMap } from '../mock_data';
+import { branches, mockBranchesAfterMap } from '../../mock_data';
describe('Pipeline Branch Name Token', () => {
let wrapper;
diff --git a/spec/frontend/pipelines/tokens/pipeline_source_token_spec.js b/spec/frontend/ci/pipeline_details/pipelines_list/tokens/pipeline_source_token_spec.js
index 180fdee8353..180fdee8353 100644
--- a/spec/frontend/pipelines/tokens/pipeline_source_token_spec.js
+++ b/spec/frontend/ci/pipeline_details/pipelines_list/tokens/pipeline_source_token_spec.js
diff --git a/spec/frontend/pipelines/tokens/pipeline_status_token_spec.js b/spec/frontend/ci/pipeline_details/pipelines_list/tokens/pipeline_status_token_spec.js
index 4b9d4fb7a94..4b9d4fb7a94 100644
--- a/spec/frontend/pipelines/tokens/pipeline_status_token_spec.js
+++ b/spec/frontend/ci/pipeline_details/pipelines_list/tokens/pipeline_status_token_spec.js
diff --git a/spec/frontend/pipelines/tokens/pipeline_tag_name_token_spec.js b/spec/frontend/ci/pipeline_details/pipelines_list/tokens/pipeline_tag_name_token_spec.js
index a40c6f5c8f8..d3eae14608d 100644
--- a/spec/frontend/pipelines/tokens/pipeline_tag_name_token_spec.js
+++ b/spec/frontend/ci/pipeline_details/pipelines_list/tokens/pipeline_tag_name_token_spec.js
@@ -2,7 +2,7 @@ import { GlFilteredSearchToken, GlFilteredSearchSuggestion, GlLoadingIcon } from
import { shallowMount } from '@vue/test-utils';
import Api from '~/api';
import PipelineTagNameToken from '~/ci/pipeline_details/pipelines_list/tokens/pipeline_tag_name_token.vue';
-import { tags, mockTagsAfterMap } from '../mock_data';
+import { tags, mockTagsAfterMap } from '../../mock_data';
describe('Pipeline Branch Name Token', () => {
let wrapper;
diff --git a/spec/frontend/pipelines/tokens/pipeline_trigger_author_token_spec.js b/spec/frontend/ci/pipeline_details/pipelines_list/tokens/pipeline_trigger_author_token_spec.js
index cc1303f4abc..2eab2cd2ef2 100644
--- a/spec/frontend/pipelines/tokens/pipeline_trigger_author_token_spec.js
+++ b/spec/frontend/ci/pipeline_details/pipelines_list/tokens/pipeline_trigger_author_token_spec.js
@@ -3,7 +3,7 @@ import { shallowMount } from '@vue/test-utils';
import { stubComponent } from 'helpers/stub_component';
import Api from '~/api';
import PipelineTriggerAuthorToken from '~/ci/pipeline_details/pipelines_list/tokens/pipeline_trigger_author_token.vue';
-import { users } from '../mock_data';
+import { users } from '../../mock_data';
describe('Pipeline Trigger Author Token', () => {
let wrapper;
diff --git a/spec/frontend/pipelines/pipelines_store_spec.js b/spec/frontend/ci/pipeline_details/pipelines_store_spec.js
index 43e605f4306..43e605f4306 100644
--- a/spec/frontend/pipelines/pipelines_store_spec.js
+++ b/spec/frontend/ci/pipeline_details/pipelines_store_spec.js
diff --git a/spec/frontend/pipelines/components/pipeline_tabs_spec.js b/spec/frontend/ci/pipeline_details/tabs/pipeline_tabs_spec.js
index 700d51930dd..700d51930dd 100644
--- a/spec/frontend/pipelines/components/pipeline_tabs_spec.js
+++ b/spec/frontend/ci/pipeline_details/tabs/pipeline_tabs_spec.js
diff --git a/spec/frontend/pipelines/test_reports/empty_state_spec.js b/spec/frontend/ci/pipeline_details/test_reports/empty_state_spec.js
index ed1d6bc7d37..ed1d6bc7d37 100644
--- a/spec/frontend/pipelines/test_reports/empty_state_spec.js
+++ b/spec/frontend/ci/pipeline_details/test_reports/empty_state_spec.js
diff --git a/spec/frontend/pipelines/test_reports/mock_data.js b/spec/frontend/ci/pipeline_details/test_reports/mock_data.js
index 7c9f9287c86..7c9f9287c86 100644
--- a/spec/frontend/pipelines/test_reports/mock_data.js
+++ b/spec/frontend/ci/pipeline_details/test_reports/mock_data.js
diff --git a/spec/frontend/pipelines/test_reports/stores/actions_spec.js b/spec/frontend/ci/pipeline_details/test_reports/stores/actions_spec.js
index 6636a7f1ed6..6636a7f1ed6 100644
--- a/spec/frontend/pipelines/test_reports/stores/actions_spec.js
+++ b/spec/frontend/ci/pipeline_details/test_reports/stores/actions_spec.js
diff --git a/spec/frontend/pipelines/test_reports/stores/getters_spec.js b/spec/frontend/ci/pipeline_details/test_reports/stores/getters_spec.js
index e52e9a07ae0..e52e9a07ae0 100644
--- a/spec/frontend/pipelines/test_reports/stores/getters_spec.js
+++ b/spec/frontend/ci/pipeline_details/test_reports/stores/getters_spec.js
diff --git a/spec/frontend/pipelines/test_reports/stores/mutations_spec.js b/spec/frontend/ci/pipeline_details/test_reports/stores/mutations_spec.js
index d58515dcc6d..d58515dcc6d 100644
--- a/spec/frontend/pipelines/test_reports/stores/mutations_spec.js
+++ b/spec/frontend/ci/pipeline_details/test_reports/stores/mutations_spec.js
diff --git a/spec/frontend/pipelines/test_reports/stores/utils_spec.js b/spec/frontend/ci/pipeline_details/test_reports/stores/utils_spec.js
index c0ffc2b34fb..c0ffc2b34fb 100644
--- a/spec/frontend/pipelines/test_reports/stores/utils_spec.js
+++ b/spec/frontend/ci/pipeline_details/test_reports/stores/utils_spec.js
diff --git a/spec/frontend/pipelines/test_reports/test_case_details_spec.js b/spec/frontend/ci/pipeline_details/test_reports/test_case_details_spec.js
index 0f651b9d456..0f651b9d456 100644
--- a/spec/frontend/pipelines/test_reports/test_case_details_spec.js
+++ b/spec/frontend/ci/pipeline_details/test_reports/test_case_details_spec.js
diff --git a/spec/frontend/pipelines/test_reports/test_reports_spec.js b/spec/frontend/ci/pipeline_details/test_reports/test_reports_spec.js
index 8ff060026da..8ff060026da 100644
--- a/spec/frontend/pipelines/test_reports/test_reports_spec.js
+++ b/spec/frontend/ci/pipeline_details/test_reports/test_reports_spec.js
diff --git a/spec/frontend/pipelines/test_reports/test_suite_table_spec.js b/spec/frontend/ci/pipeline_details/test_reports/test_suite_table_spec.js
index 5bdea6bbcbf..5bdea6bbcbf 100644
--- a/spec/frontend/pipelines/test_reports/test_suite_table_spec.js
+++ b/spec/frontend/ci/pipeline_details/test_reports/test_suite_table_spec.js
diff --git a/spec/frontend/pipelines/test_reports/test_summary_spec.js b/spec/frontend/ci/pipeline_details/test_reports/test_summary_spec.js
index f9182d52c8a..f9182d52c8a 100644
--- a/spec/frontend/pipelines/test_reports/test_summary_spec.js
+++ b/spec/frontend/ci/pipeline_details/test_reports/test_summary_spec.js
diff --git a/spec/frontend/pipelines/test_reports/test_summary_table_spec.js b/spec/frontend/ci/pipeline_details/test_reports/test_summary_table_spec.js
index bb62fbcb32c..bb62fbcb32c 100644
--- a/spec/frontend/pipelines/test_reports/test_summary_table_spec.js
+++ b/spec/frontend/ci/pipeline_details/test_reports/test_summary_table_spec.js
diff --git a/spec/frontend/pipelines/pipeline_graph/utils_spec.js b/spec/frontend/ci/pipeline_details/utils/index_spec.js
index 61230cb52e6..61230cb52e6 100644
--- a/spec/frontend/pipelines/pipeline_graph/utils_spec.js
+++ b/spec/frontend/ci/pipeline_details/utils/index_spec.js
diff --git a/spec/frontend/pipelines/utils_spec.js b/spec/frontend/ci/pipeline_details/utils/parsing_utils_spec.js
index b52a646cefc..9390f076d3d 100644
--- a/spec/frontend/pipelines/utils_spec.js
+++ b/spec/frontend/ci/pipeline_details/utils/parsing_utils_spec.js
@@ -1,5 +1,5 @@
import mockPipelineResponse from 'test_fixtures/pipelines/pipeline_details.json';
-import { createSankey } from '~/ci/pipeline_details/dag/drawing_utils';
+import { createSankey } from '~/ci/pipeline_details/dag/utils/drawing_utils';
import {
makeLinksFromNodes,
filterByAncestors,
@@ -12,10 +12,10 @@ import {
} from '~/ci/pipeline_details/utils/parsing_utils';
import { createNodeDict } from '~/ci/pipeline_details/utils';
-import { mockDownstreamPipelinesRest } from '../vue_merge_request_widget/mock_data';
-import { mockDownstreamPipelinesGraphql } from '../commit/mock_data';
-import { mockParsedGraphQLNodes, missingJob } from './components/dag/mock_data';
-import { generateResponse } from './graph/mock_data';
+import { mockDownstreamPipelinesRest } from '../../../vue_merge_request_widget/mock_data';
+import { mockDownstreamPipelinesGraphql } from '../../../commit/mock_data';
+import { mockParsedGraphQLNodes, missingJob } from '../dag/mock_data';
+import { generateResponse } from '../graph/mock_data';
describe('DAG visualization parsing utilities', () => {
const nodeDict = createNodeDict(mockParsedGraphQLNodes);
diff --git a/spec/frontend/pipelines/unwrapping_utils_spec.js b/spec/frontend/ci/pipeline_details/utils/unwrapping_utils_spec.js
index 99ee2eff1e4..99ee2eff1e4 100644
--- a/spec/frontend/pipelines/unwrapping_utils_spec.js
+++ b/spec/frontend/ci/pipeline_details/utils/unwrapping_utils_spec.js
diff --git a/spec/frontend/pipelines/pipeline_graph/mock_data.js b/spec/frontend/ci/pipeline_editor/components/graph/mock_data.js
index db77e0a0573..db77e0a0573 100644
--- a/spec/frontend/pipelines/pipeline_graph/mock_data.js
+++ b/spec/frontend/ci/pipeline_editor/components/graph/mock_data.js
diff --git a/spec/frontend/pipelines/pipeline_graph/pipeline_graph_spec.js b/spec/frontend/ci/pipeline_editor/components/graph/pipeline_graph_spec.js
index 95edfb01cf0..95edfb01cf0 100644
--- a/spec/frontend/pipelines/pipeline_graph/pipeline_graph_spec.js
+++ b/spec/frontend/ci/pipeline_editor/components/graph/pipeline_graph_spec.js
diff --git a/spec/frontend/pipelines/components/pipeline_mini_graph/job_item_spec.js b/spec/frontend/ci/pipeline_mini_graph/job_item_spec.js
index 9c14e75caa4..9c14e75caa4 100644
--- a/spec/frontend/pipelines/components/pipeline_mini_graph/job_item_spec.js
+++ b/spec/frontend/ci/pipeline_mini_graph/job_item_spec.js
diff --git a/spec/frontend/pipelines/components/pipeline_mini_graph/legacy_pipeline_mini_graph_spec.js b/spec/frontend/ci/pipeline_mini_graph/legacy_pipeline_mini_graph_spec.js
index 916f3053153..916f3053153 100644
--- a/spec/frontend/pipelines/components/pipeline_mini_graph/legacy_pipeline_mini_graph_spec.js
+++ b/spec/frontend/ci/pipeline_mini_graph/legacy_pipeline_mini_graph_spec.js
diff --git a/spec/frontend/pipelines/components/pipeline_mini_graph/legacy_pipeline_stage_spec.js b/spec/frontend/ci/pipeline_mini_graph/legacy_pipeline_stage_spec.js
index 6573aaf39fa..1d44134bef8 100644
--- a/spec/frontend/pipelines/components/pipeline_mini_graph/legacy_pipeline_stage_spec.js
+++ b/spec/frontend/ci/pipeline_mini_graph/legacy_pipeline_stage_spec.js
@@ -8,7 +8,7 @@ import { HTTP_STATUS_INTERNAL_SERVER_ERROR, HTTP_STATUS_OK } from '~/lib/utils/h
import LegacyPipelineStage from '~/ci/pipeline_mini_graph/legacy_pipeline_stage.vue';
import eventHub from '~/ci/pipeline_details/event_hub';
import waitForPromises from 'helpers/wait_for_promises';
-import { stageReply } from '../../mock_data';
+import { stageReply } from './mock_data';
const dropdownPath = 'path.json';
diff --git a/spec/frontend/pipelines/components/pipeline_mini_graph/linked_pipelines_mini_list_spec.js b/spec/frontend/ci/pipeline_mini_graph/linked_pipelines_mini_list_spec.js
index 0396029cdaf..0396029cdaf 100644
--- a/spec/frontend/pipelines/components/pipeline_mini_graph/linked_pipelines_mini_list_spec.js
+++ b/spec/frontend/ci/pipeline_mini_graph/linked_pipelines_mini_list_spec.js
diff --git a/spec/frontend/pipelines/components/pipeline_mini_graph/linked_pipelines_mock_data.js b/spec/frontend/ci/pipeline_mini_graph/linked_pipelines_mock_data.js
index 117c7f2ae52..117c7f2ae52 100644
--- a/spec/frontend/pipelines/components/pipeline_mini_graph/linked_pipelines_mock_data.js
+++ b/spec/frontend/ci/pipeline_mini_graph/linked_pipelines_mock_data.js
diff --git a/spec/frontend/pipelines/components/pipeline_mini_graph/mock_data.js b/spec/frontend/ci/pipeline_mini_graph/mock_data.js
index 1c13e9eb62b..231375b40dd 100644
--- a/spec/frontend/pipelines/components/pipeline_mini_graph/mock_data.js
+++ b/spec/frontend/ci/pipeline_mini_graph/mock_data.js
@@ -148,3 +148,105 @@ export const mockUpstreamDownstreamQueryResponse = {
export const linkedPipelinesFetchError = 'There was a problem fetching linked pipelines.';
export const stagesFetchError = 'There was a problem fetching the pipeline stages.';
+
+export const stageReply = {
+ name: 'deploy',
+ title: 'deploy: running',
+ latest_statuses: [
+ {
+ id: 928,
+ name: 'stop staging',
+ started: false,
+ build_path: '/twitter/flight/-/jobs/928',
+ cancel_path: '/twitter/flight/-/jobs/928/cancel',
+ playable: false,
+ created_at: '2018-04-04T20:02:02.728Z',
+ updated_at: '2018-04-04T20:02:02.766Z',
+ status: {
+ icon: 'status_pending',
+ text: 'pending',
+ label: 'pending',
+ group: 'pending',
+ tooltip: 'pending',
+ has_details: true,
+ details_path: '/twitter/flight/-/jobs/928',
+ favicon:
+ '/assets/ci_favicons/dev/favicon_status_pending-db32e1faf94b9f89530ac519790920d1f18ea8f6af6cd2e0a26cd6840cacf101.ico',
+ action: {
+ icon: 'cancel',
+ title: 'Cancel',
+ path: '/twitter/flight/-/jobs/928/cancel',
+ method: 'post',
+ },
+ },
+ },
+ {
+ id: 926,
+ name: 'production',
+ started: false,
+ build_path: '/twitter/flight/-/jobs/926',
+ retry_path: '/twitter/flight/-/jobs/926/retry',
+ play_path: '/twitter/flight/-/jobs/926/play',
+ playable: true,
+ created_at: '2018-04-04T20:00:57.202Z',
+ updated_at: '2018-04-04T20:11:13.110Z',
+ status: {
+ icon: 'status_canceled',
+ text: 'canceled',
+ label: 'manual play action',
+ group: 'canceled',
+ tooltip: 'canceled',
+ has_details: true,
+ details_path: '/twitter/flight/-/jobs/926',
+ favicon:
+ '/assets/ci_favicons/dev/favicon_status_canceled-5491840b9b6feafba0bc599cbd49ee9580321dc809683856cf1b0d51532b1af6.ico',
+ action: {
+ icon: 'play',
+ title: 'Play',
+ path: '/twitter/flight/-/jobs/926/play',
+ method: 'post',
+ },
+ },
+ },
+ {
+ id: 217,
+ name: 'staging',
+ started: '2018-03-07T08:41:46.234Z',
+ build_path: '/twitter/flight/-/jobs/217',
+ retry_path: '/twitter/flight/-/jobs/217/retry',
+ playable: false,
+ created_at: '2018-03-07T14:41:58.093Z',
+ updated_at: '2018-03-07T14:41:58.093Z',
+ status: {
+ icon: 'status_success',
+ text: 'passed',
+ label: 'passed',
+ group: 'success',
+ tooltip: 'passed',
+ has_details: true,
+ details_path: '/twitter/flight/-/jobs/217',
+ favicon:
+ '/assets/ci_favicons/dev/favicon_status_success-308b4fc054cdd1b68d0865e6cfb7b02e92e3472f201507418f8eddb74ac11a59.ico',
+ action: {
+ icon: 'retry',
+ title: 'Retry',
+ path: '/twitter/flight/-/jobs/217/retry',
+ method: 'post',
+ },
+ },
+ },
+ ],
+ status: {
+ icon: 'status_running',
+ text: 'running',
+ label: 'running',
+ group: 'running',
+ tooltip: 'running',
+ has_details: true,
+ details_path: '/twitter/flight/pipelines/13#deploy',
+ favicon:
+ '/assets/ci_favicons/dev/favicon_status_running-c3ad2fc53ea6079c174e5b6c1351ff349e99ec3af5a5622fb77b0fe53ea279c1.ico',
+ },
+ path: '/twitter/flight/pipelines/13#deploy',
+ dropdown_path: '/twitter/flight/pipelines/13/stage.json?stage=deploy',
+};
diff --git a/spec/frontend/pipelines/components/pipeline_mini_graph/pipeline_mini_graph_spec.js b/spec/frontend/ci/pipeline_mini_graph/pipeline_mini_graph_spec.js
index 6833726a297..6833726a297 100644
--- a/spec/frontend/pipelines/components/pipeline_mini_graph/pipeline_mini_graph_spec.js
+++ b/spec/frontend/ci/pipeline_mini_graph/pipeline_mini_graph_spec.js
diff --git a/spec/frontend/pipelines/components/pipeline_mini_graph/pipeline_stage_spec.js b/spec/frontend/ci/pipeline_mini_graph/pipeline_stage_spec.js
index 96966bcbb84..96966bcbb84 100644
--- a/spec/frontend/pipelines/components/pipeline_mini_graph/pipeline_stage_spec.js
+++ b/spec/frontend/ci/pipeline_mini_graph/pipeline_stage_spec.js
diff --git a/spec/frontend/pipelines/components/pipeline_mini_graph/pipeline_stages_spec.js b/spec/frontend/ci/pipeline_mini_graph/pipeline_stages_spec.js
index bbd39c6fcd9..bbd39c6fcd9 100644
--- a/spec/frontend/pipelines/components/pipeline_mini_graph/pipeline_stages_spec.js
+++ b/spec/frontend/ci/pipeline_mini_graph/pipeline_stages_spec.js
diff --git a/spec/frontend/pipelines/notification/mock_data.js b/spec/frontend/pipelines/notification/mock_data.js
deleted file mode 100644
index e36f391a854..00000000000
--- a/spec/frontend/pipelines/notification/mock_data.js
+++ /dev/null
@@ -1,33 +0,0 @@
-const randomWarning = {
- content: 'another random warning',
- id: 'gid://gitlab/Ci::PipelineMessage/272',
-};
-
-const rootTypeWarning = {
- content: 'root `types` will be removed in 15.0.',
- id: 'gid://gitlab/Ci::PipelineMessage/273',
-};
-
-const typeWarning = {
- content: '`type` will be removed in 15.0.',
- id: 'gid://gitlab/Ci::PipelineMessage/274',
-};
-
-function createWarningMock(warnings) {
- return {
- data: {
- project: {
- id: 'gid://gitlab/Project/28"',
- pipeline: {
- id: 'gid://gitlab/Ci::Pipeline/183',
- warningMessages: warnings,
- },
- },
- },
- };
-}
-
-export const mockWarningsWithoutDeprecation = createWarningMock([randomWarning]);
-export const mockWarningsRootType = createWarningMock([rootTypeWarning]);
-export const mockWarningsType = createWarningMock([typeWarning]);
-export const mockWarningsTypesAll = createWarningMock([rootTypeWarning, typeWarning]);
diff --git a/spec/lib/gitlab/bitbucket_server_import/importer_spec.rb b/spec/lib/gitlab/bitbucket_server_import/importer_spec.rb
deleted file mode 100644
index 4ff61bf329c..00000000000
--- a/spec/lib/gitlab/bitbucket_server_import/importer_spec.rb
+++ /dev/null
@@ -1,653 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::BitbucketServerImport::Importer, feature_category: :importers do
- include ImportSpecHelper
-
- let(:import_url) { 'http://my-bitbucket' }
- let(:bitbucket_user) { 'bitbucket' }
- let(:project_creator) { create(:user, username: 'project_creator', email: 'project_creator@example.org') }
- let(:password) { 'test' }
- let(:project) { create(:project, :repository, import_url: import_url, creator: project_creator) }
- let(:now) { Time.now.utc.change(usec: 0) }
- let(:project_key) { 'TEST' }
- let(:repo_slug) { 'rouge-repo' }
- let(:sample) { RepoHelpers.sample_compare }
-
- subject { described_class.new(project, recover_missing_commits: true) }
-
- before do
- data = project.create_or_update_import_data(
- data: { project_key: project_key, repo_slug: repo_slug },
- credentials: { base_uri: import_url, user: bitbucket_user, password: password }
- )
- data.save!
- project.save!
- end
-
- describe '#import_repository' do
- let(:repo_url) { 'http://bitbucket:test@my-bitbucket' }
-
- before do
- expect(project.repository).to receive(:import_repository).with(repo_url)
- end
-
- it 'adds a remote' do
- expect(subject).to receive(:import_pull_requests)
- expect(subject).to receive(:delete_temp_branches)
- expect(project.repository).to receive(:fetch_as_mirror)
- .with(repo_url,
- refmap: ['+refs/pull-requests/*/to:refs/merge-requests/*/head'])
-
- subject.execute
- end
-
- it 'raises a Gitlab::Git::CommandError in the fetch' do
- expect(project.repository).to receive(:fetch_as_mirror).and_raise(::Gitlab::Git::CommandError)
-
- expect { subject.execute }.to raise_error(::Gitlab::Git::CommandError)
- end
-
- it 'raises an unhandled exception in the fetch' do
- expect(project.repository).to receive(:fetch_as_mirror).and_raise(RuntimeError)
-
- expect { subject.execute }.to raise_error(RuntimeError)
- end
- end
-
- describe '#import_pull_requests' do
- let(:pull_request_author) { create(:user, username: 'pull_request_author', email: 'pull_request_author@example.org') }
- let(:note_author) { create(:user, username: 'note_author', email: 'note_author@example.org') }
-
- let(:pull_request) do
- instance_double(
- BitbucketServer::Representation::PullRequest,
- iid: 10,
- source_branch_sha: sample.commits.last,
- source_branch_name: Gitlab::Git::BRANCH_REF_PREFIX + sample.source_branch,
- target_branch_sha: sample.commits.first,
- target_branch_name: Gitlab::Git::BRANCH_REF_PREFIX + sample.target_branch,
- title: 'This is a title',
- description: 'This is a test pull request',
- reviewers: [],
- state: 'merged',
- author: 'Test Author',
- author_email: pull_request_author.email,
- author_username: pull_request_author.username,
- created_at: Time.now,
- updated_at: Time.now,
- raw: {},
- merged?: true)
- end
-
- let(:merge_event) do
- instance_double(
- BitbucketServer::Representation::Activity,
- comment?: false,
- merge_event?: true,
- committer_email: pull_request_author.email,
- merge_timestamp: now,
- merge_commit: '12345678'
- )
- end
-
- let(:pr_note) do
- instance_double(
- BitbucketServer::Representation::Comment,
- note: 'Hello world',
- author_email: note_author.email,
- author_username: note_author.username,
- comments: [],
- created_at: now,
- updated_at: now,
- parent_comment: nil)
- end
-
- let(:pr_comment) do
- instance_double(
- BitbucketServer::Representation::Activity,
- comment?: true,
- inline_comment?: false,
- merge_event?: false,
- comment: pr_note)
- end
-
- before do
- allow(subject).to receive(:import_repository)
- allow(subject).to receive(:delete_temp_branches)
- allow(subject).to receive(:restore_branches)
-
- allow(subject.client).to receive(:pull_requests).and_return([pull_request], [])
- end
-
- # As we are using Caching with redis, it is best to clean the cache after each test run, else we need to wait for
- # the expiration by the importer
- after do
- Gitlab::Cache::Import::Caching.expire(subject.already_imported_cache_key, 0)
- end
-
- it 'imports merge event' do
- expect(subject.client).to receive(:activities).and_return([merge_event])
-
- expect { subject.execute }.to change { MergeRequest.count }.by(1)
-
- merge_request = MergeRequest.first
- expect(merge_request.metrics.merged_by).to eq(pull_request_author)
- expect(merge_request.metrics.merged_at).to eq(merge_event.merge_timestamp)
- expect(merge_request.merge_commit_sha).to eq('12345678')
- expect(merge_request.state_id).to eq(3)
- end
-
- describe 'pull request author user mapping' do
- before do
- allow(subject.client).to receive(:activities).and_return([merge_event])
- end
-
- shared_examples 'imports pull requests' do
- it 'maps user' do
- expect { subject.execute }.to change { MergeRequest.count }.by(1)
-
- merge_request = MergeRequest.first
- expect(merge_request.author).to eq(expected_author)
- end
- end
-
- context 'when bitbucket_server_user_mapping_by_username feature flag is disabled' do
- before do
- stub_feature_flags(bitbucket_server_user_mapping_by_username: false)
- end
-
- context 'when email is not present' do
- before do
- allow(pull_request).to receive(:author_email).and_return(nil)
- end
-
- let(:expected_author) { project_creator }
-
- include_examples 'imports pull requests'
- end
-
- context 'when email is present' do
- before do
- allow(pull_request).to receive(:author_email).and_return(pull_request_author.email)
- end
-
- let(:expected_author) { pull_request_author }
-
- include_examples 'imports pull requests'
- end
- end
-
- context 'when bitbucket_server_user_mapping_by_username feature flag is enabled' do
- before do
- stub_feature_flags(bitbucket_server_user_mapping_by_username: true)
- end
-
- context 'when username is not present' do
- before do
- allow(pull_request).to receive(:author_username).and_return(nil)
- end
-
- let(:expected_author) { project_creator }
-
- include_examples 'imports pull requests'
- end
-
- context 'when username is present' do
- before do
- allow(pull_request).to receive(:author_username).and_return(pull_request_author.username)
- end
-
- let(:expected_author) { pull_request_author }
-
- include_examples 'imports pull requests'
- end
- end
-
- context 'when user is not found' do
- before do
- allow(pull_request).to receive(:author_username).and_return(nil)
- allow(pull_request).to receive(:author_email).and_return(nil)
- end
-
- it 'maps importer user' do
- expect { subject.execute }.to change { MergeRequest.count }.by(1)
-
- merge_request = MergeRequest.first
- expect(merge_request.author).to eq(project_creator)
- end
- end
- end
-
- describe 'comments' do
- shared_examples 'imports comments' do
- it 'imports comments' do
- expect(subject.client).to receive(:activities).and_return([pr_comment])
-
- expect { subject.execute }.to change { MergeRequest.count }.by(1)
-
- merge_request = MergeRequest.first
- expect(merge_request.notes.count).to eq(1)
- note = merge_request.notes.first
- expect(note.note).to end_with(pr_note.note)
- expect(note.author).to eq(note_author)
- expect(note.created_at).to eq(pr_note.created_at)
- expect(note.updated_at).to eq(pr_note.created_at)
- end
- end
-
- context 'when bitbucket_server_user_mapping_by_username feature flag is disabled' do
- before do
- stub_feature_flags(bitbucket_server_user_mapping_by_username: false)
- end
-
- include_examples 'imports comments'
- end
-
- context 'when bitbucket_server_user_mapping_by_username feature flag is enabled' do
- before do
- stub_feature_flags(bitbucket_server_user_mapping_by_username: true)
- end
-
- include_examples 'imports comments'
-
- context 'when username is not present' do
- before do
- allow(pr_note).to receive(:author_username).and_return(nil)
- allow(subject.client).to receive(:activities).and_return([pr_comment])
- end
-
- it 'defaults to import user' do
- expect { subject.execute }.to change { MergeRequest.count }.by(1)
-
- merge_request = MergeRequest.first
- expect(merge_request.notes.count).to eq(1)
- note = merge_request.notes.first
- expect(note.author).to eq(project_creator)
- end
- end
-
- context 'when username is present' do
- before do
- allow(pr_note).to receive(:author_username).and_return(note_author.username)
- allow(subject.client).to receive(:activities).and_return([pr_comment])
- end
-
- it 'maps by username' do
- expect { subject.execute }.to change { MergeRequest.count }.by(1)
-
- merge_request = MergeRequest.first
- expect(merge_request.notes.count).to eq(1)
- note = merge_request.notes.first
- expect(note.author).to eq(note_author)
- end
- end
- end
- end
-
- context 'metrics' do
- let(:histogram) { double(:histogram).as_null_object }
- let(:counter) { double('counter', increment: true) }
-
- before do
- allow(Gitlab::Metrics).to receive(:counter) { counter }
- allow(Gitlab::Metrics).to receive(:histogram) { histogram }
- allow(subject.client).to receive(:activities).and_return([merge_event])
- end
-
- it 'counts and measures duration of imported projects' do
- expect(Gitlab::Metrics).to receive(:counter).with(
- :bitbucket_server_importer_imported_projects_total,
- 'The number of imported projects'
- )
-
- expect(Gitlab::Metrics).to receive(:histogram).with(
- :bitbucket_server_importer_total_duration_seconds,
- 'Total time spent importing projects, in seconds',
- {},
- Gitlab::Import::Metrics::IMPORT_DURATION_BUCKETS
- )
-
- expect(counter).to receive(:increment)
- expect(histogram).to receive(:observe).with({ importer: :bitbucket_server_importer }, anything)
-
- subject.execute
- end
-
- it 'counts imported pull requests' do
- expect(Gitlab::Metrics).to receive(:counter).with(
- :bitbucket_server_importer_imported_merge_requests_total,
- 'The number of imported merge (pull) requests'
- )
-
- expect(counter).to receive(:increment)
-
- subject.execute
- end
- end
-
- describe 'threaded discussions' do
- let(:reply_author) { create(:user, username: 'reply_author', email: 'reply_author@example.org') }
- let(:inline_note_author) { create(:user, username: 'inline_note_author', email: 'inline_note_author@example.org') }
-
- let(:reply) do
- instance_double(
- BitbucketServer::Representation::PullRequestComment,
- author_email: reply_author.email,
- author_username: reply_author.username,
- note: 'I agree',
- created_at: now,
- updated_at: now)
- end
-
- # https://gitlab.com/gitlab-org/gitlab-test/compare/c1acaa58bbcbc3eafe538cb8274ba387047b69f8...5937ac0a7beb003549fc5fd26fc247ad
- let(:inline_note) do
- instance_double(
- BitbucketServer::Representation::PullRequestComment,
- file_type: 'ADDED',
- from_sha: sample.commits.first,
- to_sha: sample.commits.last,
- file_path: '.gitmodules',
- old_pos: nil,
- new_pos: 4,
- note: 'Hello world',
- author_email: inline_note_author.email,
- author_username: inline_note_author.username,
- comments: [reply],
- created_at: now,
- updated_at: now,
- parent_comment: nil)
- end
-
- let(:inline_comment) do
- instance_double(
- BitbucketServer::Representation::Activity,
- comment?: true,
- inline_comment?: true,
- merge_event?: false,
- comment: inline_note)
- end
-
- before do
- allow(reply).to receive(:parent_comment).and_return(inline_note)
- allow(subject.client).to receive(:activities).and_return([inline_comment])
- end
-
- shared_examples 'imports threaded discussions' do
- it 'imports threaded discussions' do
- expect { subject.execute }.to change { MergeRequest.count }.by(1)
-
- merge_request = MergeRequest.first
- expect(merge_request.notes.count).to eq(2)
- expect(merge_request.notes.map(&:discussion_id).uniq.count).to eq(1)
-
- notes = merge_request.notes.order(:id).to_a
- start_note = notes.first
- expect(start_note.type).to eq('DiffNote')
- expect(start_note.note).to end_with(inline_note.note)
- expect(start_note.created_at).to eq(inline_note.created_at)
- expect(start_note.updated_at).to eq(inline_note.updated_at)
- expect(start_note.position.base_sha).to eq(inline_note.from_sha)
- expect(start_note.position.start_sha).to eq(inline_note.from_sha)
- expect(start_note.position.head_sha).to eq(inline_note.to_sha)
- expect(start_note.position.old_line).to be_nil
- expect(start_note.position.new_line).to eq(inline_note.new_pos)
- expect(start_note.author).to eq(inline_note_author)
-
- reply_note = notes.last
- # Make sure author and reply context is included
- expect(reply_note.note).to start_with("> #{inline_note.note}\n\n#{reply.note}")
- expect(reply_note.author).to eq(reply_author)
- expect(reply_note.created_at).to eq(reply.created_at)
- expect(reply_note.updated_at).to eq(reply.created_at)
- expect(reply_note.position.base_sha).to eq(inline_note.from_sha)
- expect(reply_note.position.start_sha).to eq(inline_note.from_sha)
- expect(reply_note.position.head_sha).to eq(inline_note.to_sha)
- expect(reply_note.position.old_line).to be_nil
- expect(reply_note.position.new_line).to eq(inline_note.new_pos)
- end
- end
-
- context 'when bitbucket_server_user_mapping_by_username feature flag is disabled' do
- before do
- stub_feature_flags(bitbucket_server_user_mapping_by_username: false)
- end
-
- include_examples 'imports threaded discussions'
- end
-
- context 'when bitbucket_server_user_mapping_by_username feature flag is enabled' do
- before do
- stub_feature_flags(bitbucket_server_user_mapping_by_username: true)
- end
-
- include_examples 'imports threaded discussions' do
- context 'when username is not present' do
- before do
- allow(reply).to receive(:author_username).and_return(nil)
- allow(inline_note).to receive(:author_username).and_return(nil)
- end
-
- it 'defaults to import user' do
- expect { subject.execute }.to change { MergeRequest.count }.by(1)
-
- notes = MergeRequest.first.notes.order(:id).to_a
-
- expect(notes.first.author).to eq(project_creator)
- expect(notes.last.author).to eq(project_creator)
- end
- end
- end
- end
-
- context 'when user is not found' do
- before do
- allow(reply).to receive(:author_username).and_return(nil)
- allow(reply).to receive(:author_email).and_return(nil)
- allow(inline_note).to receive(:author_username).and_return(nil)
- allow(inline_note).to receive(:author_email).and_return(nil)
- end
-
- it 'maps importer user' do
- expect { subject.execute }.to change { MergeRequest.count }.by(1)
-
- notes = MergeRequest.first.notes.order(:id).to_a
-
- expect(notes.first.author).to eq(project_creator)
- expect(notes.last.author).to eq(project_creator)
- end
- end
- end
-
- it 'falls back to comments if diff comments fail to validate' do
- reply = instance_double(
- BitbucketServer::Representation::Comment,
- author_email: 'someuser@gitlab.com',
- author_username: 'Aquaman',
- note: 'I agree',
- created_at: now,
- updated_at: now)
-
- # https://gitlab.com/gitlab-org/gitlab-test/compare/c1acaa58bbcbc3eafe538cb8274ba387047b69f8...5937ac0a7beb003549fc5fd26fc247ad
- inline_note = instance_double(
- BitbucketServer::Representation::PullRequestComment,
- file_type: 'REMOVED',
- from_sha: sample.commits.first,
- to_sha: sample.commits.last,
- file_path: '.gitmodules',
- old_pos: 8,
- new_pos: 9,
- note: 'This is a note with an invalid line position.',
- author_email: project.owner.email,
- author_username: 'Owner',
- comments: [reply],
- created_at: now,
- updated_at: now,
- parent_comment: nil)
-
- inline_comment = instance_double(
- BitbucketServer::Representation::Activity,
- comment?: true,
- inline_comment?: true,
- merge_event?: false,
- comment: inline_note)
-
- allow(reply).to receive(:parent_comment).and_return(inline_note)
-
- expect(subject.client).to receive(:activities).and_return([inline_comment])
-
- expect { subject.execute }.to change { MergeRequest.count }.by(1)
-
- merge_request = MergeRequest.first
- expect(merge_request.notes.count).to eq(2)
- notes = merge_request.notes
-
- expect(notes.first.note).to start_with('*Comment on .gitmodules')
- expect(notes.second.note).to start_with('*Comment on .gitmodules')
- end
-
- it 'reports an error if an exception is raised' do
- allow(subject).to receive(:import_bitbucket_pull_request).and_raise(RuntimeError)
- expect(Gitlab::ErrorTracking).to receive(:log_exception)
-
- subject.execute
- end
-
- describe 'import pull requests with caching' do
- let(:pull_request_already_imported) do
- instance_double(
- BitbucketServer::Representation::PullRequest,
- iid: 11)
- end
-
- let(:pull_request_to_be_imported) do
- instance_double(
- BitbucketServer::Representation::PullRequest,
- iid: 12,
- source_branch_sha: sample.commits.last,
- source_branch_name: Gitlab::Git::BRANCH_REF_PREFIX + sample.source_branch,
- target_branch_sha: sample.commits.first,
- target_branch_name: Gitlab::Git::BRANCH_REF_PREFIX + sample.target_branch,
- title: 'This is a title',
- description: 'This is a test pull request',
- reviewers: sample.reviewers,
- state: 'merged',
- author: 'Test Author',
- author_email: pull_request_author.email,
- author_username: pull_request_author.username,
- created_at: Time.now,
- updated_at: Time.now,
- raw: {},
- merged?: true)
- end
-
- before do
- Gitlab::Cache::Import::Caching.set_add(subject.already_imported_cache_key, pull_request_already_imported.iid)
- allow(subject.client).to receive(:pull_requests).and_return([pull_request_to_be_imported, pull_request_already_imported], [])
- end
-
- it 'only imports one Merge Request, as the other on is in the cache' do
- expect(subject.client).to receive(:activities).and_return([merge_event])
- expect { subject.execute }.to change { MergeRequest.count }.by(1)
-
- expect(Gitlab::Cache::Import::Caching.set_includes?(subject.already_imported_cache_key, pull_request_already_imported.iid)).to eq(true)
- expect(Gitlab::Cache::Import::Caching.set_includes?(subject.already_imported_cache_key, pull_request_to_be_imported.iid)).to eq(true)
- end
- end
- end
-
- describe 'inaccessible branches' do
- let(:id) { 10 }
- let(:temp_branch_from) { "gitlab/import/pull-request/#{id}/from" }
- let(:temp_branch_to) { "gitlab/import/pull-request/#{id}/to" }
-
- before do
- pull_request = instance_double(
- BitbucketServer::Representation::PullRequest,
- iid: id,
- source_branch_sha: '12345678',
- source_branch_name: Gitlab::Git::BRANCH_REF_PREFIX + sample.source_branch,
- target_branch_sha: '98765432',
- target_branch_name: Gitlab::Git::BRANCH_REF_PREFIX + sample.target_branch,
- title: 'This is a title',
- description: 'This is a test pull request',
- reviewers: [],
- state: 'merged',
- author: 'Test Author',
- author_email: project.owner.email,
- author_username: 'author',
- created_at: Time.now,
- updated_at: Time.now,
- merged?: true)
-
- expect(subject.client).to receive(:pull_requests).and_return([pull_request], [])
- expect(subject.client).to receive(:activities).and_return([])
- expect(subject).to receive(:import_repository).twice
- end
-
- it '#restore_branches' do
- expect(subject).to receive(:restore_branches).and_call_original
- expect(subject).to receive(:delete_temp_branches)
- expect(subject.client).to receive(:create_branch)
- .with(project_key, repo_slug,
- temp_branch_from,
- '12345678')
- expect(subject.client).to receive(:create_branch)
- .with(project_key, repo_slug,
- temp_branch_to,
- '98765432')
-
- expect { subject.execute }.to change { MergeRequest.count }.by(1)
- end
-
- it '#delete_temp_branches' do
- expect(subject.client).to receive(:create_branch).twice
- expect(subject).to receive(:delete_temp_branches).and_call_original
- expect(subject.client).to receive(:delete_branch)
- .with(project_key, repo_slug,
- temp_branch_from,
- '12345678')
- expect(subject.client).to receive(:delete_branch)
- .with(project_key, repo_slug,
- temp_branch_to,
- '98765432')
- expect(project.repository).to receive(:delete_branch).with(temp_branch_from)
- expect(project.repository).to receive(:delete_branch).with(temp_branch_to)
-
- expect { subject.execute }.to change { MergeRequest.count }.by(1)
- end
- end
-
- context "lfs files" do
- before do
- allow(project).to receive(:lfs_enabled?).and_return(true)
- allow(subject).to receive(:import_repository)
- allow(subject).to receive(:import_pull_requests)
- end
-
- it "downloads lfs objects if lfs_enabled is enabled for project" do
- expect_next_instance_of(Projects::LfsPointers::LfsImportService) do |lfs_import_service|
- expect(lfs_import_service).to receive(:execute).and_return(status: :success)
- end
-
- subject.execute
- end
-
- it "adds the error message when the lfs download fails" do
- allow_next_instance_of(Projects::LfsPointers::LfsImportService) do |lfs_import_service|
- expect(lfs_import_service).to receive(:execute).and_return(status: :error, message: "LFS server not reachable")
- end
-
- subject.execute
-
- expect(project.import_state.reload.last_error).to eq(Gitlab::Json.dump({
- message: "The remote data could not be fully imported.",
- errors: [{
- type: "lfs_objects",
- errors: "The Lfs import process failed. LFS server not reachable"
- }]
- }))
- end
- end
-end
diff --git a/spec/lib/gitlab/import_sources_spec.rb b/spec/lib/gitlab/import_sources_spec.rb
index 13547609f68..db23e3b1fd4 100644
--- a/spec/lib/gitlab/import_sources_spec.rb
+++ b/spec/lib/gitlab/import_sources_spec.rb
@@ -72,49 +72,11 @@ RSpec.describe Gitlab::ImportSources, feature_category: :importers do
expect(described_class.importer(name)).to eq(klass)
end
end
-
- context 'when flag is disabled' do
- before do
- stub_feature_flags(bitbucket_server_parallel_importer: false)
- end
-
- it 'returns Gitlab::BitbucketServerImport::Importer when given bitbucket_server' do
- expect(described_class.importer('bitbucket_server')).to eq(Gitlab::BitbucketServerImport::Importer)
- end
- end
end
describe '.import_table' do
subject { described_class.import_table }
- describe 'Bitbucket server' do
- it 'returns the ParallelImporter' do
- is_expected.to include(
- described_class::ImportSource.new(
- 'bitbucket_server',
- 'Bitbucket Server',
- Gitlab::BitbucketServerImport::ParallelImporter
- )
- )
- end
-
- context 'when flag is disabled' do
- before do
- stub_feature_flags(bitbucket_server_parallel_importer: false)
- end
-
- it 'returns the legacy Importer' do
- is_expected.to include(
- described_class::ImportSource.new(
- 'bitbucket_server',
- 'Bitbucket Server',
- Gitlab::BitbucketServerImport::Importer
- )
- )
- end
- end
- end
-
describe 'Bitbucket cloud' do
it 'returns the ParallelImporter' do
is_expected.to include(
diff --git a/spec/lib/sidebars/projects/menus/issues_menu_spec.rb b/spec/lib/sidebars/projects/menus/issues_menu_spec.rb
index 53d92d013a9..91913e5b733 100644
--- a/spec/lib/sidebars/projects/menus/issues_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/issues_menu_spec.rb
@@ -14,6 +14,7 @@ RSpec.describe Sidebars::Projects::Menus::IssuesMenu, feature_category: :navigat
let(:extra_attrs) do
{
item_id: :project_issue_list,
+ active_routes: { path: %w[projects/issues#index projects/issues#show projects/issues#new] },
pill_count: menu.pill_count,
has_pill: menu.has_pill?,
super_sidebar_parent: Sidebars::Projects::SuperSidebarMenus::PlanMenu